mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-11-23 18:36:50 +01:00
Various changes to Service, Activity and Notification handling
- Bluetooth connection is now established in BtSocketIOThread - Service is now started as soon as the main activity is started - changed "start service" button to "connect" button - quit button in service notification now also quits the main activity - Service notification now displays "Gadgetbride started", "connected to Pebble XXXXX" and "not connected" depending on connection state
This commit is contained in:
parent
ab233279e1
commit
243b9f0a88
@ -1,6 +1,7 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge;
|
package nodomain.freeyourgadget.gadgetbridge;
|
||||||
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
@ -8,6 +9,7 @@ import android.bluetooth.BluetoothDevice;
|
|||||||
import android.bluetooth.BluetoothSocket;
|
import android.bluetooth.BluetoothSocket;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
@ -25,13 +27,15 @@ import java.io.OutputStream;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class BluetoothCommunicationService extends Service {
|
public class BluetoothCommunicationService extends Service {
|
||||||
private static final String TAG = "BluetoothCommunicationService";
|
private static final String TAG = "BluetoothCommunicationService";
|
||||||
|
private static final int NOTIFICATION_ID = 1;
|
||||||
|
|
||||||
public static final String ACTION_START
|
public static final String ACTION_START
|
||||||
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.start";
|
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.start";
|
||||||
|
public static final String ACTION_CONNECT
|
||||||
|
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.connect";
|
||||||
public static final String ACTION_NOTIFICATION_GENERIC
|
public static final String ACTION_NOTIFICATION_GENERIC
|
||||||
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.notification_generic";
|
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.notification_generic";
|
||||||
public static final String ACTION_NOTIFICATION_SMS
|
public static final String ACTION_NOTIFICATION_SMS
|
||||||
@ -44,10 +48,10 @@ public class BluetoothCommunicationService extends Service {
|
|||||||
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.settime";
|
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.settime";
|
||||||
|
|
||||||
private BluetoothAdapter mBtAdapter = null;
|
private BluetoothAdapter mBtAdapter = null;
|
||||||
private String mBtDeviceAddress = null;
|
|
||||||
private BluetoothSocket mBtSocket = null;
|
private BluetoothSocket mBtSocket = null;
|
||||||
private BtSocketIoThread mBtSocketIoThread = null;
|
private BtSocketIoThread mBtSocketIoThread = null;
|
||||||
private static final UUID PEBBLE_UUID = UUID.fromString("00000000-deca-fade-deca-deafdecacafe");
|
|
||||||
|
private boolean mStarted = false;
|
||||||
|
|
||||||
private void setReceiversEnableState(boolean enable) {
|
private void setReceiversEnableState(boolean enable) {
|
||||||
final Class[] receiverClasses = {
|
final Class[] receiverClasses = {
|
||||||
@ -78,33 +82,57 @@ public class BluetoothCommunicationService extends Service {
|
|||||||
super.onCreate();
|
super.onCreate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Notification createNotification(String text) {
|
||||||
|
Intent notificationIntent = new Intent(this, ControlCenter.class);
|
||||||
|
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
|
||||||
|
notificationIntent, 0);
|
||||||
|
|
||||||
|
Intent stopIntent = new Intent(this, StopServiceReceiver.class);
|
||||||
|
PendingIntent pendingIntentStop = PendingIntent.getBroadcast(this, 0, stopIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
return new NotificationCompat.Builder(this)
|
||||||
|
.setContentTitle("Gadgetbridge")
|
||||||
|
.setTicker(text)
|
||||||
|
.setContentText(text)
|
||||||
|
.setSmallIcon(R.drawable.ic_launcher)
|
||||||
|
.addAction(android.R.drawable.ic_menu_close_clear_cancel, "Quit", pendingIntentStop)
|
||||||
|
.setContentIntent(pendingIntent)
|
||||||
|
.setOngoing(true).build();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateNotification(String text) {
|
||||||
|
|
||||||
|
Notification notification = createNotification(text);
|
||||||
|
|
||||||
|
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
|
nm.notify(NOTIFICATION_ID, notification);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
|
||||||
if (!intent.getAction().equals(ACTION_START) && mBtSocketIoThread == null) {
|
String action = intent.getAction();
|
||||||
|
|
||||||
|
if (!mStarted && !action.equals(ACTION_START)) {
|
||||||
|
// using the service before issuing ACTION_START
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mStarted && action.equals(ACTION_START)) {
|
||||||
|
// using ACTION_START when the service has already been started
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intent.getAction().equals(ACTION_START)) {
|
if (!action.equals(ACTION_START) && !action.equals(ACTION_CONNECT) && mBtSocket == null) {
|
||||||
Intent notificationIntent = new Intent(this, ControlCenter.class);
|
// trying to send notification without valid Blutooth socket
|
||||||
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
return START_STICKY;
|
||||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
}
|
||||||
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
|
|
||||||
notificationIntent, 0);
|
|
||||||
|
|
||||||
Intent stopIntent = new Intent(this, StopServiceReceiver.class);
|
|
||||||
PendingIntent pendingIntentStop = PendingIntent.getBroadcast(this, 0, stopIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
||||||
|
|
||||||
Notification notification = new NotificationCompat.Builder(this)
|
|
||||||
.setContentTitle("Gadgetbridge")
|
|
||||||
.setTicker("Gadgetbridge Running")
|
|
||||||
.setContentText("Gadgetbrige Running")
|
|
||||||
.setSmallIcon(R.drawable.ic_launcher)
|
|
||||||
.addAction(android.R.drawable.ic_menu_close_clear_cancel, "Quit", pendingIntentStop)
|
|
||||||
.setContentIntent(pendingIntent)
|
|
||||||
.setOngoing(true).build();
|
|
||||||
|
|
||||||
|
|
||||||
|
if (intent.getAction().equals(ACTION_CONNECT)) {
|
||||||
//Check the system status
|
//Check the system status
|
||||||
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
|
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||||
if (mBtAdapter == null) {
|
if (mBtAdapter == null) {
|
||||||
@ -112,30 +140,28 @@ public class BluetoothCommunicationService extends Service {
|
|||||||
} else if (!mBtAdapter.isEnabled()) {
|
} else if (!mBtAdapter.isEnabled()) {
|
||||||
Toast.makeText(this, "Bluetooth is disabled.", Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, "Bluetooth is disabled.", Toast.LENGTH_SHORT).show();
|
||||||
} else {
|
} else {
|
||||||
|
String btDeviceAddress = null;
|
||||||
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
|
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
|
||||||
for (BluetoothDevice device : pairedDevices) {
|
for (BluetoothDevice device : pairedDevices) {
|
||||||
if (device.getName().indexOf("Pebble") == 0) {
|
if (device.getName().indexOf("Pebble") == 0) {
|
||||||
// Matching device found
|
// Matching device found
|
||||||
mBtDeviceAddress = device.getAddress();
|
btDeviceAddress = device.getAddress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if (mBtSocket == null || !mBtSocket.isConnected()) {
|
||||||
if (mBtSocket == null || !mBtSocket.isConnected()) {
|
// currently only one thread allowed
|
||||||
BluetoothDevice btDevice = mBtAdapter.getRemoteDevice(mBtDeviceAddress);
|
if (mBtSocketIoThread != null) {
|
||||||
ParcelUuid uuids[] = btDevice.getUuids();
|
mBtSocketIoThread.quit();
|
||||||
mBtSocket = btDevice.createRfcommSocketToServiceRecord(uuids[0].getUuid());
|
try {
|
||||||
mBtSocket.connect();
|
mBtSocketIoThread.join();
|
||||||
mBtSocketIoThread = new BtSocketIoThread(mBtSocket.getInputStream(), mBtSocket.getOutputStream());
|
} catch (InterruptedException e) {
|
||||||
mBtSocketIoThread.start();
|
e.printStackTrace();
|
||||||
|
}
|
||||||
setReceiversEnableState(true); // enable BroadcastReceivers
|
|
||||||
}
|
}
|
||||||
|
mBtSocketIoThread = new BtSocketIoThread(btDeviceAddress);
|
||||||
} catch (IOException e) {
|
mBtSocketIoThread.start();
|
||||||
e.printStackTrace();
|
|
||||||
}
|
}
|
||||||
startForeground(1, notification); //FIXME: don't hardcode id
|
|
||||||
}
|
}
|
||||||
} else if (intent.getAction().equals(ACTION_NOTIFICATION_GENERIC)) {
|
} else if (intent.getAction().equals(ACTION_NOTIFICATION_GENERIC)) {
|
||||||
String title = intent.getStringExtra("notification_title");
|
String title = intent.getStringExtra("notification_title");
|
||||||
@ -163,7 +189,11 @@ public class BluetoothCommunicationService extends Service {
|
|||||||
} else if (intent.getAction().equals(ACTION_SETTIME)) {
|
} else if (intent.getAction().equals(ACTION_SETTIME)) {
|
||||||
byte[] msg = PebbleProtocol.encodeSetTime(-1);
|
byte[] msg = PebbleProtocol.encodeSetTime(-1);
|
||||||
mBtSocketIoThread.write(msg);
|
mBtSocketIoThread.write(msg);
|
||||||
|
} else if (intent.getAction().equals(ACTION_START)) {
|
||||||
|
startForeground(NOTIFICATION_ID, createNotification("Gadgetbridge running"));
|
||||||
|
mStarted = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,13 +211,8 @@ public class BluetoothCommunicationService extends Service {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mBtSocket != null) {
|
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
try {
|
nm.cancel(NOTIFICATION_ID); // need to do this because the updated notification wont be cancelled when service stops
|
||||||
mBtSocket.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -223,16 +248,40 @@ public class BluetoothCommunicationService extends Service {
|
|||||||
|
|
||||||
|
|
||||||
private class BtSocketIoThread extends Thread {
|
private class BtSocketIoThread extends Thread {
|
||||||
private final InputStream mmInStream;
|
private InputStream mmInStream = null;
|
||||||
private final OutputStream mmOutStream;
|
private OutputStream mmOutStream = null;
|
||||||
|
private final String mmBtDeviceAddress;
|
||||||
private boolean mQuit = false;
|
private boolean mQuit = false;
|
||||||
|
private boolean mmIsConnected = false;
|
||||||
|
|
||||||
public BtSocketIoThread(InputStream instream, OutputStream outstream) {
|
public BtSocketIoThread(String btDeviceAddress) {
|
||||||
mmInStream = instream;
|
mmBtDeviceAddress = btDeviceAddress;
|
||||||
mmOutStream = outstream;
|
}
|
||||||
|
|
||||||
|
private boolean connect(String btDeviceAddress) {
|
||||||
|
BluetoothDevice btDevice = mBtAdapter.getRemoteDevice(btDeviceAddress);
|
||||||
|
ParcelUuid uuids[] = btDevice.getUuids();
|
||||||
|
try {
|
||||||
|
mBtSocket = btDevice.createRfcommSocketToServiceRecord(uuids[0].getUuid());
|
||||||
|
mBtSocket.connect();
|
||||||
|
mmInStream = mBtSocket.getInputStream();
|
||||||
|
mmOutStream = mBtSocket.getOutputStream();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
mmInStream = null;
|
||||||
|
mmOutStream = null;
|
||||||
|
mBtSocket = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
updateNotification("connected to " + btDevice.getName());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() {
|
public void run() {
|
||||||
|
mmIsConnected = connect(mmBtDeviceAddress);
|
||||||
|
setReceiversEnableState(mmIsConnected); // enable/disable BroadcastReceivers
|
||||||
|
mQuit = !mmIsConnected; // quit if not connected
|
||||||
|
|
||||||
byte[] buffer = new byte[8192];
|
byte[] buffer = new byte[8192];
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
||||||
@ -286,18 +335,37 @@ public class BluetoothCommunicationService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mmIsConnected = false;
|
||||||
|
if (mBtSocket != null) {
|
||||||
|
try {
|
||||||
|
mBtSocket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mBtSocket = null;
|
||||||
|
updateNotification("not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized public void write(byte[] bytes) {
|
synchronized public void write(byte[] bytes) {
|
||||||
try {
|
if (mmIsConnected) {
|
||||||
mmOutStream.write(bytes);
|
try {
|
||||||
mmOutStream.flush();
|
mmOutStream.write(bytes);
|
||||||
} catch (IOException e) {
|
mmOutStream.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void quit() {
|
public void quit() {
|
||||||
mQuit = true;
|
mQuit = true;
|
||||||
|
if (mBtSocket != null) {
|
||||||
|
try {
|
||||||
|
mBtSocket.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge;
|
package nodomain.freeyourgadget.gadgetbridge;
|
||||||
|
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
@ -13,11 +16,10 @@ import android.view.View;
|
|||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class ControlCenter extends ActionBarActivity {
|
public class ControlCenter extends ActionBarActivity {
|
||||||
// SPP Serial Device UUID
|
|
||||||
private static final UUID SERIAL_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
|
public static final String ACTION_QUIT
|
||||||
|
= "nodomain.freeyourgadget.gadgetbride.controlcenter.action.quit";
|
||||||
|
|
||||||
Button sendButton;
|
Button sendButton;
|
||||||
Button testNotificationButton;
|
Button testNotificationButton;
|
||||||
@ -26,11 +28,21 @@ public class ControlCenter extends ActionBarActivity {
|
|||||||
EditText editTitle;
|
EditText editTitle;
|
||||||
EditText editContent;
|
EditText editContent;
|
||||||
|
|
||||||
|
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (intent.getAction().equals(ACTION_QUIT)) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_controlcenter);
|
setContentView(R.layout.activity_controlcenter);
|
||||||
|
|
||||||
|
registerReceiver(mReceiver, new IntentFilter(ACTION_QUIT));
|
||||||
|
|
||||||
editTitle = (EditText) findViewById(R.id.editTitle);
|
editTitle = (EditText) findViewById(R.id.editTitle);
|
||||||
editContent = (EditText) findViewById(R.id.editContent);
|
editContent = (EditText) findViewById(R.id.editContent);
|
||||||
@ -39,7 +51,7 @@ public class ControlCenter extends ActionBarActivity {
|
|||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
Intent startIntent = new Intent(ControlCenter.this, BluetoothCommunicationService.class);
|
Intent startIntent = new Intent(ControlCenter.this, BluetoothCommunicationService.class);
|
||||||
startIntent.setAction(BluetoothCommunicationService.ACTION_START);
|
startIntent.setAction(BluetoothCommunicationService.ACTION_CONNECT);
|
||||||
startService(startIntent);
|
startService(startIntent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -82,6 +94,10 @@ public class ControlCenter extends ActionBarActivity {
|
|||||||
Intent enableIntent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
|
Intent enableIntent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
|
||||||
startActivity(enableIntent);
|
startActivity(enableIntent);
|
||||||
}
|
}
|
||||||
|
Intent startIntent = new Intent(ControlCenter.this, BluetoothCommunicationService.class);
|
||||||
|
startIntent.setAction(BluetoothCommunicationService.ACTION_START);
|
||||||
|
startService(startIntent);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testNotification() {
|
private void testNotification() {
|
||||||
@ -118,4 +134,10 @@ public class ControlCenter extends ActionBarActivity {
|
|||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
unregisterReceiver(mReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -9,5 +9,9 @@ public class StopServiceReceiver extends BroadcastReceiver {
|
|||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
Intent stopIntent = new Intent(context, BluetoothCommunicationService.class);
|
Intent stopIntent = new Intent(context, BluetoothCommunicationService.class);
|
||||||
context.stopService(stopIntent);
|
context.stopService(stopIntent);
|
||||||
|
|
||||||
|
Intent quitIntent = new Intent();
|
||||||
|
quitIntent.setAction(ControlCenter.ACTION_QUIT);
|
||||||
|
context.sendBroadcast(quitIntent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<Button
|
<Button
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="start service"
|
android:text="connect"
|
||||||
android:id="@+id/startServiceButton"
|
android:id="@+id/startServiceButton"
|
||||||
android:layout_above="@+id/setTimeButton"
|
android:layout_above="@+id/setTimeButton"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_alignParentStart="true"
|
||||||
|
Loading…
Reference in New Issue
Block a user