4545import java .text .DecimalFormat ;
4646import java .util .ArrayList ;
4747
48- import com .projecttango .experiments .javaarealearning .SetADFNameDialog .SetNameCommunicator ;
49-
5048/**
5149 * Main Activity class for the Area Learning API Sample. Handles the connection to the Tango service
5250 * and propagation of Tango pose data to OpenGL and Layout views. OpenGL rendering logic is
5351 * delegated to the {@link ALRenderer} class.
5452 */
5553public class AreaLearningActivity extends Activity implements View .OnClickListener ,
56- SetNameCommunicator {
54+ SetADFNameDialog . CallbackListener , SaveAdfTask . SaveAdfListener {
5755
5856 private static final String TAG = AreaLearningActivity .class .getSimpleName ();
5957 private static final int SECONDS_TO_MILLI = 1000 ;
@@ -79,7 +77,7 @@ public class AreaLearningActivity extends Activity implements View.OnClickListen
7977 private TextView mAdf2DevicePoseDeltaTextView ;
8078 private TextView mAdf2StartPoseDeltaTextView ;
8179
82- private Button mSaveAdf ;
80+ private Button mSaveAdfButton ;
8381 private Button mFirstPersonButton ;
8482 private Button mThirdPersonButton ;
8583 private Button mTopDownButton ;
@@ -109,6 +107,8 @@ public class AreaLearningActivity extends Activity implements View.OnClickListen
109107 private TangoPoseData [] mPoses ;
110108 private static final int UPDATE_INTERVAL_MS = 100 ;
111109 private static final DecimalFormat threeDec = new DecimalFormat ("00.000" );
110+ // Long-running task to save the ADF.
111+ private SaveAdfTask mSaveAdfTask ;
112112 public static Object sharedLock = new Object ();
113113
114114 @ Override
@@ -145,10 +145,10 @@ protected void onCreate(Bundle savedInstanceState) {
145145 mApplicationVersionTextView = (TextView ) findViewById (R .id .appversion );
146146 mGLView = (GLSurfaceView ) findViewById (R .id .gl_surface_view );
147147
148- mSaveAdf = (Button ) findViewById (R .id .saveAdf );
148+ mSaveAdfButton = (Button ) findViewById (R .id .saveAdf );
149149 mUUIDTextView = (TextView ) findViewById (R .id .uuid );
150150
151- mSaveAdf .setVisibility (View .GONE );
151+ mSaveAdfButton .setVisibility (View .GONE );
152152 // Set up button click listeners
153153 mFirstPersonButton .setOnClickListener (this );
154154 mThirdPersonButton .setOnClickListener (this );
@@ -187,8 +187,11 @@ private void setTangoConfig() {
187187 // Set learning mode to config.
188188 mConfig .putBoolean (TangoConfig .KEY_BOOLEAN_LEARNINGMODE , true );
189189 // Set the ADF save button visible.
190- mSaveAdf .setVisibility (View .VISIBLE );
191- mSaveAdf .setOnClickListener (this );
190+ mSaveAdfButton .setEnabled (false );
191+ mSaveAdfButton .setOnClickListener (this );
192+ }else {
193+ // Hide to save ADF button if leanring mode is off.
194+ mSaveAdfButton .setVisibility (View .GONE );
192195 }
193196 // Check for Load ADF/Constant Space relocalization mode
194197 if (mIsConstantSpaceRelocalize ) {
@@ -243,7 +246,17 @@ public void onTangoEvent(final TangoEvent event) {
243246 runOnUiThread (new Runnable () {
244247 @ Override
245248 public void run () {
249+ // Update the debug UI with information about this event.
246250 mTangoEventTextView .setText (event .eventKey + ": " + event .eventValue );
251+
252+ // When saving an ADF, update the progress bar UI.
253+ if (event .eventType == TangoEvent .EVENT_AREA_LEARNING &&
254+ TangoEvent .KEY_AREA_DESCRIPTION_SAVE_PROGRESS .equals (event .eventKey )) {
255+ int progressPercent = (int ) (Double .parseDouble (event .eventValue ) * 100 );
256+ if (mSaveAdfTask != null ) {
257+ mSaveAdfTask .publishProgress (progressPercent );
258+ }
259+ }
247260 }
248261 });
249262 }
@@ -363,35 +376,13 @@ private void showSetNameDialog() {
363376 setADFNameDialog .show (manager , "ADFNameDialog" );
364377 }
365378
366- @ Override
367- public void onSetName (String name , String uuids ) {
368-
369- TangoAreaDescriptionMetaData metadata = new TangoAreaDescriptionMetaData ();
370- try {
371- mCurrentUUID = mTango .saveAreaDescription ();
372- metadata = mTango .loadAreaDescriptionMetaData (mCurrentUUID );
373- metadata .set (TangoAreaDescriptionMetaData .KEY_NAME , name .getBytes ());
374- mTango .saveAreaDescriptionMetadata (mCurrentUUID , metadata );
375- } catch (TangoErrorException e ) {
376- Toast .makeText (getApplicationContext (), getString (R .string .tango_error ),
377- Toast .LENGTH_SHORT ).show ();
378- return ;
379- } catch (TangoInvalidException e ) {
380- Toast .makeText (getApplicationContext (), getString (R .string .tango_invalid ),
381- Toast .LENGTH_SHORT ).show ();
382- return ;
383- }
384- Toast .makeText (getApplicationContext (), getString (R .string .adf_save ) + mCurrentUUID ,
385- Toast .LENGTH_SHORT ).show ();
386- }
387-
388379 /**
389380 * Updates the text view in UI screen with the Pose. Each pose is associated with Target and
390381 * Base Frame. We need to check for that pair and update our views accordingly.
391- *
392- * @param pose
393382 */
394383 private void updateTextViews () {
384+ // Allow clicking of the save button only when Tango is localized to the current ADF.
385+ mSaveAdfButton .setEnabled (mIsRelocalized );
395386 if (mPoses [0 ] != null
396387 && mPoses [0 ].baseFrame == TangoPoseData .COORDINATE_FRAME_AREA_DESCRIPTION
397388 && mPoses [0 ].targetFrame == TangoPoseData .COORDINATE_FRAME_DEVICE ) {
@@ -445,7 +436,7 @@ private String getPoseStatus(TangoPoseData pose) {
445436 return getString (R .string .pose_invalid );
446437 case TangoPoseData .POSE_VALID :
447438 return getString (R .string .pose_valid );
448- default :
439+ default :
449440 return getString (R .string .pose_unknown );
450441 }
451442 }
@@ -456,31 +447,31 @@ protected void onPause() {
456447 try {
457448 mTango .disconnect ();
458449 } catch (TangoErrorException e ) {
459- Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT )
460- .show ();
450+ Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT ).show ();
461451 }
462452 }
463453
464454 @ Override
465455 protected void onResume () {
466456 super .onResume ();
457+ // Clear the relocalization state: we don't know where the device has been since our app was paused
458+ mIsRelocalized = false ;
467459 try {
468460 setUpTangoListeners ();
469461 } catch (TangoErrorException e ) {
470- Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT )
471- .show ();
462+ Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT ).show ();
472463 } catch (SecurityException e ) {
473- Toast .makeText (getApplicationContext (), R .string .no_permissions , Toast .LENGTH_SHORT )
474- .show ();
464+ Toast .makeText (getApplicationContext (), R .string .no_permissions , Toast .LENGTH_SHORT ).show ();
475465 }
466+ // Connect to the tango service (start receiving pose updates).
476467 try {
477468 mTango .connect (mConfig );
478469 } catch (TangoOutOfDateException e ) {
479- Toast .makeText (getApplicationContext (), R .string .tango_out_of_date_exception ,
480- Toast .LENGTH_SHORT ).show ();
470+ Toast .makeText (getApplicationContext (), R .string .tango_out_of_date_exception , Toast .LENGTH_SHORT ).show ();
481471 } catch (TangoErrorException e ) {
482- Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT )
483- .show ();
472+ Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT ).show ();
473+ } catch (TangoInvalidException e ) {
474+ Toast .makeText (getApplicationContext (), R .string .tango_invalid , Toast .LENGTH_SHORT ).show ();
484475 }
485476 }
486477
@@ -503,7 +494,8 @@ public void onClick(View v) {
503494 mRenderer .setThirdPersonView ();
504495 break ;
505496 case R .id .saveAdf :
506- saveAdf ();
497+ // Query the user for an ADF name and save if OK was clicked.
498+ showSetADFNameDialog ();
507499 break ;
508500 default :
509501 Log .w (TAG , "Unknown button click" );
@@ -551,4 +543,61 @@ public void run() {
551543 }
552544 }).start ();
553545 }
546+
547+ /**
548+ * Save the current Area Description File.
549+ * Performs saving on a background thread and displays a progress dialog.
550+ */
551+ private void saveAdf (String adfName ) {
552+ mSaveAdfTask = new SaveAdfTask (this , this , mTango , adfName );
553+ mSaveAdfTask .execute ();
554+ }
555+
556+ /**
557+ * Handles failed save from mSaveAdfTask.
558+ */
559+ @ Override
560+ public void onSaveAdfFailed (String adfName ) {
561+ String toastMessage = String .format (
562+ getResources ().getString (R .string .save_adf_failed_toast_format ),
563+ adfName );
564+ Toast .makeText (this , toastMessage , Toast .LENGTH_LONG ).show ();
565+ mSaveAdfTask = null ;
566+ }
567+
568+ /**
569+ * Handles successful save from mSaveAdfTask.
570+ */
571+ @ Override
572+ public void onSaveAdfSuccess (String adfName , String adfUuid ) {
573+ String toastMessage = String .format (
574+ getResources ().getString (R .string .save_adf_success_toast_format ),
575+ adfName , adfUuid );
576+ Toast .makeText (this , toastMessage , Toast .LENGTH_LONG ).show ();
577+ mSaveAdfTask = null ;
578+ finish ();
579+ }
580+
581+ /**
582+ * Shows a dialog for setting the ADF name.
583+ */
584+ private void showSetADFNameDialog () {
585+ Bundle bundle = new Bundle ();
586+ bundle .putString ("name" , "New ADF" );
587+ bundle .putString ("id" , "" ); // UUID is generated after the ADF is saved.
588+
589+ FragmentManager manager = getFragmentManager ();
590+ SetADFNameDialog setADFNameDialog = new SetADFNameDialog ();
591+ setADFNameDialog .setArguments (bundle );
592+ setADFNameDialog .show (manager , "ADFNameDialog" );
593+ }
594+ @ Override
595+ public void onAdfNameOk (String name , String uuid ) {
596+ saveAdf (name );
597+ }
598+
599+ @ Override
600+ public void onAdfNameCancelled () {
601+
602+ }
554603}
0 commit comments