diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java index 605557ac1..a161508e7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java @@ -5,6 +5,7 @@ import android.app.PendingIntent; import android.app.Service; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothSocket; import android.content.Intent; import android.os.IBinder; @@ -17,22 +18,27 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Set; +import java.util.UUID; public class BluetoothCommunicationService extends Service { private static final String TAG = "BluetoothCommunicationService"; - // TODO: put in separate static class - public static final String ACTION_STARTBLUETOOTHCOMMUNITCATIONSERVICE + public static final String ACTION_START = "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.start"; - public static final String ACTION_STOPBLUETOOTHCOMMUNITCATIONSERVICE + public static final String ACTION_STOP = "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.stop"; - public static final String ACTION_SENDBLUETOOTHMESSAGE + public static final String ACTION_SENDMESSAGE = "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.sendbluetoothmessage"; + public static final String ACTION_SETTIME + = "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.settime"; private BluetoothAdapter mBtAdapter = null; private String mBtDeviceAddress = null; private BluetoothSocket mBtSocket = null; private BtSocketIoThread mBtSocketIoThread = null; + private BtSocketAcceptThread mBtSocketAcceptThread = null; + private static final UUID PEBBLE_UUID = UUID.fromString("00000000-deca-fade-deca-deafdecacafe"); + private boolean mPassiveMode = false; @Override public void onCreate() { @@ -41,7 +47,7 @@ public class BluetoothCommunicationService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { - if (intent.getAction().equals(ACTION_STARTBLUETOOTHCOMMUNITCATIONSERVICE)) { + if (intent.getAction().equals(ACTION_START)) { Intent notificationIntent = new Intent(this, ControlCenter.class); notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); @@ -73,7 +79,10 @@ public class BluetoothCommunicationService extends Service { } try { - if (mBtSocket == null || !mBtSocket.isConnected()) { + if (mPassiveMode) { + mBtSocketAcceptThread = new BtSocketAcceptThread(); + mBtSocketAcceptThread.start(); + } else if (mBtSocket == null || !mBtSocket.isConnected()) { BluetoothDevice btDevice = mBtAdapter.getRemoteDevice(mBtDeviceAddress); ParcelUuid uuids[] = btDevice.getUuids(); mBtSocket = btDevice.createRfcommSocketToServiceRecord(uuids[0].getUuid()); @@ -87,7 +96,7 @@ public class BluetoothCommunicationService extends Service { } startForeground(1, notification); //FIXME: don't hardcode id } - } else if (intent.getAction().equals(ACTION_STOPBLUETOOTHCOMMUNITCATIONSERVICE)) { + } else if (intent.getAction().equals(ACTION_STOP)) { try { mBtSocketIoThread.join(); } catch (InterruptedException e) { @@ -103,12 +112,16 @@ public class BluetoothCommunicationService extends Service { stopForeground(true); stopSelf(); - } else if (intent.getAction().equals(ACTION_SENDBLUETOOTHMESSAGE)) { + } else if (intent.getAction().equals(ACTION_SENDMESSAGE)) { String title = intent.getStringExtra("notification_title"); String content = intent.getStringExtra("notification_content"); if (mBtSocketIoThread != null) { - byte[] msg; - msg = PebbleProtocol.encodeSMS(title, content); + byte[] msg = PebbleProtocol.encodeSMS(title, content); + mBtSocketIoThread.write(msg); + } + } else if (intent.getAction().equals(ACTION_SETTIME)) { + if (mBtSocketIoThread != null) { + byte[] msg = PebbleProtocol.encodeSetTime(-1); mBtSocketIoThread.write(msg); } } @@ -125,6 +138,40 @@ public class BluetoothCommunicationService extends Service { return null; } + private class BtSocketAcceptThread extends Thread { + private final BluetoothServerSocket mmServerSocket; + + public BtSocketAcceptThread() { + BluetoothServerSocket tmp = null; + try { + tmp = mBtAdapter.listenUsingRfcommWithServiceRecord("PebbleListener", PEBBLE_UUID); + } catch (IOException e) { + } + mmServerSocket = tmp; + } + + public void run() { + while (true) { + try { + mBtSocket = mmServerSocket.accept(); + } catch (IOException e) { + e.printStackTrace(); + break; + } + if (mBtSocket != null) { + try { + mBtSocketIoThread = new BtSocketIoThread(mBtSocket.getInputStream(), mBtSocket.getOutputStream()); + } catch (IOException e) { + e.printStackTrace(); + break; + } + mBtSocketIoThread.start(); + break; + } + } + } + } + private class BtSocketIoThread extends Thread { private final InputStream mmInStream; private final OutputStream mmOutStream; @@ -141,6 +188,7 @@ public class BluetoothCommunicationService extends Service { while (true) { try { byte[] ping = {0, 0, 0, 0}; + byte[] version = {0x00, 0x0d, 0x00, 0x11, 0x01, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72}; // Read from the InputStream //bytes = mmInStream.read(buffer,0,2); //ByteBuffer buf = ByteBuffer.wrap(buffer); @@ -149,7 +197,7 @@ public class BluetoothCommunicationService extends Service { //Log.e(TAG,Integer.toString(length+4) + " as total length"); bytes = mmInStream.read(buffer); Log.e(TAG, Integer.toString(bytes) + ": " + PebbleProtocol.decodeResponse(buffer)); - write(ping); + //write(version); } catch (IOException e) { } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java index eb5431606..e98a90349 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/ControlCenter.java @@ -21,6 +21,7 @@ public class ControlCenter extends ActionBarActivity { Button sendButton; Button testNotificationButton; Button startServiceButton; + Button setTimeButton; EditText editTitle; EditText editContent; @@ -37,7 +38,7 @@ public class ControlCenter extends ActionBarActivity { @Override public void onClick(View v) { Intent startIntent = new Intent(ControlCenter.this, BluetoothCommunicationService.class); - startIntent.setAction(BluetoothCommunicationService.ACTION_STARTBLUETOOTHCOMMUNITCATIONSERVICE); + startIntent.setAction(BluetoothCommunicationService.ACTION_START); startService(startIntent); } }); @@ -46,12 +47,21 @@ public class ControlCenter extends ActionBarActivity { @Override public void onClick(View v) { Intent startIntent = new Intent(ControlCenter.this, BluetoothCommunicationService.class); - startIntent.setAction(BluetoothCommunicationService.ACTION_SENDBLUETOOTHMESSAGE); + startIntent.setAction(BluetoothCommunicationService.ACTION_SENDMESSAGE); startIntent.putExtra("notification_title", editTitle.getText().toString()); startIntent.putExtra("notification_content", editTitle.getText().toString()); startService(startIntent); } }); + setTimeButton = (Button) findViewById(R.id.setTimeButton); + setTimeButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent startIntent = new Intent(ControlCenter.this, BluetoothCommunicationService.class); + startIntent.setAction(BluetoothCommunicationService.ACTION_SETTIME); + startService(startIntent); + } + }); testNotificationButton = (Button) findViewById(R.id.testNotificationButton); testNotificationButton.setOnClickListener(new View.OnClickListener() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/NotificationListener.java index 6b1b274d4..bad1208b4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/NotificationListener.java @@ -31,7 +31,7 @@ public class NotificationListener extends NotificationListenerService { if (content != null) { Intent startIntent = new Intent(NotificationListener.this, BluetoothCommunicationService.class); - startIntent.setAction(BluetoothCommunicationService.ACTION_SENDBLUETOOTHMESSAGE); + startIntent.setAction(BluetoothCommunicationService.ACTION_SENDMESSAGE); startIntent.putExtra("notification_title", title); startIntent.putExtra("notification_content", content); startService(startIntent); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java index b08063442..389461fe0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java @@ -92,9 +92,11 @@ public class PebbleProtocol { return encodeMessage(ENDPOINT_NOTIFICATION, NOTIFICATION_EMAIL, parts); } - public static byte[] encodeSetTime() { - long ts = System.currentTimeMillis() / 1000; - ts += SimpleTimeZone.getDefault().getOffset(ts) / 1000; + public static byte[] encodeSetTime(long ts) { + if (ts == -1) { + ts = System.currentTimeMillis() / 1000; + ts += SimpleTimeZone.getDefault().getOffset(ts) / 1000; + } ByteBuffer buf = ByteBuffer.allocate(LENGTH_SETTIME); buf.order(ByteOrder.BIG_ENDIAN); buf.putShort((short) (LENGTH_SETTIME - LENGTH_PREFIX)); diff --git a/app/src/main/res/layout/activity_controlcenter.xml b/app/src/main/res/layout/activity_controlcenter.xml index 616f73214..0cf476069 100644 --- a/app/src/main/res/layout/activity_controlcenter.xml +++ b/app/src/main/res/layout/activity_controlcenter.xml @@ -60,4 +60,13 @@ android:layout_above="@+id/sendButton" android:layout_alignEnd="@+id/sendButton" android:layout_alignParentStart="true" /> + +