MasterChooser.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.Context;
00023 import android.content.Intent;
00024 import android.content.SharedPreferences;
00025 import android.content.pm.PackageManager;
00026 import android.content.pm.ResolveInfo;
00027 import android.net.Uri;
00028 import android.os.AsyncTask;
00029 import android.os.Bundle;
00030 import android.text.Editable;
00031 import android.text.TextWatcher;
00032 import android.view.View;
00033 import android.widget.Button;
00034 import android.widget.CheckBox;
00035 import android.widget.EditText;
00036 import android.widget.Toast;
00037 import android.widget.AdapterView;
00038 import android.widget.ArrayAdapter;
00039 import android.widget.LinearLayout;
00040 import android.widget.ListView;
00041 import org.ros.android.android_10.R;
00042 import org.ros.exception.RosRuntimeException;
00043 import org.ros.internal.node.client.MasterClient;
00044 import org.ros.internal.node.xmlrpc.XmlRpcTimeoutException;
00045 import org.ros.namespace.GraphName;
00046 import org.ros.node.NodeConfiguration;
00047 
00048 import java.net.NetworkInterface;
00049 import java.net.SocketException;
00050 import java.net.URI;
00051 import java.net.URISyntaxException;
00052 import java.util.ArrayList;
00053 import java.util.Collections;
00054 import java.util.Enumeration;
00055 import java.util.HashMap;
00056 import java.util.List;
00057 
00069 public class MasterChooser extends Activity {
00070 
00075   private static final String PREFS_KEY_NAME = "URI_KEY";
00076 
00080   private static final String BAR_CODE_SCANNER_PACKAGE_NAME =
00081       "com.google.zxing.client.android.SCAN";
00082 
00083   private String selectedInterface;
00084   private EditText uriText;
00085   private Button connectButton;
00086 
00087   private class StableArrayAdapter extends ArrayAdapter<String> {
00088 
00089     HashMap<String, Integer> idMap = new HashMap<String, Integer>();
00090 
00091     public StableArrayAdapter(Context context, int textViewResourceId, List<String> objects) {
00092       super(context, textViewResourceId, objects);
00093       for (int i = 0; i < objects.size(); ++i) {
00094         idMap.put(objects.get(i), i);
00095       }
00096     }
00097 
00098     @Override
00099     public long getItemId(int position) {
00100       String item = getItem(position);
00101       return idMap.get(item);
00102     }
00103 
00104     @Override
00105     public boolean hasStableIds() {
00106       return true;
00107     }
00108   }
00109 
00110   @Override
00111   protected void onCreate(Bundle savedInstanceState) {
00112     super.onCreate(savedInstanceState);
00113     setContentView(R.layout.master_chooser);
00114     uriText = (EditText) findViewById(R.id.master_chooser_uri);
00115     connectButton = (Button) findViewById(R.id.master_chooser_ok);
00116     uriText.addTextChangedListener(new TextWatcher() {
00117       @Override
00118       public void onTextChanged(CharSequence s, int start, int before, int count) {
00119         if (s.length() > 0) {
00120           connectButton.setEnabled(true);
00121         } else {
00122           connectButton.setEnabled(false);
00123         }
00124       }
00125 
00126       @Override
00127       public void beforeTextChanged(CharSequence s, int start, int count, int after) {
00128       }
00129 
00130       @Override
00131       public void afterTextChanged(Editable s) {
00132       }
00133     });
00134 
00135     ListView interfacesList = (ListView) findViewById(R.id.networkInterfaces);
00136     final List<String> list = new ArrayList<String>();
00137 
00138     try {
00139       for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
00140         if (networkInterface.isUp() && !networkInterface.isLoopback()) {
00141           list.add(networkInterface.getName());
00142         }
00143       }
00144     } catch (SocketException e) {
00145       throw new RosRuntimeException(e);
00146     }
00147 
00148     // Fallback to previous behaviour when no interface is selected.
00149     selectedInterface = "";
00150 
00151     final StableArrayAdapter adapter = new StableArrayAdapter(this, android.R.layout.simple_list_item_1, list);
00152     interfacesList.setAdapter(adapter);
00153 
00154     interfacesList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
00155       @Override
00156       public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
00157         selectedInterface = parent.getItemAtPosition(position).toString();
00158       }
00159     });
00160 
00161     // Get the URI from preferences and display it. Since only primitive types
00162     // can be saved in preferences the URI is stored as a string.
00163     String uri =
00164         getPreferences(MODE_PRIVATE).getString(PREFS_KEY_NAME,
00165             NodeConfiguration.DEFAULT_MASTER_URI.toString());
00166     uriText.setText(uri);
00167   }
00168 
00169   @Override
00170   public void onActivityResult(int requestCode, int resultCode, Intent intent) {
00171     // If the Barcode Scanner returned a string then display that string.
00172     if (requestCode == 0) {
00173       if (resultCode == RESULT_OK) {
00174         String scanResultFormat = intent.getStringExtra("SCAN_RESULT_FORMAT");
00175         Preconditions.checkState(scanResultFormat.equals("TEXT_TYPE")
00176             || scanResultFormat.equals("QR_CODE"));
00177         String contents = intent.getStringExtra("SCAN_RESULT");
00178         uriText.setText(contents);
00179       }
00180     }
00181   }
00182 
00183   public void okButtonClicked(View unused) {
00184     // Prevent further edits while we verify the URI.
00185     uriText.setEnabled(false);
00186     connectButton.setEnabled(false);
00187     final String uri = uriText.getText().toString();
00188 
00189     // Make sure the URI can be parsed correctly and that the master is
00190     // reachable.
00191     new AsyncTask<Void, Void, Boolean>() {
00192       @Override
00193       protected Boolean doInBackground(Void... params) {
00194         try {
00195           toast("Trying to reach master...");
00196           MasterClient masterClient = new MasterClient(new URI(uri));
00197           masterClient.getUri(GraphName.of("android/master_chooser_activity"));
00198           toast("Connected!");
00199           return true;
00200         } catch (URISyntaxException e) {
00201           toast("Invalid URI.");
00202           return false;
00203         } catch (XmlRpcTimeoutException e) {
00204           toast("Master unreachable!");
00205           return false;
00206         }
00207       }
00208 
00209       @Override
00210       protected void onPostExecute(Boolean result) {
00211         if (result) {
00212           // If the displayed URI is valid then pack that into the intent.
00213           SharedPreferences.Editor editor = getPreferences(MODE_PRIVATE).edit();
00214           editor.putString(PREFS_KEY_NAME, uri);
00215           editor.commit();
00216           // Package the intent to be consumed by the calling activity.
00217           Intent intent = createNewMasterIntent(false, true);
00218           setResult(RESULT_OK, intent);
00219           finish();
00220         } else {
00221           connectButton.setEnabled(true);
00222           uriText.setEnabled(true);
00223         }
00224       }
00225     }.execute();
00226   }
00227 
00228   protected void toast(final String text) {
00229     runOnUiThread(new Runnable() {
00230       @Override
00231       public void run() {
00232         Toast.makeText(MasterChooser.this, text, Toast.LENGTH_SHORT).show();
00233       }
00234     });
00235   }
00236 
00237   public void qrCodeButtonClicked(View unused) {
00238     Intent intent = new Intent(BAR_CODE_SCANNER_PACKAGE_NAME);
00239     intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
00240     // Check if the Barcode Scanner is installed.
00241     if (!isQRCodeReaderInstalled(intent)) {
00242       // Open the Market and take them to the page from which they can download the Barcode Scanner
00243       // app.
00244       startActivity(new Intent(Intent.ACTION_VIEW,
00245           Uri.parse("market://details?id=com.google.zxing.client.android")));
00246     } else {
00247       // Call the Barcode Scanner to let the user scan a QR code.
00248       startActivityForResult(intent, 0);
00249     }
00250   }
00251 
00252   public void advancedCheckboxClicked(View view) {
00253     boolean checked = ((CheckBox) view).isChecked();
00254     LinearLayout advancedOptions = (LinearLayout) findViewById(R.id.advancedOptions);
00255     if (checked) {
00256       advancedOptions.setVisibility(View.VISIBLE);
00257     } else {
00258       advancedOptions.setVisibility(View.GONE);
00259     }
00260   }
00261 
00262   public Intent createNewMasterIntent(boolean newMaster, boolean isPrivate) {
00263     Intent intent = new Intent();
00264     final String uri = uriText.getText().toString();
00265     intent.putExtra("ROS_MASTER_CREATE_NEW", newMaster);
00266     intent.putExtra("ROS_MASTER_PRIVATE", isPrivate);
00267     intent.putExtra("ROS_MASTER_URI", uri);
00268     intent.putExtra("ROS_MASTER_NETWORK_INTERFACE", selectedInterface);
00269     return intent;
00270   }
00271 
00272   public void newMasterButtonClicked(View unused) {
00273     setResult(RESULT_OK, createNewMasterIntent(true, false));
00274     finish();
00275   }
00276 
00277   public void newPrivateMasterButtonClicked(View unused) {
00278     setResult(RESULT_OK, createNewMasterIntent(true, true));
00279     finish();
00280   }
00281 
00282   public void cancelButtonClicked(View unused) {
00283     setResult(RESULT_CANCELED);
00284     finish();
00285   }
00286 
00295   protected boolean isQRCodeReaderInstalled(Intent intent) {
00296     List<ResolveInfo> list =
00297         getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
00298     return (list.size() > 0);
00299   }
00300 }


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