mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-10 12:09:27 +01:00
support removing apps/watchfaces
This commit is contained in:
parent
67a5917597
commit
42e53c3c8d
@ -6,6 +6,10 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ListView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -15,15 +19,8 @@ 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) {
|
||||
@ -31,16 +28,25 @@ public class AppManagerActivity extends Activity {
|
||||
if (action.equals(ControlCenter.ACTION_QUIT)) {
|
||||
finish();
|
||||
} else if (action.equals(ACTION_REFRESH_APPLIST)) {
|
||||
appList.clear();
|
||||
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, ""));
|
||||
int id = intent.getIntExtra("app_id" + i.toString(), -1);
|
||||
int index = intent.getIntExtra("app_index" + i.toString(), -1);
|
||||
|
||||
appList.add(new GBDeviceApp(id, index, appName, appCreator, ""));
|
||||
}
|
||||
mGBDeviceAppAdapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
};
|
||||
final List<GBDeviceApp> appList = new ArrayList<>();
|
||||
private final String TAG = this.getClass().getSimpleName();
|
||||
private ListView appListView;
|
||||
private GBDeviceAppAdapter mGBDeviceAppAdapter;
|
||||
private GBDeviceApp selectedApp = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -50,6 +56,7 @@ public class AppManagerActivity extends Activity {
|
||||
appListView = (ListView) findViewById(R.id.appListView);
|
||||
mGBDeviceAppAdapter = new GBDeviceAppAdapter(this, appList);
|
||||
appListView.setAdapter(this.mGBDeviceAppAdapter);
|
||||
registerForContextMenu(appListView);
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(ControlCenter.ACTION_QUIT);
|
||||
@ -61,6 +68,33 @@ public class AppManagerActivity extends Activity {
|
||||
startService(startIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
getMenuInflater().inflate(
|
||||
R.menu.appmanager_context, menu);
|
||||
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo) menuInfo;
|
||||
selectedApp = appList.get(acmi.position);
|
||||
menu.setHeaderTitle(selectedApp.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.appmanager_app_delete:
|
||||
if (selectedApp != null) {
|
||||
Intent deleteIntent = new Intent(this, BluetoothCommunicationService.class);
|
||||
deleteIntent.setAction(BluetoothCommunicationService.ACTION_DELETEAPP);
|
||||
deleteIntent.putExtra("app_id", selectedApp.getId());
|
||||
deleteIntent.putExtra("app_index", selectedApp.getIndex());
|
||||
startService(deleteIntent);
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
@ -31,6 +31,7 @@ import java.nio.ByteOrder;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommand;
|
||||
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandAppInfo;
|
||||
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandAppManagementResult;
|
||||
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandCallControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandMusicControl;
|
||||
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandVersionInfo;
|
||||
@ -57,6 +58,8 @@ public class BluetoothCommunicationService extends Service {
|
||||
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.request_versioninfo";
|
||||
public static final String ACTION_REQUEST_APPINFO
|
||||
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.request_appinfo";
|
||||
public static final String ACTION_DELETEAPP
|
||||
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.deleteapp";
|
||||
|
||||
private static final String TAG = "BluetoothCommunicationService";
|
||||
private static final int NOTIFICATION_ID = 1;
|
||||
@ -128,14 +131,14 @@ public class BluetoothCommunicationService extends Service {
|
||||
switch (deviceCmd.commandClass) {
|
||||
case MUSIC_CONTROL:
|
||||
Log.i(TAG, "Got command for MUSIC_CONTROL");
|
||||
GBDeviceCommandMusicControl musicCmd = (GBDeviceCommandMusicControl)deviceCmd;
|
||||
GBDeviceCommandMusicControl musicCmd = (GBDeviceCommandMusicControl) deviceCmd;
|
||||
Intent musicIntent = new Intent(GBMusicControlReceiver.ACTION_MUSICCONTROL);
|
||||
musicIntent.putExtra("command", musicCmd.command.ordinal());
|
||||
sendBroadcast(musicIntent);
|
||||
break;
|
||||
case CALL_CONTROL:
|
||||
Log.i(TAG, "Got command for CALL_CONTROL");
|
||||
GBDeviceCommandCallControl callCmd = (GBDeviceCommandCallControl)deviceCmd;
|
||||
GBDeviceCommandCallControl callCmd = (GBDeviceCommandCallControl) deviceCmd;
|
||||
Intent callIntent = new Intent(GBCallControlReceiver.ACTION_CALLCONTROL);
|
||||
callIntent.putExtra("command", callCmd.command.ordinal());
|
||||
sendBroadcast(callIntent);
|
||||
@ -145,22 +148,43 @@ public class BluetoothCommunicationService extends Service {
|
||||
if (gbdevice == null) {
|
||||
return;
|
||||
}
|
||||
GBDeviceCommandVersionInfo infoCmd = (GBDeviceCommandVersionInfo)deviceCmd;
|
||||
GBDeviceCommandVersionInfo infoCmd = (GBDeviceCommandVersionInfo) deviceCmd;
|
||||
gbdevice.setFirmwareVersion(infoCmd.fwVersion);
|
||||
sendDeviceUpdateIntent();
|
||||
break;
|
||||
case APP_INFO:
|
||||
Log.i(TAG, "Got command for APP_INFO");
|
||||
GBDeviceCommandAppInfo appInfoCmd = (GBDeviceCommandAppInfo)deviceCmd;
|
||||
GBDeviceCommandAppInfo appInfoCmd = (GBDeviceCommandAppInfo) deviceCmd;
|
||||
Intent appInfoIntent = new Intent(AppManagerActivity.ACTION_REFRESH_APPLIST);
|
||||
int appCount = appInfoCmd.apps.length;
|
||||
appInfoIntent.putExtra("app_count", appCount);
|
||||
for (Integer i = 0; i < appCount; i++) {
|
||||
appInfoIntent.putExtra("app_name" + i.toString(), appInfoCmd.apps[i].getName());
|
||||
appInfoIntent.putExtra("app_creator" + i.toString(), appInfoCmd.apps[i].getCreator());
|
||||
appInfoIntent.putExtra("app_id" + i.toString(), appInfoCmd.apps[i].getId());
|
||||
appInfoIntent.putExtra("app_index" + i.toString(), appInfoCmd.apps[i].getIndex());
|
||||
}
|
||||
sendBroadcast(appInfoIntent);
|
||||
break;
|
||||
case APP_MANAGEMENT_RES:
|
||||
GBDeviceCommandAppManagementResult appMgmtRes = (GBDeviceCommandAppManagementResult) deviceCmd;
|
||||
switch (appMgmtRes.type) {
|
||||
case DELETE:
|
||||
switch (appMgmtRes.result) {
|
||||
case FAILURE:
|
||||
Log.i(TAG, "failure removing app"); // TODO: report to AppManager
|
||||
break;
|
||||
case SUCCESS:
|
||||
// refresh app list
|
||||
mBtSocketIoThread.write(PebbleProtocol.encodeAppInfoReq());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -276,6 +300,10 @@ public class BluetoothCommunicationService extends Service {
|
||||
}
|
||||
} else if (action.equals(ACTION_REQUEST_APPINFO)) {
|
||||
mBtSocketIoThread.write(PebbleProtocol.encodeAppInfoReq());
|
||||
} else if (action.equals(ACTION_DELETEAPP)) {
|
||||
int id = intent.getIntExtra("app_id", -1);
|
||||
int index = intent.getIntExtra("app_index", -1);
|
||||
mBtSocketIoThread.write(PebbleProtocol.encodeAppDelete(id, index));
|
||||
} else if (action.equals(ACTION_START)) {
|
||||
startForeground(NOTIFICATION_ID, createNotification("Gadgetbridge running"));
|
||||
mStarted = true;
|
||||
|
@ -4,8 +4,12 @@ public class GBDeviceApp {
|
||||
private final String name;
|
||||
private final String creator;
|
||||
private final String version;
|
||||
private final int id;
|
||||
private final int index;
|
||||
|
||||
public GBDeviceApp(String name, String creator, String version) {
|
||||
public GBDeviceApp(int id, int index, String name, String creator, String version) {
|
||||
this.id = id;
|
||||
this.index = index;
|
||||
this.name = name;
|
||||
this.creator = creator;
|
||||
this.version = version;
|
||||
@ -22,4 +26,12 @@ public class GBDeviceApp {
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,8 @@ public abstract class GBDeviceCommand {
|
||||
MUSIC_CONTROL,
|
||||
CALL_CONTROL,
|
||||
APP_INFO,
|
||||
VERSION_INFO
|
||||
VERSION_INFO,
|
||||
APP_MANAGEMENT_RES,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,21 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.protocol;
|
||||
|
||||
public class GBDeviceCommandAppManagementResult extends GBDeviceCommand {
|
||||
public Result result = Result.UNKNOWN;
|
||||
public CommandType type = CommandType.UNKNOWN;
|
||||
|
||||
public GBDeviceCommandAppManagementResult() {
|
||||
commandClass = CommandClass.APP_MANAGEMENT_RES;
|
||||
}
|
||||
|
||||
public enum CommandType {
|
||||
UNKNOWN,
|
||||
DELETE,
|
||||
}
|
||||
|
||||
public enum Result {
|
||||
UNKNOWN,
|
||||
SUCCESS,
|
||||
FAILURE,
|
||||
}
|
||||
}
|
@ -69,10 +69,14 @@ public class PebbleProtocol {
|
||||
static final byte FIRMWAREVERSION_GETVERSION = 0;
|
||||
|
||||
static final byte APPMANAGER_GETAPPBANKSTATUS = 1;
|
||||
static final byte APPMANAGER_REMOVEAPP = 2;
|
||||
|
||||
static final int APPMANAGER_RES_SUCCESS = 1;
|
||||
|
||||
static final short LENGTH_PREFIX = 4;
|
||||
static final short LENGTH_SETTIME = 9;
|
||||
static final short LENGTH_PHONEVERSION = 21;
|
||||
static final short LENGTH_SETTIME = 5;
|
||||
static final short LENGTH_REMOVEAPP = 9;
|
||||
static final short LENGTH_PHONEVERSION = 17;
|
||||
|
||||
|
||||
static final byte PHONEVERSION_APPVERSION_MAGIC = 2; // increase this if pebble complains
|
||||
@ -166,9 +170,9 @@ public class PebbleProtocol {
|
||||
ts = System.currentTimeMillis() / 1000;
|
||||
ts += SimpleTimeZone.getDefault().getOffset(ts) / 1000;
|
||||
}
|
||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_SETTIME);
|
||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_SETTIME);
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
buf.putShort((short) (LENGTH_SETTIME - LENGTH_PREFIX));
|
||||
buf.putShort(LENGTH_SETTIME);
|
||||
buf.putShort(ENDPOINT_TIME);
|
||||
buf.put(TIME_SETTIME);
|
||||
buf.putInt((int) ts);
|
||||
@ -222,10 +226,22 @@ public class PebbleProtocol {
|
||||
return encodeMessage(ENDPOINT_APPMANAGER, APPMANAGER_GETAPPBANKSTATUS, 0, null);
|
||||
}
|
||||
|
||||
public static byte[] encodePhoneVersion(byte os) {
|
||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PHONEVERSION);
|
||||
public static byte[] encodeAppDelete(int id, int index) {
|
||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_REMOVEAPP);
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
buf.putShort((short) (LENGTH_PHONEVERSION - LENGTH_PREFIX));
|
||||
buf.putShort(LENGTH_REMOVEAPP);
|
||||
buf.putShort(ENDPOINT_APPMANAGER);
|
||||
buf.put(APPMANAGER_REMOVEAPP);
|
||||
buf.putInt(id);
|
||||
buf.putInt(index);
|
||||
|
||||
return buf.array();
|
||||
}
|
||||
|
||||
public static byte[] encodePhoneVersion(byte os) {
|
||||
ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_PHONEVERSION);
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
buf.putShort(LENGTH_PHONEVERSION);
|
||||
buf.putShort(ENDPOINT_PHONEVERSION);
|
||||
buf.put((byte) 0x01);
|
||||
buf.putInt(-1); //0xffffffff
|
||||
@ -296,7 +312,6 @@ public class PebbleProtocol {
|
||||
buf.get(versionString, 0, 32);
|
||||
|
||||
versionCmd.fwVersion = new String(versionString).trim();
|
||||
Log.i(TAG, "Got firmware version: " + versionCmd.fwVersion);
|
||||
cmd = versionCmd;
|
||||
break;
|
||||
case ENDPOINT_APPMANAGER:
|
||||
@ -310,23 +325,38 @@ public class PebbleProtocol {
|
||||
appInfoCmd.apps = new GBDeviceApp[banksUsed];
|
||||
|
||||
for (int i = 0; i < banksUsed; i++) {
|
||||
buf.getInt(); // id
|
||||
buf.getInt(); // index
|
||||
int id = buf.getInt();
|
||||
int index = buf.getInt();
|
||||
buf.get(appName, 0, 32);
|
||||
buf.get(creatorName, 0, 32);
|
||||
int flags = buf.getInt();
|
||||
Short appVersion = buf.getShort();
|
||||
appInfoCmd.apps[i] = new GBDeviceApp(new String(appName).trim(), new String(creatorName).trim(), appVersion.toString());
|
||||
appInfoCmd.apps[i] = new GBDeviceApp(id, index, new String(appName).trim(), new String(creatorName).trim(), appVersion.toString());
|
||||
}
|
||||
cmd = appInfoCmd;
|
||||
break;
|
||||
case APPMANAGER_REMOVEAPP:
|
||||
GBDeviceCommandAppManagementResult deleteRes = new GBDeviceCommandAppManagementResult();
|
||||
deleteRes.type = GBDeviceCommandAppManagementResult.CommandType.DELETE;
|
||||
|
||||
int result = buf.getInt();
|
||||
switch (result) {
|
||||
case APPMANAGER_RES_SUCCESS:
|
||||
deleteRes.result = GBDeviceCommandAppManagementResult.Result.SUCCESS;
|
||||
break;
|
||||
default:
|
||||
deleteRes.result = GBDeviceCommandAppManagementResult.Result.FAILURE;
|
||||
break;
|
||||
}
|
||||
cmd = deleteRes;
|
||||
break;
|
||||
default:
|
||||
Log.i(TAG, "Unknown APPMANAGER command" + pebbleCmd);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
break;
|
||||
}
|
||||
|
||||
return cmd;
|
||||
|
@ -8,9 +8,12 @@
|
||||
<string name="action_quit">Quit</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 AppManager -->
|
||||
<string name="title_activity_appmanager">App Manager</string>
|
||||
<string name="appmananger_app_delete">Delete</string>
|
||||
|
||||
<!-- Strings related to Settings -->
|
||||
<string name="title_activity_settings">Settings</string>
|
||||
<string name="pref_header_general">General Settings</string>
|
||||
|
Loading…
Reference in New Issue
Block a user