1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2024-11-29 07:24:13 +01:00

Added a home page, added an option to select connection type. Made the

ListView adapter trigger updates on the data.
This commit is contained in:
James Cotton 2011-03-20 21:34:03 -05:00
parent 6613e4d3bf
commit 247d3a7754
11 changed files with 201 additions and 56 deletions

View File

@ -10,17 +10,23 @@
<application android:icon="@drawable/icon" android:label="@string/app_name">
<!-- Object browser - main activity at the moment -->
<activity android:name="ObjectBrowser" android:label="@string/app_name">
<activity android:name="HomePage" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="ObjectBrowser" android:label="@string/object_browser_name">
<intent-filter>
<action android:name="org.openpilot.intent.action.CONNECTED" />
<action android:name="org.openpilot.intent.action.DISCONNECTED" />
</intent-filter>
</activity>
<activity android:name="Preferences" android:label="@string/preference_title"/>
<receiver android:name="TelemetryWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />

View File

@ -16,6 +16,11 @@ UAVTalk.java - the actual communication layer. Can packetize an object and
insert into stream and process the incoming stream and update objects
accordingly.
** Threading
Currently object updates run within the thread of the function that called
update. This should be changed so that it adds a message to the Telemetry
thread which will then send on its own time.
---- MESSAGE PASSING ----
The current implementation/analog to the slots/sockets in QT are Observers
which are registered as added to an Observable. This is used extensibly within
@ -28,4 +33,38 @@ Activity) to instantiate a Handler to which messages or runnables are posted.
So for external objects they will register a runnable somehow...
--- TELEMETRY SERVICE ---
The telemetry connection will be maintained by a service separate from the the
main activity(s). Although it is a bit unusual, the service will support being
started and stopped, as well as being bound. Binding will be required to get
access to the Object Manager.
In addition, to make it forward looking, the start intent can specify a
connection to open. This will allow the service in future to monitor multiple
connections.
The service will destroy itself only when all active connections disappear and
all activies are unbound.
It will also handle any logging desired (I think).
There will be a primary message handler thread. This thread will separately
launch telemetry threads when required.
The service should send broadcast intents whenever a connection is estabilished
or dropped.
I dont think the service should have the options about which UAVs are
supported.
** Telemetry IBinder
*** Give handle to the ObjectManager for each UAV
*** Call disconnect
*** Query conncetion status
--- TELEMETRY WIDGET ---
Listens for conncet/disconnect intents
Also show if service is running?
Ability to launch service?

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button android:layout_alignParentTop="true" android:layout_height="wrap_content" android:text="@string/object_browser_name" android:layout_width="wrap_content" android:id="@+id/launch_object_browser"></Button>
</RelativeLayout>

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<string-array name="connectTypeArray">
<item>None</item>
<item>Fake</item>
<item>Bluetooth</item>
<item>Network</item>
</string-array>
<string-array name="connectTypeValues">
<item>0</item>
<item>1</item>
<item>2</item>
<item>3</item>
</string-array>
</resources>

View File

@ -1,8 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">OpenPilot GCS</string>
<string name="app_name">OpenPilot GCS Home</string>
<string name="object_browser_name">OpenPilot Object Browser</string>
<string name="menu_item_settings">Settings</string>
<string name="menu_item_connect">Connect</string>
<string name="menu_item_disconnect">Disconnect</string>
<string name="object_browser_title">OpenPilot Object Browser</string>
<string name="preference_title">Settings</string>
<string name="preference_checkbox_autoconnect">Automatically Connect</string>
<string name="preference_checkbox_connection_type">Connection Type</string>
<string name="preference_checkbox_bluetooth">Bluetooth</string>
<string name="preference_connection_method_summary">Select the connection method</string>
</resources>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference android:title="@string/preference_checkbox_autoconnect" android:key="autoconnect" />
<ListPreference
android:title="@string/preference_checkbox_connection_type"
android:key="connection_type"
android:summary="@string/preference_connection_method_summary"
android:defaultValue="None"
android:entries="@array/connectTypeArray"
android:entryValues="@array/connectTypeValues" />
</PreferenceScreen>

View File

@ -0,0 +1,23 @@
package org.openpilot.androidgcs;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class HomePage extends ObjectManagerActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gcs_home);
Button objectBrowser = (Button) findViewById(R.id.launch_object_browser);
objectBrowser.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
startActivity(new Intent(HomePage.this, ObjectBrowser.class));
}
});
}
}

View File

