mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-01 09:24:10 +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:
parent
6613e4d3bf
commit
247d3a7754
@ -10,17 +10,23 @@
|
|||||||
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
<application android:icon="@drawable/icon" android:label="@string/app_name">
|
||||||
|
|
||||||
<!-- Object browser - main activity at the moment -->
|
<!-- 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>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
|
||||||
|
<activity android:name="ObjectBrowser" android:label="@string/object_browser_name">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="org.openpilot.intent.action.CONNECTED" />
|
<action android:name="org.openpilot.intent.action.CONNECTED" />
|
||||||
<action android:name="org.openpilot.intent.action.DISCONNECTED" />
|
<action android:name="org.openpilot.intent.action.DISCONNECTED" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name="Preferences" android:label="@string/preference_title"/>
|
||||||
|
|
||||||
<receiver android:name="TelemetryWidget">
|
<receiver android:name="TelemetryWidget">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||||
|
@ -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
|
insert into stream and process the incoming stream and update objects
|
||||||
accordingly.
|
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 ----
|
---- MESSAGE PASSING ----
|
||||||
The current implementation/analog to the slots/sockets in QT are Observers
|
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
|
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...
|
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?
|
||||||
|
7
androidgcs/res/layout/gcs_home.xml
Normal file
7
androidgcs/res/layout/gcs_home.xml
Normal 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>
|
15
androidgcs/res/values/arrays.xml
Normal file
15
androidgcs/res/values/arrays.xml
Normal 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>
|
@ -1,8 +1,13 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<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_settings">Settings</string>
|
||||||
<string name="menu_item_connect">Connect</string>
|
<string name="menu_item_connect">Connect</string>
|
||||||
<string name="menu_item_disconnect">Disconnect</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>
|
</resources>
|
||||||
|
12
androidgcs/res/xml/preferences.xml
Normal file
12
androidgcs/res/xml/preferences.xml
Normal 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>
|
23
androidgcs/src/org/openpilot/androidgcs/HomePage.java
Normal file
23
androidgcs/src/org/openpilot/androidgcs/HomePage.java
Normal 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));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,6 +16,7 @@ import android.app.PendingIntent;
|
|||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
@ -24,6 +25,7 @@ import android.os.IBinder;
|
|||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@ -48,8 +50,7 @@ public class OPTelemetryService extends Service {
|
|||||||
|
|
||||||
// Message ids
|
// Message ids
|
||||||
static final int MSG_START = 0;
|
static final int MSG_START = 0;
|
||||||
static final int MSG_CONNECT_BT = 1;
|
static final int MSG_CONNECT = 1;
|
||||||
static final int MSG_CONNECT_FAKE = 2;
|
|
||||||
static final int MSG_DISCONNECT = 3;
|
static final int MSG_DISCONNECT = 3;
|
||||||
static final int MSG_TOAST = 100;
|
static final int MSG_TOAST = 100;
|
||||||
|
|
||||||
@ -70,14 +71,22 @@ public class OPTelemetryService extends Service {
|
|||||||
Toast.makeText(OPTelemetryService.this, "HERE", Toast.LENGTH_SHORT);
|
Toast.makeText(OPTelemetryService.this, "HERE", Toast.LENGTH_SHORT);
|
||||||
System.out.println("HERE");
|
System.out.println("HERE");
|
||||||
stopSelf(msg.arg2);
|
stopSelf(msg.arg2);
|
||||||
case MSG_CONNECT_BT:
|
case MSG_CONNECT:
|
||||||
terminate = false;
|
terminate = false;
|
||||||
activeTelem = new BTTelemetryThread();
|
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(OPTelemetryService.this);
|
||||||
activeTelem.start();
|
int connection_type = Integer.decode(prefs.getString("connection_type", ""));
|
||||||
break;
|
switch(connection_type) {
|
||||||
case MSG_CONNECT_FAKE:
|
case 0: // No connection
|
||||||
terminate = false;
|
return;
|
||||||
activeTelem = new FakeTelemetryThread();
|
case 1:
|
||||||
|
activeTelem = new FakeTelemetryThread();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
activeTelem = new BTTelemetryThread();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
throw new Error("Unsupported");
|
||||||
|
}
|
||||||
activeTelem.start();
|
activeTelem.start();
|
||||||
break;
|
break;
|
||||||
case MSG_DISCONNECT:
|
case MSG_DISCONNECT:
|
||||||
@ -146,14 +155,9 @@ public class OPTelemetryService extends Service {
|
|||||||
public TelemTask getTelemTask(int id) {
|
public TelemTask getTelemTask(int id) {
|
||||||
return (TelemTask) activeTelem;
|
return (TelemTask) activeTelem;
|
||||||
}
|
}
|
||||||
public void openFakeConnection() {
|
public void openConnection() {
|
||||||
Message msg = mServiceHandler.obtainMessage();
|
Message msg = mServiceHandler.obtainMessage();
|
||||||
msg.arg1 = MSG_CONNECT_FAKE;
|
msg.arg1 = MSG_CONNECT;
|
||||||
mServiceHandler.sendMessage(msg);
|
|
||||||
}
|
|
||||||
public void openBTConnection() {
|
|
||||||
Message msg = mServiceHandler.obtainMessage();
|
|
||||||
msg.arg1 = MSG_CONNECT_BT;
|
|
||||||
mServiceHandler.sendMessage(msg);
|
mServiceHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
public void stopConnection() {
|
public void stopConnection() {
|
||||||
@ -161,6 +165,9 @@ public class OPTelemetryService extends Service {
|
|||||||
msg.arg1 = MSG_DISCONNECT;
|
msg.arg1 = MSG_DISCONNECT;
|
||||||
mServiceHandler.sendMessage(msg);
|
mServiceHandler.sendMessage(msg);
|
||||||
}
|
}
|
||||||
|
public boolean isConnected() {
|
||||||
|
return activeTelem != null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public void toastMessage(String msgText) {
|
public void toastMessage(String msgText) {
|
||||||
|
@ -6,15 +6,20 @@ import java.util.ListIterator;
|
|||||||
import java.util.Observable;
|
import java.util.Observable;
|
||||||
import java.util.Observer;
|
import java.util.Observer;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
|
||||||
import android.database.DataSetObserver;
|
import android.database.DataSetObserver;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
import android.preference.PreferenceManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Adapter;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.ExpandableListAdapter;
|
import android.widget.ExpandableListAdapter;
|
||||||
import android.widget.ExpandableListView;
|
import android.widget.ExpandableListView;
|
||||||
@ -27,35 +32,12 @@ import android.widget.Toast;
|
|||||||
import org.openpilot.uavtalk.UAVDataObject;
|
import org.openpilot.uavtalk.UAVDataObject;
|
||||||
import org.openpilot.uavtalk.UAVObject;
|
import org.openpilot.uavtalk.UAVObject;
|
||||||
|
|
||||||
public class ObjectBrowser extends ObjectManagerActivity {
|
public class ObjectBrowser extends ObjectManagerActivity implements OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
|
|
||||||
private final String TAG = "ObjectBrower";
|
private final String TAG = "ObjectBrower";
|
||||||
boolean connected;
|
boolean connected;
|
||||||
|
SharedPreferences prefs;
|
||||||
|
ArrayAdapter<UAVDataObject> adapter;
|
||||||
|
|
||||||
final Handler uavobjHandler = new Handler();
|
final Handler uavobjHandler = new Handler();
|
||||||
final Runnable updateText = new Runnable() {
|
final Runnable updateText = new Runnable() {
|
||||||
@ -70,6 +52,8 @@ public class ObjectBrowser extends ObjectManagerActivity {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.main);
|
setContentView(R.layout.main);
|
||||||
|
prefs = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
|
prefs.registerOnSharedPreferenceChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -77,6 +61,17 @@ public class ObjectBrowser extends ObjectManagerActivity {
|
|||||||
Toast.makeText(this,"Telemetry estabilished",Toast.LENGTH_SHORT);
|
Toast.makeText(this,"Telemetry estabilished",Toast.LENGTH_SHORT);
|
||||||
Log.d(TAG, "onOPConnected()");
|
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");
|
UAVObject obj = objMngr.getObject("SystemStats");
|
||||||
if(obj != null)
|
if(obj != null)
|
||||||
obj.addUpdatedObserver(new Observer() {
|
obj.addUpdatedObserver(new Observer() {
|
||||||
@ -88,16 +83,12 @@ public class ObjectBrowser extends ObjectManagerActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void update() {
|
public void update() {
|
||||||
List<List<UAVDataObject>> allobjects = objMngr.getDataObjects();
|
adapter.notifyDataSetChanged();
|
||||||
List<UAVDataObject> linearized = new ArrayList<UAVDataObject>();
|
}
|
||||||
ListIterator<List<UAVDataObject>> li = allobjects.listIterator();
|
|
||||||
while(li.hasNext()) {
|
|
||||||
linearized.addAll(li.next());
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayAdapter<UAVDataObject> adapter = new ArrayAdapter<UAVDataObject>(this,R.layout.object_view, linearized);
|
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
|
||||||
ListView objects = (ListView) findViewById(R.id.object_list);
|
String key) {
|
||||||
objects.setAdapter(adapter);
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@ import android.content.ServiceConnection;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
|
|
||||||
public abstract class ObjectManagerActivity extends Activity {
|
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
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {
|
||||||
super.onStart();
|
super.onStart();
|
||||||
|
12
androidgcs/src/org/openpilot/androidgcs/Preferences.java
Normal file
12
androidgcs/src/org/openpilot/androidgcs/Preferences.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user