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 
00028 import org.ros.address.InetAddressFactory;
00029 import org.ros.exception.RosRuntimeException;
00030 import org.ros.node.NodeMain;
00031 import org.ros.node.NodeMainExecutor;
00032 
00033 import java.net.NetworkInterface;
00034 import java.net.SocketException;
00035 import java.net.URI;
00036 import java.net.URISyntaxException;
00037 
00041 public abstract class RosActivity extends Activity {
00042 
00043   private static final int MASTER_CHOOSER_REQUEST_CODE = 0;
00044 
00045   private final NodeMainExecutorServiceConnection nodeMainExecutorServiceConnection;
00046   private final String notificationTicker;
00047   private final String notificationTitle;
00048 
00049   protected NodeMainExecutorService nodeMainExecutorService;
00050 
00051   private final class NodeMainExecutorServiceConnection implements ServiceConnection {
00052 
00053     private NodeMainExecutorServiceListener serviceListener;
00054     private URI customMasterUri;
00055 
00056     public NodeMainExecutorServiceConnection(URI customUri) {
00057       super();
00058       customMasterUri = customUri;
00059     }
00060 
00061     @Override
00062     public void onServiceConnected(ComponentName name, IBinder binder) {
00063       nodeMainExecutorService = ((NodeMainExecutorService.LocalBinder) binder).getService();
00064 
00065       if (customMasterUri != null) {
00066         nodeMainExecutorService.setMasterUri(customMasterUri);
00067         nodeMainExecutorService.setRosHostname(getDefaultHostAddress());
00068       }
00069 
00070       serviceListener = new NodeMainExecutorServiceListener() {
00071         @Override
00072         public void onShutdown(NodeMainExecutorService nodeMainExecutorService) {
00073           // We may have added multiple shutdown listeners and we only want to
00074           // call finish() once.
00075           if (!RosActivity.this.isFinishing()) {
00076             RosActivity.this.finish();
00077           }
00078         }
00079       };
00080       nodeMainExecutorService.addListener(serviceListener);
00081       if (getMasterUri() == null) {
00082         startMasterChooser();
00083       } else {
00084         init();
00085       }
00086     }
00087 
00088     @Override
00089     public void onServiceDisconnected(ComponentName name) {
00090       nodeMainExecutorService.removeListener(serviceListener);
00091       serviceListener = null;
00092     }
00093 
00094     public NodeMainExecutorServiceListener getServiceListener()
00095     {
00096       return serviceListener;
00097     }
00098   };
00099 
00100   protected RosActivity(String notificationTicker, String notificationTitle) {
00101     this(notificationTicker, notificationTitle, null);
00102   }
00103 
00104   protected RosActivity(String notificationTicker, String notificationTitle, URI customMasterUri) {
00105     super();
00106     this.notificationTicker = notificationTicker;
00107     this.notificationTitle = notificationTitle;
00108     nodeMainExecutorServiceConnection = new NodeMainExecutorServiceConnection(customMasterUri);
00109   }
00110 
00111   @Override
00112   protected void onStart() {
00113     super.onStart();
00114     bindNodeMainExecutorService();
00115   }
00116 
00117   protected void bindNodeMainExecutorService() {
00118     Intent intent = new Intent(this, NodeMainExecutorService.class);
00119     intent.setAction(NodeMainExecutorService.ACTION_START);
00120     intent.putExtra(NodeMainExecutorService.EXTRA_NOTIFICATION_TICKER, notificationTicker);
00121     intent.putExtra(NodeMainExecutorService.EXTRA_NOTIFICATION_TITLE, notificationTitle);
00122     startService(intent);
00123     Preconditions.checkState(
00124         bindService(intent, nodeMainExecutorServiceConnection, BIND_AUTO_CREATE),
00125         "Failed to bind NodeMainExecutorService.");
00126   }
00127 
00128   @Override
00129   protected void onDestroy() {
00130     unbindService(nodeMainExecutorServiceConnection);
00131     nodeMainExecutorService.
00132             removeListener(nodeMainExecutorServiceConnection.getServiceListener());
00133     super.onDestroy();
00134   }
00135 
00136   protected void init() {
00137     // Run init() in a new thread as a convenience since it often requires
00138     // network access.
00139     new AsyncTask<Void, Void, Void>() {
00140       @Override
00141       protected Void doInBackground(Void... params) {
00142         RosActivity.this.init(nodeMainExecutorService);
00143         return null;
00144       }
00145     }.execute();
00146   }
00147 
00157   protected abstract void init(NodeMainExecutor nodeMainExecutor);
00158 
00159   public void startMasterChooser() {
00160     Preconditions.checkState(getMasterUri() == null);
00161     // Call this method on super to avoid triggering our precondition in the
00162     // overridden startActivityForResult().
00163     super.startActivityForResult(new Intent(this, MasterChooser.class), 0);
00164   }
00165 
00166   public URI getMasterUri() {
00167     Preconditions.checkNotNull(nodeMainExecutorService);
00168     return nodeMainExecutorService.getMasterUri();
00169   }
00170 
00171   public String getRosHostname() {
00172     Preconditions.checkNotNull(nodeMainExecutorService);
00173     return nodeMainExecutorService.getRosHostname();
00174   }
00175 
00176   @Override
00177   public void startActivityForResult(Intent intent, int requestCode) {
00178     Preconditions.checkArgument(requestCode != MASTER_CHOOSER_REQUEST_CODE);
00179     super.startActivityForResult(intent, requestCode);
00180   }
00181 
00182   @Override
00183   protected void onActivityResult(int requestCode, int resultCode, Intent data) {
00184     super.onActivityResult(requestCode, resultCode, data);
00185     if (resultCode == RESULT_OK) {
00186       if (requestCode == MASTER_CHOOSER_REQUEST_CODE) {
00187         String host;
00188         String networkInterfaceName = data.getStringExtra("ROS_MASTER_NETWORK_INTERFACE");
00189         // Handles the default selection and prevents possible errors
00190         if (networkInterfaceName == null || networkInterfaceName.equals("")) {
00191           host = getDefaultHostAddress();
00192         } else {
00193           try {
00194             NetworkInterface networkInterface = NetworkInterface.getByName(networkInterfaceName);
00195             host = InetAddressFactory.newNonLoopbackForNetworkInterface(networkInterface).getHostAddress();
00196           } catch (SocketException e) {
00197             throw new RosRuntimeException(e);
00198           }
00199         }
00200         nodeMainExecutorService.setRosHostname(host);
00201         if (data.getBooleanExtra("ROS_MASTER_CREATE_NEW", false)) {
00202           nodeMainExecutorService.startMaster(data.getBooleanExtra("ROS_MASTER_PRIVATE", true));
00203         } else {
00204           URI uri;
00205           try {
00206             uri = new URI(data.getStringExtra("ROS_MASTER_URI"));
00207           } catch (URISyntaxException e) {
00208             throw new RosRuntimeException(e);
00209           }
00210           nodeMainExecutorService.setMasterUri(uri);
00211         }
00212         // Run init() in a new thread as a convenience since it often requires network access.
00213         new AsyncTask<Void, Void, Void>() {
00214           @Override
00215           protected Void doInBackground(Void... params) {
00216             RosActivity.this.init(nodeMainExecutorService);
00217             return null;
00218           }
00219         }.execute();
00220       } else {
00221         // Without a master URI configured, we are in an unusable state.
00222         nodeMainExecutorService.forceShutdown();
00223       }
00224     }
00225     super.onActivityResult(requestCode, resultCode, data);
00226   }
00227 
00228   private String getDefaultHostAddress() {
00229     return InetAddressFactory.newNonLoopback().getHostAddress();
00230   }
00231 }


android_core
Author(s): Damon Kohler
autogenerated on Thu Jun 6 2019 21:20:07