RosActivity.java
Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2011 Google Inc.
00003  * 
00004  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
00005  * use this file except in compliance with the License. You may obtain a copy of
00006  * the License at
00007  * 
00008  * http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00012  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
00013  * License for the specific language governing permissions and limitations under
00014  * the License.
00015  */
00016 
00017 package org.ros.android;
00018 
00019 import com.google.common.base.Preconditions;
00020 
00021 import android.app.Activity;
00022 import android.content.ComponentName;
00023 import android.content.Intent;
00024 import android.content.ServiceConnection;
00025 import android.os.AsyncTask;
00026 import android.os.IBinder;
00027 import android.widget.Toast;
00028 import org.ros.exception.RosRuntimeException;
00029 import org.ros.node.NodeMain;
00030 import org.ros.node.NodeMainExecutor;
00031 
00032 import java.net.URI;
00033 import java.net.URISyntaxException;
00034 import java.util.concurrent.ExecutionException;
00035 
00039 public abstract class RosActivity extends Activity {
00040 
00041   private static final int MASTER_CHOOSER_REQUEST_CODE = 0;
00042 
00043   private final ServiceConnection nodeMainExecutorServiceConnection;
00044   private final String notificationTicker;
00045   private final String notificationTitle;
00046 
00047   protected NodeMainExecutorService nodeMainExecutorService;
00048 
00049   private final class NodeMainExecutorServiceConnection implements ServiceConnection {
00050     @Override
00051     public void onServiceConnected(ComponentName name, IBinder binder) {
00052       nodeMainExecutorService = ((NodeMainExecutorService.LocalBinder) binder).getService();
00053       nodeMainExecutorService.addListener(new NodeMainExecutorServiceListener() {
00054         @Override
00055         public void onShutdown(NodeMainExecutorService nodeMainExecutorService) {
00056           if ( !isFinishing() ) {
00057             RosActivity.this.finish();
00058           }
00059         }
00060       });
00061       startMasterChooser();
00062     }
00063 
00064     @Override
00065     public void onServiceDisconnected(ComponentName name) {
00066     }
00067   };
00068 
00069   protected RosActivity(String notificationTicker, String notificationTitle) {
00070     super();
00071     this.notificationTicker = notificationTicker;
00072     this.notificationTitle = notificationTitle;
00073     nodeMainExecutorServiceConnection = new NodeMainExecutorServiceConnection();
00074   }
00075 
00076   @Override
00077   protected void onStart() {
00078     super.onStart();
00079     startNodeMainExecutorService();
00080   }
00081 
00082   private void startNodeMainExecutorService() {
00083     Intent intent = new Intent(this, NodeMainExecutorService.class);
00084     intent.setAction(NodeMainExecutorService.ACTION_START);
00085     intent.putExtra(NodeMainExecutorService.EXTRA_NOTIFICATION_TICKER, notificationTicker);
00086     intent.putExtra(NodeMainExecutorService.EXTRA_NOTIFICATION_TITLE, notificationTitle);
00087     startService(intent);
00088     Preconditions.checkState(
00089         bindService(intent, nodeMainExecutorServiceConnection, BIND_AUTO_CREATE),
00090         "Failed to bind NodeMainExecutorService.");
00091   }
00092 
00093   @Override
00094   protected void onDestroy() {
00095     if (nodeMainExecutorService != null) {
00096       nodeMainExecutorService.shutdown();
00097       unbindService(nodeMainExecutorServiceConnection);
00098       // NOTE(damonkohler): The activity could still be restarted. In that case,
00099       // nodeMainExectuorService needs to be null for everything to be started
00100       // up again.
00101       nodeMainExecutorService = null;
00102     }
00103     Toast.makeText(this, notificationTitle + " shut down.", Toast.LENGTH_SHORT).show();
00104     super.onDestroy();
00105   }
00106 
00116   protected abstract void init(NodeMainExecutor nodeMainExecutor);
00117 
00118   public void startMasterChooser() {
00119     Preconditions.checkState(getMasterUri() == null);
00120     // Call this method on super to avoid triggering our precondition in the
00121     // overridden startActivityForResult().
00122     super.startActivityForResult(new Intent(this, MasterChooser.class), 0);
00123   }
00124 
00125   public URI getMasterUri() {
00126     Preconditions.checkNotNull(nodeMainExecutorService);
00127     return nodeMainExecutorService.getMasterUri();
00128   }
00129 
00130   @Override
00131   public void startActivityForResult(Intent intent, int requestCode) {
00132     Preconditions.checkArgument(requestCode != MASTER_CHOOSER_REQUEST_CODE);
00133     super.startActivityForResult(intent, requestCode);
00134   }
00135 
00136   @Override
00137   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
00138     super.onActivityResult(requestCode, resultCode, data);
00139     if (resultCode == RESULT_OK) {
00140       if (requestCode == MASTER_CHOOSER_REQUEST_CODE) {
00141         if (data.getBooleanExtra("NEW_MASTER", false) == true) {
00142           AsyncTask<Boolean, Void, URI> task = new AsyncTask<Boolean, Void, URI>() {
00143             @Override
00144             protected URI doInBackground(Boolean[] params) {
00145               RosActivity.this.nodeMainExecutorService.startMaster(params[0]);
00146               return RosActivity.this.nodeMainExecutorService.getMasterUri();
00147             }
00148           };
00149           task.execute(data.getBooleanExtra("ROS_MASTER_PRIVATE", true));
00150           try {
00151             task.get();
00152           } catch (InterruptedException e) {
00153             e.printStackTrace();
00154           } catch (ExecutionException e) {
00155             e.printStackTrace();
00156           }
00157         } else {
00158           URI uri;
00159           try {
00160             uri = new URI(data.getStringExtra("ROS_MASTER_URI"));
00161           } catch (URISyntaxException e) {
00162             throw new RosRuntimeException(e);
00163           }
00164           nodeMainExecutorService.setMasterUri(uri);
00165         }
00166         // Run init() in a new thread as a convenience since it often requires
00167         // network access.
00168         new AsyncTask<Void, Void, Void>() {
00169           @Override
00170           protected Void doInBackground(Void... params) {
00171             RosActivity.this.init(nodeMainExecutorService);
00172             return null;
00173           }
00174         }.execute();
00175       } else {
00176         // Without a master URI configured, we are in an unusable state.
00177         nodeMainExecutorService.shutdown();
00178         finish();
00179       }
00180     }
00181   }
00182 }


android_core
Author(s): Damon Kohler
autogenerated on Thu Aug 27 2015 12:11:33