mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-27 12:26:48 +01:00
Implement music control (play, pause, next, previous). Try to make code a bit less Pebble centric.
This commit is contained in:
parent
20b3dffba6
commit
df8c290442
@ -72,6 +72,11 @@
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".StopServiceReceiver" />
|
||||
<receiver android:name=".GBMusicControlReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="nodomain.freeyourgadget.gadgetbridge.musiccontrol" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<activity
|
||||
android:name=".DebugActivity"
|
||||
|
@ -114,6 +114,23 @@ public class BluetoothCommunicationService extends Service {
|
||||
nm.notify(NOTIFICATION_ID, notification);
|
||||
}
|
||||
|
||||
private void evaluateGBCommandBundle(GBCommandBundle cmdBundle) {
|
||||
switch (cmdBundle.commandClass) {
|
||||
case MUSIC_CONTROL:
|
||||
Log.i(TAG, "Got command for MUSIC_CONTROL");
|
||||
Intent i = new Intent(GBMusicControlReceiver.ACTION_MUSICCONTROL);
|
||||
i.putExtra("command", cmdBundle.command.ordinal());
|
||||
sendBroadcast(i);
|
||||
break;
|
||||
case CALL_CONTROL:
|
||||
Log.i(TAG, "Got command for CALL_CONTROL");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
@ -183,13 +200,13 @@ public class BluetoothCommunicationService extends Service {
|
||||
byte[] msg = PebbleProtocol.encodeEmail(sender, subject, body);
|
||||
mBtSocketIoThread.write(msg);
|
||||
} else if (intent.getAction().equals(ACTION_CALLSTATE)) {
|
||||
byte phoneState = intent.getByteExtra("call_state", (byte) 0);
|
||||
GBCommand command = GBCommand.values()[intent.getIntExtra("call_command", 0)]; // UGLY
|
||||
String phoneNumber = intent.getStringExtra("call_phonenumber");
|
||||
String callerName = null;
|
||||
if (phoneNumber != null) {
|
||||
callerName = getContactDisplayNameByNumber(phoneNumber);
|
||||
}
|
||||
byte[] msg = PebbleProtocol.encodeSetPhoneState(phoneNumber, callerName, phoneState);
|
||||
byte[] msg = PebbleProtocol.encodeSetCallState(phoneNumber, callerName, command);
|
||||
mBtSocketIoThread.write(msg);
|
||||
} else if (intent.getAction().equals(ACTION_SETTIME)) {
|
||||
byte[] msg = PebbleProtocol.encodeSetTime(-1);
|
||||
@ -330,7 +347,12 @@ public class BluetoothCommunicationService extends Service {
|
||||
Log.i(TAG, "Pebble asked for Phone/App Version - repLYING!");
|
||||
write(PebbleProtocol.encodePhoneVersion(PebbleProtocol.PHONEVERSION_REMOTE_OS_ANDROID));
|
||||
} else if (endpoint != PebbleProtocol.ENDPOINT_DATALOG) {
|
||||
Log.i(TAG, "unhandled message to endpoint " + endpoint + " (" + bytes + " bytes)");
|
||||
GBCommandBundle cmdBundle = PebbleProtocol.decodeResponse(buffer);
|
||||
if (cmdBundle == null) {
|
||||
Log.i(TAG, "unhandled message to endpoint " + endpoint + " (" + bytes + " bytes)");
|
||||
} else {
|
||||
evaluateGBCommandBundle(cmdBundle);
|
||||
}
|
||||
}
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
|
@ -73,7 +73,7 @@ public class DebugActivity extends ActionBarActivity {
|
||||
Intent startIntent = new Intent(DebugActivity.this, BluetoothCommunicationService.class);
|
||||
startIntent.setAction(BluetoothCommunicationService.ACTION_CALLSTATE);
|
||||
startIntent.putExtra("call_phonenumber", editContent.getText().toString());
|
||||
startIntent.putExtra("call_state", PebbleProtocol.PHONECONTROL_INCOMINGCALL);
|
||||
startIntent.putExtra("call_command", GBCommand.CALL_INCOMING.ordinal());
|
||||
startService(startIntent);
|
||||
}
|
||||
});
|
||||
@ -84,7 +84,7 @@ public class DebugActivity extends ActionBarActivity {
|
||||
Intent startIntent = new Intent(DebugActivity.this, BluetoothCommunicationService.class);
|
||||
startIntent.setAction(BluetoothCommunicationService.ACTION_CALLSTATE);
|
||||
startIntent.putExtra("call_phonenumber", editContent.getText().toString());
|
||||
startIntent.putExtra("call_state", PebbleProtocol.PHONECONTROL_OUTGOINGCALL);
|
||||
startIntent.putExtra("call_command", GBCommand.CALL_OUTGOING.ordinal());
|
||||
startService(startIntent);
|
||||
}
|
||||
});
|
||||
@ -95,7 +95,7 @@ public class DebugActivity extends ActionBarActivity {
|
||||
public void onClick(View v) {
|
||||
Intent startIntent = new Intent(DebugActivity.this, BluetoothCommunicationService.class);
|
||||
startIntent.setAction(BluetoothCommunicationService.ACTION_CALLSTATE);
|
||||
startIntent.putExtra("call_state", PebbleProtocol.PHONECONTROL_START);
|
||||
startIntent.putExtra("call_command", GBCommand.CALL_START.ordinal());
|
||||
startService(startIntent);
|
||||
}
|
||||
});
|
||||
@ -105,7 +105,7 @@ public class DebugActivity extends ActionBarActivity {
|
||||
public void onClick(View v) {
|
||||
Intent startIntent = new Intent(DebugActivity.this, BluetoothCommunicationService.class);
|
||||
startIntent.setAction(BluetoothCommunicationService.ACTION_CALLSTATE);
|
||||
startIntent.putExtra("call_state", PebbleProtocol.PHONECONTROL_END);
|
||||
startIntent.putExtra("call_command", GBCommand.CALL_END.ordinal());
|
||||
startService(startIntent);
|
||||
}
|
||||
});
|
||||
|
@ -0,0 +1,20 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
public enum GBCommand {
|
||||
|
||||
UNDEFINEND,
|
||||
|
||||
CALL_ACCEPT,
|
||||
CALL_END,
|
||||
CALL_INCOMING,
|
||||
CALL_OUTGOING,
|
||||
CALL_PICKUP,
|
||||
CALL_REJECT,
|
||||
CALL_START,
|
||||
|
||||
MUSIC_PLAY,
|
||||
MUSIC_PAUSE,
|
||||
MUSIC_PLAYPAUSE,
|
||||
MUSIC_NEXT,
|
||||
MUSIC_PREVIOUS,
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
|
||||
public class GBCommandBundle {
|
||||
public GBCommandClass commandClass;
|
||||
public GBCommand command;
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
public enum GBCommandClass {
|
||||
MUSIC_CONTROL,
|
||||
CALL_CONTROL
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.SystemClock;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
public class GBMusicControlReceiver extends BroadcastReceiver {
|
||||
private final String TAG = this.getClass().getSimpleName();
|
||||
|
||||
public static final String ACTION_MUSICCONTROL = "nodomain.freeyourgadget.gadgetbridge.musiccontrol";
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
GBCommand command = GBCommand.values()[intent.getIntExtra("command", 0)];
|
||||
int keyCode;
|
||||
switch (command) {
|
||||
case MUSIC_NEXT:
|
||||
keyCode = KeyEvent.KEYCODE_MEDIA_NEXT;
|
||||
break;
|
||||
case MUSIC_PREVIOUS:
|
||||
keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS;
|
||||
break;
|
||||
case MUSIC_PLAY:
|
||||
keyCode = KeyEvent.KEYCODE_MEDIA_PLAY;
|
||||
break;
|
||||
case MUSIC_PAUSE:
|
||||
keyCode = KeyEvent.KEYCODE_MEDIA_PAUSE;
|
||||
break;
|
||||
case MUSIC_PLAYPAUSE:
|
||||
keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
long eventtime = SystemClock.uptimeMillis();
|
||||
|
||||
Intent downIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
|
||||
KeyEvent downEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_DOWN, keyCode, 0);
|
||||
downIntent.putExtra(Intent.EXTRA_KEY_EVENT, downEvent);
|
||||
context.sendOrderedBroadcast(downIntent, null);
|
||||
|
||||
Intent upIntent = new Intent(Intent.ACTION_MEDIA_BUTTON, null);
|
||||
KeyEvent upEvent = new KeyEvent(eventtime, eventtime, KeyEvent.ACTION_UP, keyCode, 0);
|
||||
upIntent.putExtra(Intent.EXTRA_KEY_EVENT, upEvent);
|
||||
context.sendOrderedBroadcast(upIntent, null);
|
||||
}
|
||||
}
|
@ -46,6 +46,14 @@ public class PebbleProtocol {
|
||||
static final byte PHONECONTROL_END = 9;
|
||||
|
||||
static final byte MUSICCONTROL_SETMUSICINFO = 16;
|
||||
static final byte MUSICCONTROL_PLAYPAUSE = 1;
|
||||
static final byte MUSICCONTROL_PAUSE = 2;
|
||||
static final byte MUSICCONTROL_PLAY = 3;
|
||||
static final byte MUSICCONTROL_NEXT = 4;
|
||||
static final byte MUSICCONTROL_PREVIOUS = 5;
|
||||
static final byte MUSICCONTROL_VOLUMEUP = 6;
|
||||
static final byte MUSICCONTROL_VOLUMEDOWN = 7;
|
||||
static final byte MUSICCONTROL_GETNOWPLAYING = 7;
|
||||
|
||||
static final short LENGTH_PREFIX = 4;
|
||||
static final short LENGTH_SETTIME = 9;
|
||||
@ -153,9 +161,26 @@ public class PebbleProtocol {
|
||||
return buf.array();
|
||||
}
|
||||
|
||||
public static byte[] encodeSetPhoneState(String number, String name, byte state) {
|
||||
public static byte[] encodeSetCallState(String number, String name, GBCommand command) {
|
||||
String[] parts = {number, name};
|
||||
return encodeMessage(ENDPOINT_PHONECONTROL, state, 0, parts);
|
||||
byte pebbleCmd;
|
||||
switch (command) {
|
||||
case CALL_START:
|
||||
pebbleCmd = PHONECONTROL_START;
|
||||
break;
|
||||
case CALL_END:
|
||||
pebbleCmd = PHONECONTROL_END;
|
||||
break;
|
||||
case CALL_INCOMING:
|
||||
pebbleCmd = PHONECONTROL_INCOMINGCALL;
|
||||
break;
|
||||
case CALL_OUTGOING:
|
||||
pebbleCmd = PHONECONTROL_OUTGOINGCALL;
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
return encodeMessage(ENDPOINT_PHONECONTROL, pebbleCmd, 0, parts);
|
||||
}
|
||||
|
||||
public static byte[] encodeSetMusicInfo(String artist, String album, String track) {
|
||||
@ -186,23 +211,41 @@ public class PebbleProtocol {
|
||||
return buf.array();
|
||||
}
|
||||
|
||||
// FIXME: that should return data into some unified struct/Class
|
||||
public static String decodeResponse(byte[] responseData) {
|
||||
public static GBCommandBundle decodeResponse(byte[] responseData) {
|
||||
ByteBuffer buf = ByteBuffer.wrap(responseData);
|
||||
buf.order(ByteOrder.BIG_ENDIAN);
|
||||
short length = buf.getShort();
|
||||
short endpoint = buf.getShort();
|
||||
byte extra = 0;
|
||||
|
||||
byte pebbleCmd = buf.get();
|
||||
GBCommandBundle cmd = new GBCommandBundle();
|
||||
switch (endpoint) {
|
||||
case ENDPOINT_PHONECONTROL:
|
||||
extra = buf.get();
|
||||
case ENDPOINT_MUSICCONTROL:
|
||||
cmd.commandClass = GBCommandClass.MUSIC_CONTROL;
|
||||
switch (pebbleCmd) {
|
||||
case MUSICCONTROL_NEXT:
|
||||
cmd.command = GBCommand.MUSIC_NEXT;
|
||||
break;
|
||||
case MUSICCONTROL_PREVIOUS:
|
||||
cmd.command = GBCommand.MUSIC_PREVIOUS;
|
||||
break;
|
||||
case MUSICCONTROL_PLAY:
|
||||
cmd.command = GBCommand.MUSIC_PLAY;
|
||||
break;
|
||||
case MUSICCONTROL_PAUSE:
|
||||
cmd.command = GBCommand.MUSIC_PAUSE;
|
||||
break;
|
||||
case MUSICCONTROL_PLAYPAUSE:
|
||||
cmd.command = GBCommand.MUSIC_PLAYPAUSE;
|
||||
break;
|
||||
default:
|
||||
cmd.command = GBCommand.UNDEFINEND;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
return null;
|
||||
}
|
||||
String ret = "length: " + Short.toString(length) + " Endpoint:" + Short.toString(endpoint) + "/" + Byte.toString(extra);
|
||||
|
||||
return ret;
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
@ -36,33 +36,33 @@ public class PhoneCallReceiver extends BroadcastReceiver {
|
||||
return;
|
||||
}
|
||||
|
||||
byte pebblePhoneCommand = -1; // TODO: dont assume Pebble here
|
||||
GBCommand callCommand = null;
|
||||
switch (state) {
|
||||
case TelephonyManager.CALL_STATE_RINGING:
|
||||
mSavedNumber = number;
|
||||
pebblePhoneCommand = PebbleProtocol.PHONECONTROL_INCOMINGCALL;
|
||||
callCommand = GBCommand.CALL_INCOMING;
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_OFFHOOK:
|
||||
if (mLastState == TelephonyManager.CALL_STATE_RINGING) {
|
||||
pebblePhoneCommand = PebbleProtocol.PHONECONTROL_START;
|
||||
callCommand = GBCommand.CALL_START;
|
||||
} else {
|
||||
pebblePhoneCommand = PebbleProtocol.PHONECONTROL_OUTGOINGCALL;
|
||||
callCommand = GBCommand.CALL_OUTGOING;
|
||||
}
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_IDLE:
|
||||
if (mLastState == TelephonyManager.CALL_STATE_RINGING) {
|
||||
//pebblePhoneCommand = PebbleProtocol.PHONECONTROL_MISSEDCALL;
|
||||
pebblePhoneCommand = PebbleProtocol.PHONECONTROL_END; // MISSED CALL DOES NOT WORK
|
||||
//missed call would be correct here
|
||||
callCommand = GBCommand.CALL_END;
|
||||
} else {
|
||||
pebblePhoneCommand = PebbleProtocol.PHONECONTROL_END;
|
||||
callCommand = GBCommand.CALL_END;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (pebblePhoneCommand != -1) {
|
||||
if (callCommand != null) {
|
||||
Intent startIntent = new Intent(context, BluetoothCommunicationService.class);
|
||||
startIntent.setAction(BluetoothCommunicationService.ACTION_CALLSTATE);
|
||||
startIntent.putExtra("call_phonenumber", mSavedNumber);
|
||||
startIntent.putExtra("call_state", pebblePhoneCommand);
|
||||
startIntent.putExtra("call_command", callCommand.ordinal());
|
||||
context.startService(startIntent);
|
||||
}
|
||||
mLastState = state;
|
||||
|
@ -10,8 +10,7 @@ public class StopServiceReceiver extends BroadcastReceiver {
|
||||
Intent stopIntent = new Intent(context, BluetoothCommunicationService.class);
|
||||
context.stopService(stopIntent);
|
||||
|
||||
Intent quitIntent = new Intent();
|
||||
quitIntent.setAction(ControlCenter.ACTION_QUIT);
|
||||
Intent quitIntent = new Intent(ControlCenter.ACTION_QUIT);
|
||||
context.sendBroadcast(quitIntent);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user