diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a85e9fef4..fa4932240 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -15,17 +15,20 @@
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/GadgetbridgeTheme">
-
+ android:label="@string/title_activity_controlcenter">
+
+
-
@@ -88,7 +90,7 @@
+ android:label="@string/title_activity_debug" />
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/AppManagerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/AppManagerActivity.java
new file mode 100644
index 000000000..764aed0dc
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/AppManagerActivity.java
@@ -0,0 +1,69 @@
+package nodomain.freeyourgadget.gadgetbridge;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.widget.ListView;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import nodomain.freeyourgadget.gadgetbridge.adapter.GBDeviceAppAdapter;
+
+
+public class AppManagerActivity extends Activity {
+ private final String TAG = this.getClass().getSimpleName();
+
+ public static final String ACTION_REFRESH_APPLIST
+ = "nodomain.freeyourgadget.gadgetbride.appmanager.action.refresh_applist";
+
+ ListView appListView;
+ GBDeviceAppAdapter mGBDeviceAppAdapter;
+ final List appList = new ArrayList<>();
+
+ private BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (action.equals(ControlCenter.ACTION_QUIT)) {
+ finish();
+ } else if (action.equals(ACTION_REFRESH_APPLIST)) {
+ int appCount = intent.getIntExtra("app_count", 0);
+ for (Integer i = 0; i < appCount; i++) {
+ String appName = intent.getStringExtra("app_name" + i.toString());
+ String appCreator = intent.getStringExtra("app_creator" + i.toString());
+ appList.add(new GBDeviceApp(appName, appCreator, ""));
+ }
+ mGBDeviceAppAdapter.notifyDataSetChanged();
+ }
+ }
+ };
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_appmanager);
+
+ appListView = (ListView) findViewById(R.id.appListView);
+ mGBDeviceAppAdapter = new GBDeviceAppAdapter(this, appList);
+ appListView.setAdapter(this.mGBDeviceAppAdapter);
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ControlCenter.ACTION_QUIT);
+ filter.addAction(ACTION_REFRESH_APPLIST);
+ registerReceiver(mReceiver, filter);
+
+ Intent startIntent = new Intent(this, BluetoothCommunicationService.class);
+ startIntent.setAction(BluetoothCommunicationService.ACTION_REQUEST_APPINFO);
+ startService(startIntent);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ unregisterReceiver(mReceiver);
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java
index ba99aecd6..1095b78ef 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java
@@ -48,6 +48,9 @@ public class BluetoothCommunicationService extends Service {
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.setmusicinfo";
public static final String ACTION_REQUEST_VERSIONINFO
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.request_versioninfo";
+ public static final String ACTION_REQUEST_APPINFO
+ = "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.request_appinfo";
+
private static final String TAG = "BluetoothCommunicationService";
private static final int NOTIFICATION_ID = 1;
private BluetoothAdapter mBtAdapter = null;
@@ -129,12 +132,24 @@ public class BluetoothCommunicationService extends Service {
sendBroadcast(callIntent);
break;
case VERSION_INFO:
- Log.i(TAG, "Got command for VERSION INFO");
+ Log.i(TAG, "Got command for VERSION_INFO");
if (gbdevice == null) {
return;
}
- gbdevice.setFirmwareVersion(cmdBundle.info);
+ gbdevice.setFirmwareVersion(cmdBundle.info[0]);
sendDeviceUpdateIntent();
+ break;
+ case APP_INFO:
+ Log.i(TAG, "Got command for APP_INFO");
+ Intent appInfoIntent = new Intent(AppManagerActivity.ACTION_REFRESH_APPLIST);
+ int appCount = cmdBundle.info.length / 2;
+ appInfoIntent.putExtra("app_count", appCount);
+ for (Integer i = 0; i < appCount; i++) {
+ appInfoIntent.putExtra("app_name" + i.toString(), cmdBundle.info[i * 2]);
+ appInfoIntent.putExtra("app_creator" + i.toString(), cmdBundle.info[i * 2 + 1]);
+ }
+ sendBroadcast(appInfoIntent);
+ break;
default:
break;
}
@@ -248,6 +263,8 @@ public class BluetoothCommunicationService extends Service {
} else {
sendDeviceUpdateIntent();
}
+ } else if (action.equals(ACTION_REQUEST_APPINFO)) {
+ mBtSocketIoThread.write(PebbleProtocol.encodeAppInfoReq());
} else if (action.equals(ACTION_START)) {
startForeground(NOTIFICATION_ID, createNotification("Gadgetbridge running"));
mStarted = true;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java
index 71bb7f48a..1b0ab54c4 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java
@@ -75,11 +75,16 @@ public class ControlCenter extends Activity {
deviceListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View v, int position, long id) {
- Intent startIntent = new Intent(ControlCenter.this, BluetoothCommunicationService.class);
- startIntent.setAction(BluetoothCommunicationService.ACTION_CONNECT);
- startIntent.putExtra("device_address", deviceList.get(position).getAddress());
+ if (deviceList.get(position).getState() == GBDevice.State.CONNECTED) {
+ Intent startIntent = new Intent(ControlCenter.this, AppManagerActivity.class);
+ startActivity(startIntent);
+ } else {
+ Intent startIntent = new Intent(ControlCenter.this, BluetoothCommunicationService.class);
+ startIntent.setAction(BluetoothCommunicationService.ACTION_CONNECT);
+ startIntent.putExtra("device_address", deviceList.get(position).getAddress());
- startService(startIntent);
+ startService(startIntent);
+ }
}
});
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommand.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommand.java
index 9241d75ed..4f30e4b1e 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommand.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommand.java
@@ -17,5 +17,6 @@ public enum GBCommand {
MUSIC_NEXT,
MUSIC_PREVIOUS,
+ APP_INFO_NAME,
VERSION_FIRMWARE
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandBundle.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandBundle.java
index f63f79c78..a0c9eaef2 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandBundle.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandBundle.java
@@ -4,5 +4,5 @@ package nodomain.freeyourgadget.gadgetbridge;
public class GBCommandBundle {
public GBCommandClass commandClass;
public GBCommand command;
- public String info;
+ public String[] info;
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandClass.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandClass.java
index 0fd5aeebf..8faa4657b 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandClass.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandClass.java
@@ -3,5 +3,6 @@ package nodomain.freeyourgadget.gadgetbridge;
public enum GBCommandClass {
MUSIC_CONTROL,
CALL_CONTROL,
+ APP_INFO,
VERSION_INFO
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDevice.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDevice.java
index dbe3bcc57..d33666612 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDevice.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDevice.java
@@ -16,7 +16,6 @@ public class GBDevice {
CONNECTED
}
-
public GBDevice(String address, String name) {
this.address = address;
this.name = name;
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDeviceApp.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDeviceApp.java
new file mode 100644
index 000000000..17b122325
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDeviceApp.java
@@ -0,0 +1,25 @@
+package nodomain.freeyourgadget.gadgetbridge;
+
+public class GBDeviceApp {
+ private final String name;
+ private final String creator;
+ private final String version;
+
+ public GBDeviceApp(String name, String creator, String version) {
+ this.name = name;
+ this.creator = creator;
+ this.version = version;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getCreator() {
+ return creator;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java
index c1eadd93d..15ba3a529 100644
--- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java
@@ -60,12 +60,17 @@ public class PebbleProtocol {
static final byte MUSICCONTROL_VOLUMEDOWN = 7;
static final byte MUSICCONTROL_GETNOWPLAYING = 7;
+ static final byte TIME_GETTIME = 0;
+ static final byte TIME_SETTIME = 2;
+
+ static final byte FIRMWAREVERSION_GETVERSION = 0;
+
+ static final byte APPMANAGER_GETAPPBANKSTATUS = 1;
+
static final short LENGTH_PREFIX = 4;
static final short LENGTH_SETTIME = 9;
static final short LENGTH_PHONEVERSION = 21;
- static final byte TIME_GETTIME = 0;
- static final byte TIME_SETTIME = 2;
static final byte PHONEVERSION_APPVERSION_MAGIC = 2; // increase this if pebble complains
static final byte PHONEVERSION_APPVERSION_MAJOR = 2;
@@ -91,7 +96,7 @@ public class PebbleProtocol {
static final byte PHONEVERSION_REMOTE_OS_LINUX = 4;
static final byte PHONEVERSION_REMOTE_OS_WINDOWS = 5;
- static byte[] encodeMessage(short endpoint, byte type, int cookie, String[] parts) {
+ private static byte[] encodeMessage(short endpoint, byte type, int cookie, String[] parts) {
// Calculate length first
int length = LENGTH_PREFIX + 1;
if (parts != null) {
@@ -207,7 +212,11 @@ public class PebbleProtocol {
}
public static byte[] encodeFirmwareVersionReq() {
- return encodeMessage(ENDPOINT_FIRMWAREVERSION, (byte) 0, 0, null);
+ return encodeMessage(ENDPOINT_FIRMWAREVERSION, FIRMWAREVERSION_GETVERSION, 0, null);
+ }
+
+ public static byte[] encodeAppInfoReq() {
+ return encodeMessage(ENDPOINT_APPMANAGER, APPMANAGER_GETAPPBANKSTATUS, 0, null);
}
public static byte[] encodePhoneVersion(byte os) {
@@ -283,9 +292,37 @@ public class PebbleProtocol {
cmd.commandClass = GBCommandClass.VERSION_INFO;
cmd.command = GBCommand.VERSION_FIRMWARE;
- cmd.info = new String(versionString).trim();
+ cmd.info = new String[]{new String(versionString).trim()};
Log.i(TAG, "Got firmware version: " + cmd.info);
break;
+ case ENDPOINT_APPMANAGER:
+ cmd.commandClass = GBCommandClass.APP_INFO;
+ switch (pebbleCmd) {
+ case APPMANAGER_GETAPPBANKSTATUS:
+ cmd.command = GBCommand.APP_INFO_NAME;
+ int banks = buf.getInt();
+ int banksUsed = buf.getInt();
+ byte[] appName = new byte[32];
+ byte[] creatorName = new byte[32];
+ cmd.info = new String[banksUsed * 2];
+
+ for (int i = 0; i < banksUsed; i++) {
+ buf.getInt(); // id
+ buf.getInt(); // index
+ buf.get(appName, 0, 32);
+ buf.get(creatorName, 0, 32);
+ int flags = buf.getInt();
+ short appVersion = buf.getShort();
+ cmd.info[i * 2] = new String(appName).trim();
+ cmd.info[i * 2 + 1] = new String(creatorName).trim();
+ }
+ break;
+ default:
+ Log.i(TAG, "Unknown APPMANAGER command" + pebbleCmd);
+ cmd.command = GBCommand.UNDEFINEND;
+ break;
+ }
+ break;
default:
return null;
}
diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAppAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAppAdapter.java
new file mode 100644
index 000000000..dd7667079
--- /dev/null
+++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBDeviceAppAdapter.java
@@ -0,0 +1,44 @@
+package nodomain.freeyourgadget.gadgetbridge.adapter;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.TextView;
+
+import java.util.List;
+
+import nodomain.freeyourgadget.gadgetbridge.GBDeviceApp;
+import nodomain.freeyourgadget.gadgetbridge.R;
+
+public class GBDeviceAppAdapter extends ArrayAdapter {
+
+ private final Context context;
+ private final List appList;
+
+ public GBDeviceAppAdapter(Context context, List appList) {
+ super(context, 0, appList);
+
+ this.context = context;
+ this.appList = appList;
+ }
+
+ @Override
+ public View getView(int position, View view, ViewGroup parent) {
+ GBDeviceApp deviceApp = getItem(position);
+
+ if (view == null) {
+ LayoutInflater inflater = (LayoutInflater) context
+ .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+
+ view = inflater.inflate(R.layout.device_item, parent, false);
+ }
+ TextView deviceStatusLabel = (TextView) view.findViewById(R.id.device_status);
+ TextView deviceNameLabel = (TextView) view.findViewById(R.id.device_name);
+ deviceStatusLabel.setText(deviceApp.getVersion() + " by " + deviceApp.getCreator());
+ deviceNameLabel.setText(deviceApp.getName());
+
+ return view;
+ }
+}
diff --git a/app/src/main/res/layout/activity_appmanager.xml b/app/src/main/res/layout/activity_appmanager.xml
new file mode 100644
index 000000000..2c96678b7
--- /dev/null
+++ b/app/src/main/res/layout/activity_appmanager.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 71f0ab94b..ef82dae97 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -1,10 +1,23 @@
Gadgetbridge
- Gadgetbridge Control Center
+
+ Gadgetbridge
Settings
Debug
Quit
- Debug
Refresh
+
+ App Manager
+ Debug
+
+
+ Settings
+ General Settings
+ Connect to device when Bluetooth turned on
+ Notifications
+ Notification for SMS
+ Notification for K9-Mail
+ Generic notification support
+ … also when screen is on
diff --git a/app/src/main/res/values/strings_activity_settings.xml b/app/src/main/res/values/strings_activity_settings.xml
deleted file mode 100644
index 30093888f..000000000
--- a/app/src/main/res/values/strings_activity_settings.xml
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
- General Settings
- Connect to device when Bluetooth turned on
-
-
- Notifications
- Notification for SMS
- Notification for K9-Mail
- Generic notification support
- … also when screen is on
-