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,9 @@ 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 );
152151 // Set up button click listeners
153152 mFirstPersonButton .setOnClickListener (this );
154153 mThirdPersonButton .setOnClickListener (this );
@@ -187,8 +186,11 @@ private void setTangoConfig() {
187186 // Set learning mode to config.
188187 mConfig .putBoolean (TangoConfig .KEY_BOOLEAN_LEARNINGMODE , true );
189188 // Set the ADF save button visible.
190- mSaveAdf .setVisibility (View .VISIBLE );
191- mSaveAdf .setOnClickListener (this );
189+ mSaveAdfButton .setEnabled (false );
190+ mSaveAdfButton .setOnClickListener (this );
191+ }else {
192+ // Hide to save ADF button if leanring mode is off.
193+ mSaveAdfButton .setVisibility (View .GONE );
192194 }
193195 // Check for Load ADF/Constant Space relocalization mode
194196 if (mIsConstantSpaceRelocalize ) {
@@ -243,7 +245,17 @@ public void onTangoEvent(final TangoEvent event) {
243245 runOnUiThread (new Runnable () {
244246 @ Override
245247 public void run () {
248+ // Update the debug UI with information about this event.
246249 mTangoEventTextView .setText (event .eventKey + ": " + event .eventValue );
250+
251+ // When saving an ADF, update the progress bar UI.
252+ if (event .eventType == TangoEvent .EVENT_AREA_LEARNING &&
253+ TangoEvent .KEY_AREA_DESCRIPTION_SAVE_PROGRESS .equals (event .eventKey )) {
254+ int progressPercent = (int ) (Double .parseDouble (event .eventValue ) * 100 );
255+ if (mSaveAdfTask != null ) {
256+ mSaveAdfTask .publishProgress (progressPercent );
257+ }
258+ }
247259 }
248260 });
249261 }
@@ -315,10 +327,8 @@ public void onPoseAvailable(TangoPoseData pose) {
315327 mAdf2StartPreviousPoseTimeStamp = pose .timestamp ;
316328 if (pose .statusCode == TangoPoseData .POSE_VALID ) {
317329 mIsRelocalized = true ;
318- // Set the color to green
319330 } else {
320331 mIsRelocalized = false ;
321- // Set the color blue
322332 }
323333 }
324334
@@ -363,35 +373,13 @@ private void showSetNameDialog() {
363373 setADFNameDialog .show (manager , "ADFNameDialog" );
364374 }
365375
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-
388376 /**
389377 * Updates the text view in UI screen with the Pose. Each pose is associated with Target and
390378 * Base Frame. We need to check for that pair and update our views accordingly.
391- *
392- * @param pose
393379 */
394380 private void updateTextViews () {
381+ // Allow clicking of the save button only when Tango is localized to the current ADF.
382+ mSaveAdfButton .setEnabled (mIsRelocalized );
395383 if (mPoses [0 ] != null
396384 && mPoses [0 ].baseFrame == TangoPoseData .COORDINATE_FRAME_AREA_DESCRIPTION
397385 && mPoses [0 ].targetFrame == TangoPoseData .COORDINATE_FRAME_DEVICE ) {
@@ -456,31 +444,31 @@ protected void onPause() {
456444 try {
457445 mTango .disconnect ();
458446 } catch (TangoErrorException e ) {
459- Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT )
460- .show ();
447+ Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT ).show ();
461448 }
462449 }
463450
464451 @ Override
465452 protected void onResume () {
466453 super .onResume ();
454+ // Clear the relocalization state: we don't know where the device has been since our app was paused
455+ mIsRelocalized = false ;
467456 try {
468457 setUpTangoListeners ();
469458 } catch (TangoErrorException e ) {
470- Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT )
471- .show ();
459+ Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT ).show ();
472460 } catch (SecurityException e ) {
473- Toast .makeText (getApplicationContext (), R .string .no_permissions , Toast .LENGTH_SHORT )
474- .show ();
461+ Toast .makeText (getApplicationContext (), R .string .no_permissions , Toast .LENGTH_SHORT ).show ();
475462 }
463+ // Connect to the tango service (start receiving pose updates).
476464 try {
477465 mTango .connect (mConfig );
478466 } catch (TangoOutOfDateException e ) {
479- Toast .makeText (getApplicationContext (), R .string .tango_out_of_date_exception ,
480- Toast .LENGTH_SHORT ).show ();
467+ Toast .makeText (getApplicationContext (), R .string .tango_out_of_date_exception , Toast .LENGTH_SHORT ).show ();
481468 } catch (TangoErrorException e ) {
482- Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT )
483- .show ();
469+ Toast .makeText (getApplicationContext (), R .string .tango_error , Toast .LENGTH_SHORT ).show ();
470+ } catch (TangoInvalidException e ) {
471+ Toast .makeText (getApplicationContext (), R .string .tango_invalid , Toast .LENGTH_SHORT ).show ();
484472 }
485473 }
486474
@@ -503,7 +491,8 @@ public void onClick(View v) {
503491 mRenderer .setThirdPersonView ();
504492 break ;
505493 case R .id .saveAdf :
506- saveAdf ();
494+ // Query the user for an ADF name and save if OK was clicked.
495+ showSetADFNameDialog ();
507496 break ;
508497 default :
509498 Log .w (TAG , "Unknown button click" );
@@ -551,4 +540,70 @@ public void run() {
551540 }
552541 }).start ();
553542 }
543+
544+ /**
545+ * Save the current Area Description File.
546+ * Performs saving on a background thread and displays a progress dialog.
547+ */
548+ private void saveAdf (String adfName ) {
549+ mSaveAdfTask = new SaveAdfTask (this , this , mTango , adfName );
550+ mSaveAdfTask .execute ();
551+ }
552+
553+ /**
554+ * Handles failed save from mSaveAdfTask.
555+ */
556+ @ Override
557+ public void onSaveAdfFailed (String adfName ) {
558+ String toastMessage = String .format (
559+ getResources ().getString (R .string .save_adf_failed_toast_format ),
560+ adfName );
561+ Toast .makeText (this , toastMessage , Toast .LENGTH_LONG ).show ();
562+ mSaveAdfTask = null ;
563+ }
564+
565+ /**
566+ * Handles successful save from mSaveAdfTask.
567+ */
568+ @ Override
569+ public void onSaveAdfSuccess (String adfName , String adfUuid ) {
570+ String toastMessage = String .format (
571+ getResources ().getString (R .string .save_adf_success_toast_format ),
572+ adfName , adfUuid );
573+ Toast .makeText (this , toastMessage , Toast .LENGTH_LONG ).show ();
574+ mSaveAdfTask = null ;
575+ finish ();
576+ }
577+
578+ /**
579+ * Shows a dialog for setting the ADF name.
580+ */
581+ private void showSetADFNameDialog () {
582+ Bundle bundle = new Bundle ();
583+ bundle .putString ("name" ,getResources ().getString (R .string .default_adf_name ) );
584+ bundle .putString ("id" , "" ); // UUID is generated after the ADF is saved.
585+
586+ FragmentManager manager = getFragmentManager ();
587+ SetADFNameDialog setADFNameDialog = new SetADFNameDialog ();
588+ setADFNameDialog .setArguments (bundle );
589+ setADFNameDialog .show (manager , "ADFNameDialog" );
590+ }
591+
592+
593+ /**
594+ * Implements SetADFNameDialog.CallbackListener.
595+ */
596+ @ Override
597+ public void onAdfNameOk (String name , String uuid ) {
598+ saveAdf (name );
599+ }
600+
601+
602+ /**
603+ * Implements SetADFNameDialog.CallbackListener.
604+ */
605+ @ Override
606+ public void onAdfNameCancelled () {
607+ // Continue running.s
608+ }
554609}
0 commit comments