@ -16,6 +16,7 @@ import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
@ -24,6 +25,7 @@ import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
@ -48,8 +50,7 @@ public class OPTelemetryService extends Service {
// Message ids
static final int MSG_START = 0;
static final int MSG_CONNECT_BT = 1;
static final int MSG_CONNECT_FAKE = 2;
static final int MSG_CONNECT = 1;
static final int MSG_DISCONNECT = 3;
static final int MSG_TOAST = 100;
@ -70,14 +71,22 @@ public class OPTelemetryService extends Service {
Toast.makeText(OPTelemetryService.this, "HERE", Toast.LENGTH_SHORT);
System.out.println("HERE");
stopSelf(msg.arg2);
case MSG_CONNECT_BT:
case MSG_CONNECT:
terminate = false;
activeTelem = new BTTelemetryThread();
activeTelem.start();
break;
case MSG_CONNECT_FAKE:
terminate = false;
activeTelem = new FakeTelemetryThread();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(OPTelemetryService.this);
int connection_type = Integer.decode(prefs.getString("connection_type", ""));
switch(connection_type) {
case 0: // No connection
return;
case 1:
activeTelem = new FakeTelemetryThread();
break;
case 2:
activeTelem = new BTTelemetryThread();
break;
case 3:
throw new Error("Unsupported");
}
activeTelem.start();
break;
case MSG_DISCONNECT:
@ -146,14 +155,9 @@ public class OPTelemetryService extends Service {
public TelemTask getTelemTask(int id) {
return (TelemTask) activeTelem;
}
public void openFakeConnection() {
public void openConnection() {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = MSG_CONNECT_FAKE;
mServiceHandler.sendMessage(msg);
}
public void openBTConnection() {
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = MSG_CONNECT_BT;
msg.arg1 = MSG_CONNECT;
mServiceHandler.sendMessage(msg);
}
public void stopConnection() {
@ -161,6 +165,9 @@ public class OPTelemetryService extends Service {
msg.arg1 = MSG_DISCONNECT;
mServiceHandler.sendMessage(msg);
}
public boolean isConnected() {
return activeTelem != null;
}
};
public void toastMessage(String msgText) {

View File

@ -6,15 +6,20 @@ import java.util.ListIterator;
import java.util.Observable;
import java.util.Observer;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Adapter;
import android.widget.ArrayAdapter;
import android.widget.ExpandableListAdapter;
import android.widget.ExpandableListView;
@ -27,35 +32,12 @@ import android.widget.Toast;
import org.openpilot.uavtalk.UAVDataObject;
import org.openpilot.uavtalk.UAVObject;
public class ObjectBrowser extends ObjectManagerActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_connect:
binder.openBTConnection();
return true;
case R.id.menu_disconnect:
binder.stopConnection();
updateText.run();
return true;
case R.id.menu_settings:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
public class ObjectBrowser extends ObjectManagerActivity implements OnSharedPreferenceChangeListener {
private final String TAG = "ObjectBrower";
boolean connected;
SharedPreferences prefs;
ArrayAdapter<UAVDataObject> adapter;
final Handler uavobjHandler = new Handler();
final Runnable updateText = new Runnable() {
@ -70,6 +52,8 @@ public class ObjectBrowser extends ObjectManagerActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
}
@Override
@ -77,6 +61,17 @@ public class ObjectBrowser extends ObjectManagerActivity {
Toast.makeText(this,"Telemetry estabilished",Toast.LENGTH_SHORT);
Log.d(TAG, "onOPConnected()");
List<List<UAVDataObject>> allobjects = objMngr.getDataObjects();
List<UAVDataObject> linearized = new ArrayList<UAVDataObject>();
ListIterator<List<UAVDataObject>> li = allobjects.listIterator();
while(li.hasNext()) {
linearized.addAll(li.next());
}
adapter = new ArrayAdapter<UAVDataObject>(this,R.layout.object_view, linearized);
ListView objects = (ListView) findViewById(R.id.object_list);
objects.setAdapter(adapter);
UAVObject obj = objMngr.getObject("SystemStats");
if(obj != null)
obj.addUpdatedObserver(new Observer() {
@ -88,16 +83,12 @@ public class ObjectBrowser extends ObjectManagerActivity {
}
public void update() {
List<List<UAVDataObject>> allobjects = objMngr.getDataObjects();
List<UAVDataObject> linearized = new ArrayList<UAVDataObject>();
ListIterator<List<UAVDataObject>> li = allobjects.listIterator();
while(li.hasNext()) {
linearized.addAll(li.next());
}
adapter.notifyDataSetChanged();
}
ArrayAdapter<UAVDataObject> adapter = new ArrayAdapter<UAVDataObject>(this,R.layout.object_view, linearized);
ListView objects = (ListView) findViewById(R.id.object_list);
objects.setAdapter(adapter);
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
// TODO Auto-generated method stub
}
}

View File

@ -14,6 +14,9 @@ import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
public abstract class ObjectManagerActivity extends Activity {
@ -72,6 +75,31 @@ public abstract class ObjectManagerActivity extends Activity {
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_connect:
binder.openConnection();
return true;
case R.id.menu_disconnect:
binder.stopConnection();
return true;
case R.id.menu_settings:
startActivity(new Intent(this, Preferences.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_menu, menu);
return true;
}
@Override
public void onStart() {
super.onStart();

View File

@ -0,0 +1,12 @@
package org.openpilot.androidgcs;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class Preferences extends PreferenceActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}