mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-19 09:54:15 +01:00
AndroidGCS: Create a fragment API.
The ObjectManagerFragment will automatically registers against the activity to be notified when an onOPConnected or onOPDisconnected method occurs. The Fragment API also duplicates the registerObjectUpdates(UAVObject) method from ObjectManagerActivity so that it's objectUpdated() method is called whenever and using the appropriate UI thread.
This commit is contained in:
parent
0f0e5faba0
commit
6bed9fcb3c
@ -4,6 +4,12 @@
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center" >
|
||||
|
||||
<fragment
|
||||
android:name="org.openpilot.androidgcs.SystemAlarmsFragment"
|
||||
android:id="@+id/viewer"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<TextView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/system_alarms_status"
|
||||
|
18
androidgcs/res/layout/system_alarms_fragment.xml
Normal file
18
androidgcs/res/layout/system_alarms_fragment.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar3"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/system_alarms_fragment_field"
|
||||
android:layout_width="200dip"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
@ -29,7 +29,7 @@ import android.widget.TextView;
|
||||
public abstract class ObjectManagerActivity extends Activity {
|
||||
|
||||
private final String TAG = "ObjectManagerActivity";
|
||||
private static int LOGLEVEL = 0;
|
||||
private static int LOGLEVEL = 1;
|
||||
// private static boolean WARN = LOGLEVEL > 1;
|
||||
private static boolean DEBUG = LOGLEVEL > 0;
|
||||
|
||||
@ -162,6 +162,9 @@ public abstract class ObjectManagerActivity extends Activity {
|
||||
stats.addUpdatedObserver(telemetryObserver);
|
||||
telemetryStatsConnected = true;
|
||||
updateStats();
|
||||
|
||||
if (DEBUG) Log.d(TAG, "Notifying listeners about connection. There are " + connectionListeners.countObservers());
|
||||
connectionListeners.connected();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,6 +178,9 @@ public abstract class ObjectManagerActivity extends Activity {
|
||||
TextView txRate = (TextView) findViewById(R.id.telemetry_stats_tx_rate);
|
||||
rxRate.setText("");
|
||||
txRate.setText("");
|
||||
|
||||
// Providing a null update triggers a disconnect on fragments
|
||||
connectionListeners.disconnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -223,6 +229,50 @@ public abstract class ObjectManagerActivity extends Activity {
|
||||
public void onBind() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callbacks so ObjectManagerFragments get the onOPConnected and onOPDisconnected signals
|
||||
*/
|
||||
class ConnectionObserver extends Observable {
|
||||
public void disconnected() {
|
||||
synchronized(this) {
|
||||
setChanged();
|
||||
notifyObservers();
|
||||
}
|
||||
}
|
||||
public void connected() {
|
||||
synchronized(this) {
|
||||
setChanged();
|
||||
notifyObservers(objMngr);
|
||||
}
|
||||
}
|
||||
};
|
||||
private ConnectionObserver connectionListeners = new ConnectionObserver();
|
||||
public class OnConnectionListener implements Observer {
|
||||
|
||||
// Local reference of the fragment to notify, store in constructor
|
||||
ObjectManagerFragment fragment;
|
||||
OnConnectionListener(ObjectManagerFragment fragment) { this.fragment = fragment; };
|
||||
|
||||
// Whenever the observer is updated either conenct or disconnect based on the data
|
||||
@Override
|
||||
public void update(Observable observable, Object data) {
|
||||
Log.d(TAG, "onConnectionListener called");
|
||||
if (data == null)
|
||||
fragment.onOPDisconnected();
|
||||
else
|
||||
fragment.onOPConnected(objMngr);
|
||||
}
|
||||
|
||||
} ;
|
||||
void addOnConnectionListenerFragment(ObjectManagerFragment frag) {
|
||||
connectionListeners.addObserver(new OnConnectionListener(frag));
|
||||
if (DEBUG) Log.d(TAG, "Connecting " + frag + " there are now " + connectionListeners.countObservers());
|
||||
if (mConnected)
|
||||
frag.onOPConnected(objMngr);
|
||||
}
|
||||
|
||||
|
||||
/** Defines callbacks for service binding, passed to bindService() */
|
||||
private ServiceConnection mConnection = new ServiceConnection() {
|
||||
|
@ -0,0 +1,102 @@
|
||||
package org.openpilot.androidgcs;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
|
||||
import org.openpilot.uavtalk.UAVObject;
|
||||
import org.openpilot.uavtalk.UAVObjectManager;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
|
||||
public class ObjectManagerFragment extends Fragment {
|
||||
|
||||
private static final String TAG = ObjectManagerFragment.class.getSimpleName();
|
||||
private static int LOGLEVEL = 1;
|
||||
// private static boolean WARN = LOGLEVEL > 1;
|
||||
private static boolean DEBUG = LOGLEVEL > 0;
|
||||
|
||||
UAVObjectManager objMngr;
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (DEBUG) Log.d(TAG, "Created an ObjectManagerFragment");
|
||||
// For an activity this registers against the telemetry service intents. Fragments must be notified by their
|
||||
// parent activity
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach to the parent activity so it can notify us when the connection
|
||||
* changed
|
||||
*/
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
if (DEBUG) Log.d(TAG,"onAttach");
|
||||
|
||||
((ObjectManagerActivity)activity).addOnConnectionListenerFragment(this);
|
||||
}
|
||||
|
||||
// The below methods should all be called by the parent activity at the appropriate times
|
||||
void onOPConnected(UAVObjectManager objMngr) {
|
||||
this.objMngr = objMngr;
|
||||
if (DEBUG) Log.d(TAG,"onOPConnected");
|
||||
}
|
||||
|
||||
void onOPDisconnected() {
|
||||
objMngr = null;
|
||||
if (DEBUG) Log.d(TAG,"onOPDisconnected");
|
||||
}
|
||||
|
||||
public void onBind() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called whenever any objects subscribed to via registerObjects
|
||||
*/
|
||||
protected void objectUpdated(UAVObject obj) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A message handler and a custom Observer to use it which calls
|
||||
* objectUpdated with the right object type
|
||||
*/
|
||||
final Handler uavobjHandler = new Handler();
|
||||
private class UpdatedObserver implements Observer {
|
||||
UAVObject obj;
|
||||
UpdatedObserver(UAVObject obj) { this.obj = obj; };
|
||||
public void update(Observable observable, Object data) {
|
||||
uavobjHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() { objectUpdated(obj); }
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Register an activity to receive updates from this object
|
||||
*
|
||||
* the objectUpdated() method will be called in the original UI thread
|
||||
*/
|
||||
protected void registerObjectUpdates(UAVObject object) {
|
||||
object.addUpdatedObserver(new UpdatedObserver(object));
|
||||
}
|
||||
protected void registerObjectUpdates(List<List<UAVObject>> objects) {
|
||||
ListIterator<List<UAVObject>> li = objects.listIterator();
|
||||
while(li.hasNext()) {
|
||||
ListIterator<UAVObject> li2 = li.next().listIterator();
|
||||
while(li2.hasNext())
|
||||
registerObjectUpdates(li2.next());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +1,14 @@
|
||||
package org.openpilot.androidgcs;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openpilot.uavtalk.UAVObject;
|
||||
import org.openpilot.uavtalk.UAVObjectField;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* All the work for this activity is performed by it's fragment
|
||||
*/
|
||||
public class SystemAlarmActivity extends ObjectManagerActivity {
|
||||
/**
|
||||
* Update the UI whenever the attitude is updated
|
||||
*/
|
||||
protected void objectUpdated(UAVObject obj) {
|
||||
if (obj.getName().compareTo("SystemAlarms") != 0)
|
||||
return;
|
||||
|
||||
TextView alarms = (TextView) findViewById(R.id.system_alarms_status);
|
||||
UAVObjectField a = obj.getField("Alarm");
|
||||
List<String> names = a.getElementNames();
|
||||
String contents = new String();
|
||||
List <String> options = a.getOptions();
|
||||
|
||||
// Rank the alarms by order of severity, skip uninitialized
|
||||
for (int j = options.size() - 1; j > 0; j--) {
|
||||
for (int i = 0; i < names.size(); i++) {
|
||||
if(a.getDouble(i) == j)
|
||||
contents += names.get(i) + " : " + a.getValue(i).toString() + "\n";
|
||||
}
|
||||
}
|
||||
alarms.setText(contents);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.system_alarms);
|
||||
}
|
||||
|
||||
@Override
|
||||
void onOPConnected() {
|
||||
super.onOPConnected();
|
||||
|
||||
// Connect the update method to AttitudeActual
|
||||
UAVObject obj = objMngr.getObject("SystemAlarms");
|
||||
if (obj != null)
|
||||
registerObjectUpdates(obj);
|
||||
objectUpdated(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
package org.openpilot.androidgcs;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.openpilot.uavtalk.UAVObject;
|
||||
import org.openpilot.uavtalk.UAVObjectField;
|
||||
import org.openpilot.uavtalk.UAVObjectManager;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class SystemAlarmsFragment extends ObjectManagerFragment {
|
||||
|
||||
private static final String TAG = SystemAlarmsFragment.class.getSimpleName();
|
||||
|
||||
//@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
return inflater.inflate(R.layout.system_alarms_fragment, container, false);
|
||||
}
|
||||
|
||||
public void onOPConnected(UAVObjectManager objMngr) {
|
||||
super.onOPConnected(objMngr);
|
||||
Log.d(TAG,"On connected");
|
||||
|
||||
UAVObject obj = objMngr.getObject("SystemAlarms");
|
||||
if (obj != null)
|
||||
registerObjectUpdates(obj);
|
||||
objectUpdated(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever any objects subscribed to via registerObjects
|
||||
*/
|
||||
@Override
|
||||
protected void objectUpdated(UAVObject obj) {
|
||||
Log.d(TAG, "Updated");
|
||||
if (obj.getName().compareTo("SystemAlarms") == 0) {
|
||||
TextView alarms = (TextView) getActivity().findViewById(R.id.system_alarms_fragment_field);
|
||||
UAVObjectField a = obj.getField("Alarm");
|
||||
List<String> names = a.getElementNames();
|
||||
String contents = new String();
|
||||
List <String> options = a.getOptions();
|
||||
|
||||
// Rank the alarms by order of severity, skip uninitialized
|
||||
for (int j = options.size() - 1; j > 0; j--) {
|
||||
for (int i = 0; i < names.size(); i++) {
|
||||
if(a.getDouble(i) == j)
|
||||
contents += names.get(i) + " : " + a.getValue(i).toString() + "\n";
|
||||
}
|
||||
}
|
||||
alarms.setText(contents);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user