mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-30 20:45:49 +01:00
Amazfit Cor: implement basic music controls
Play/pause and skip to previous/next song work. The currently playing song name is shown on the Cor. The track length and progress are now shown as we don't know how to send these yet.
This commit is contained in:
parent
cc3c70b161
commit
3fac021ff2
@ -75,4 +75,16 @@ public class MusicSpec {
|
|||||||
result = 31 * result + trackNr;
|
result = 31 * result + trackNr;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MusicSpec{" +
|
||||||
|
"artist='" + artist + '\'' +
|
||||||
|
", album='" + album + '\'' +
|
||||||
|
", track='" + track + '\'' +
|
||||||
|
", duration=" + duration +
|
||||||
|
", trackCount=" + trackCount +
|
||||||
|
", trackNr=" + trackNr +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,4 +71,15 @@ public class MusicStateSpec {
|
|||||||
result = 31 * result + (int) repeat;
|
result = 31 * result + (int) repeat;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MusicStateSpec{" +
|
||||||
|
"state=" + state +
|
||||||
|
", position=" + position +
|
||||||
|
", playRate=" + playRate +
|
||||||
|
", shuffle=" + shuffle +
|
||||||
|
", repeat=" + repeat +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -171,6 +173,10 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
private RealtimeSamplesSupport realtimeSamplesSupport;
|
private RealtimeSamplesSupport realtimeSamplesSupport;
|
||||||
private boolean alarmClockRinging;
|
private boolean alarmClockRinging;
|
||||||
|
|
||||||
|
private boolean isMusicAppStarted = false;
|
||||||
|
private MusicSpec bufferMusicSpec = null;
|
||||||
|
private MusicStateSpec bufferMusicStateSpec = null;
|
||||||
|
|
||||||
public HuamiSupport() {
|
public HuamiSupport() {
|
||||||
this(LOG);
|
this(LOG);
|
||||||
}
|
}
|
||||||
@ -726,12 +732,102 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSetMusicState(MusicStateSpec stateSpec) {
|
public void onSetMusicState(MusicStateSpec stateSpec) {
|
||||||
// not supported
|
if (bufferMusicStateSpec != stateSpec)
|
||||||
|
bufferMusicStateSpec = stateSpec;
|
||||||
|
sendMusicStateToDevice();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSetMusicInfo(MusicSpec musicSpec) {
|
public void onSetMusicInfo(MusicSpec musicSpec) {
|
||||||
// not supported
|
if (bufferMusicSpec != musicSpec)
|
||||||
|
bufferMusicSpec = musicSpec;
|
||||||
|
|
||||||
|
if (!isMusicAppStarted) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendMusicStateToDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void sendMusicStateToDevice() {
|
||||||
|
|
||||||
|
|
||||||
|
if (characteristicChunked == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (bufferMusicSpec == null && bufferMusicStateSpec == null) {
|
||||||
|
try {
|
||||||
|
TransactionBuilder builder = performInitialized("send dummy playback info to enable music controls");
|
||||||
|
writeToChunked(builder, 3, new byte[]{1, 0, 1, 0, 0, 0, 1, 0});
|
||||||
|
builder.queue(getQueue());
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Unable to send dummy music controls");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte flags = 0x00;
|
||||||
|
flags |= 0x01;
|
||||||
|
int length = 8;
|
||||||
|
if (bufferMusicSpec.track != null && bufferMusicSpec.track.getBytes().length > 0) {
|
||||||
|
length += bufferMusicSpec.track.getBytes().length + 1;
|
||||||
|
flags |= 0x02;
|
||||||
|
}
|
||||||
|
if (bufferMusicSpec.album != null && bufferMusicSpec.album.getBytes().length > 0) {
|
||||||
|
length += bufferMusicSpec.album.getBytes().length + 1;
|
||||||
|
flags |= 0x04;
|
||||||
|
}
|
||||||
|
if (bufferMusicSpec.artist != null && bufferMusicSpec.artist.getBytes().length > 0) {
|
||||||
|
length += bufferMusicSpec.artist.getBytes().length + 1;
|
||||||
|
flags |= 0x08;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// LOG.info("Music flags are: " + (flags & 0xff));
|
||||||
|
try {
|
||||||
|
ByteBuffer buf = ByteBuffer.allocate(length);
|
||||||
|
buf.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
buf.put(flags);
|
||||||
|
byte state;
|
||||||
|
switch (bufferMusicStateSpec.state) {
|
||||||
|
case MusicStateSpec.STATE_PLAYING:
|
||||||
|
state = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.put(state);
|
||||||
|
buf.put(new byte[]{0x1, 0x0, 0x0, 0x0}); //unknown
|
||||||
|
buf.put(new byte[]{0x1,0x0}); //show track
|
||||||
|
// buf.put(new byte[]{0x1,0x1}); //show album
|
||||||
|
|
||||||
|
|
||||||
|
if (bufferMusicSpec.track != null && bufferMusicSpec.track.getBytes().length > 0) {
|
||||||
|
buf.put(bufferMusicSpec.track.getBytes());
|
||||||
|
buf.put((byte) 0);
|
||||||
|
}
|
||||||
|
if (bufferMusicSpec.album != null && bufferMusicSpec.album.getBytes().length > 0) {
|
||||||
|
buf.put(bufferMusicSpec.album.getBytes());
|
||||||
|
buf.put((byte) 0);
|
||||||
|
}
|
||||||
|
if (bufferMusicSpec.artist != null && bufferMusicSpec.artist.getBytes().length > 0) {
|
||||||
|
buf.put(bufferMusicSpec.artist.getBytes());
|
||||||
|
buf.put((byte) 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TransactionBuilder builder = performInitialized("send playback info");
|
||||||
|
writeToChunked(builder, 3, buf.array());
|
||||||
|
|
||||||
|
builder.queue(getQueue());
|
||||||
|
} catch (IOException e) {
|
||||||
|
LOG.error("Unable to send playback state");
|
||||||
|
}
|
||||||
|
|
||||||
|
// LOG.info("Sent music: " + bufferMusicSpec.toString() + " " + bufferMusicStateSpec.toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1012,6 +1108,15 @@ public class HuamiSupport extends AbstractBTLEDeviceSupport {
|
|||||||
case 6:
|
case 6:
|
||||||
deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.VOLUMEDOWN;
|
deviceEventMusicControl.event = GBDeviceEventMusicControl.Event.VOLUMEDOWN;
|
||||||
break;
|
break;
|
||||||
|
case (byte) 224:
|
||||||
|
LOG.info("Music app started");
|
||||||
|
isMusicAppStarted = true;
|
||||||
|
sendMusicStateToDevice();
|
||||||
|
break;
|
||||||
|
case (byte) 225:
|
||||||
|
LOG.info("Music app terminated");
|
||||||
|
isMusicAppStarted = false;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOG.info("unhandled music control event " + value[1]);
|
LOG.info("unhandled music control event " + value[1]);
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user