Added AppManager, does not do anything useful yet. Only lists installed Apps.

This commit is contained in:
Andreas Shimokawa 2015-03-25 22:23:45 +01:00
parent 2e7f45433a
commit 0ccb818f58
14 changed files with 250 additions and 34 deletions

View File

@ -15,17 +15,20 @@
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/GadgetbridgeTheme">
<activity
android:name=".SettingsActivity"
android:label="@string/app_name" />
<activity
android:name=".ControlCenter"
android:label="@string/app_name">
android:label="@string/title_activity_controlcenter">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"
android:label="@string/title_activity_settings" />
<activity
android:name=".AppManagerActivity"
android:label="App Manager" />
<service
android:name=".NotificationListener"
@ -74,7 +77,6 @@
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
</intent-filter>
</receiver>
<receiver android:name=".StopServiceReceiver" />
<receiver android:name=".GBMusicControlReceiver">
<intent-filter>
<action android:name="nodomain.freeyourgadget.gadgetbridge.musiccontrol" />
@ -88,7 +90,7 @@
<activity
android:name=".DebugActivity"
android:label="@string/title_activity_debug"></activity>
android:label="@string/title_activity_debug" />
</application>
</manifest>

View File

@ -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<GBDeviceApp> 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);
}
}

View File

@ -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;

View File

@ -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);
}
}
});

View File

@ -17,5 +17,6 @@ public enum GBCommand {
MUSIC_NEXT,
MUSIC_PREVIOUS,
APP_INFO_NAME,
VERSION_FIRMWARE
}

View File

@ -4,5 +4,5 @@ package nodomain.freeyourgadget.gadgetbridge;
public class GBCommandBundle {
public GBCommandClass commandClass;
public GBCommand command;
public String info;
public String[] info;
}

View File

@ -3,5 +3,6 @@ package nodomain.freeyourgadget.gadgetbridge;
public enum GBCommandClass {
MUSIC_CONTROL,
CALL_CONTROL,
APP_INFO,
VERSION_INFO
}

View File

@ -16,7 +16,6 @@ public class GBDevice {
CONNECTED
}
public GBDevice(String address, String name) {
this.address = address;
this.name = name;

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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<GBDeviceApp> {
private final Context context;
private final List<GBDeviceApp> appList;
public GBDeviceAppAdapter(Context context, List<GBDeviceApp> 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;
}
}

View File

@ -0,0 +1,16 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="nodomain.freeyourgadget.gadgetbridge.AppManagerActivity">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/appListView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>

View File

@ -1,10 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Gadgetbridge</string>
<string name="title_activity_main">Gadgetbridge Control Center</string>
<string name="title_activity_controlcenter">Gadgetbridge</string>
<string name="action_settings">Settings</string>
<string name="action_debug">Debug</string>
<string name="action_quit">Quit</string>
<string name="title_activity_debug">Debug</string>
<string name="action_refresh" >Refresh</string>
<string name="title_activity_appmanager">App Manager</string>
<string name="title_activity_debug">Debug</string>
<!-- Strings related to Settings -->
<string name="title_activity_settings">Settings</string>
<string name="pref_header_general">General Settings</string>
<string name="pref_title_general_autoconnectonbluetooth">Connect to device when Bluetooth turned on</string>
<string name="pref_header_notifications">Notifications</string>
<string name="pref_title_notifications_sms">Notification for SMS</string>
<string name="pref_title_notifications_k9mail">Notification for K9-Mail</string>
<string name="pref_title_notifications_generic">Generic notification support</string>
<string name="pref_title_whenscreenon">… also when screen is on</string>
</resources>

View File

@ -1,13 +0,0 @@
<resources>
<!-- Strings related to Settings -->
<string name="pref_header_general">General Settings</string>
<string name="pref_title_general_autoconnectonbluetooth">Connect to device when Bluetooth turned on</string>
<!-- Strings related to Notifications -->
<string name="pref_header_notifications">Notifications</string>
<string name="pref_title_notifications_sms">Notification for SMS</string>
<string name="pref_title_notifications_k9mail">Notification for K9-Mail</string>
<string name="pref_title_notifications_generic">Generic notification support</string>
<string name="pref_title_whenscreenon">… also when screen is on</string>
</resources>