Connect to BLE device through service
This commit is contained in:
parent
192f65dd93
commit
f1a0f48628
4 changed files with 269 additions and 110 deletions
117
.idea/codeStyles/Project.xml
generated
Normal file
117
.idea/codeStyles/Project.xml
generated
Normal file
|
@ -0,0 +1,117 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
|
@ -21,10 +21,13 @@
|
|||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<service android:name=".LightsService">
|
||||
</service>
|
||||
</application>
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />
|
||||
</manifest>
|
67
app/src/main/java/uk/robware/vanlights/LightsService.java
Normal file
67
app/src/main/java/uk/robware/vanlights/LightsService.java
Normal file
|
@ -0,0 +1,67 @@
|
|||
package uk.robware.vanlights;
|
||||
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCallback;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattService;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.Binder;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class LightsService extends Service {
|
||||
private final IBinder binder = new LightsBinder();
|
||||
|
||||
public class LightsBinder extends Binder {
|
||||
LightsService getService() {
|
||||
return LightsService.this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return binder;
|
||||
}
|
||||
|
||||
private Handler handler = new Handler();
|
||||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
BluetoothDevice _device = bluetoothAdapter.getRemoteDevice("9C:9C:1F:E3:C0:26");
|
||||
private BluetoothGattCharacteristic _characteristic;
|
||||
private BluetoothGatt _gatt;
|
||||
BluetoothGattCallback gattCallback=new BluetoothGattCallback() {
|
||||
|
||||
@Override
|
||||
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
||||
if (status!=133) {
|
||||
gatt.discoverServices();
|
||||
_gatt = gatt;
|
||||
}else{
|
||||
handler.postDelayed(()->connect(), 500);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
|
||||
BluetoothGattService service = gatt.getService(UUID.fromString("4fafc201-1fb5-459e-8fcc-c5c9c331914b"));
|
||||
_characteristic = service.getCharacteristic(UUID.fromString("beb5483e-36e1-4688-b7f5-ea07361b26a8"));
|
||||
}
|
||||
};
|
||||
|
||||
public void connect(){
|
||||
_device.connectGatt(this, false, gattCallback);
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
_gatt.disconnect();
|
||||
}
|
||||
|
||||
public void write(String value){
|
||||
_characteristic.setValue(value);
|
||||
_gatt.writeCharacteristic(_characteristic);
|
||||
}
|
||||
}
|
|
@ -1,89 +1,77 @@
|
|||
package uk.robware.vanlights;
|
||||
|
||||
import android.Manifest;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.bluetooth.BluetoothGatt;
|
||||
import android.bluetooth.BluetoothGattCallback;
|
||||
import android.bluetooth.BluetoothGattCharacteristic;
|
||||
import android.bluetooth.BluetoothGattService;
|
||||
import android.bluetooth.le.BluetoothLeScanner;
|
||||
import android.bluetooth.le.ScanCallback;
|
||||
import android.bluetooth.le.ScanFilter;
|
||||
import android.bluetooth.le.ScanResult;
|
||||
import android.bluetooth.le.ScanSettings;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
private static final int ACCESS_COARSE_LOCATION_REQUEST = 2;
|
||||
|
||||
private Handler handler = new Handler();
|
||||
private ScanCallback leScanCallback=new ScanCallback() {
|
||||
@Override
|
||||
public void onScanResult(int callbackType, ScanResult result) {
|
||||
BluetoothDevice device = result.getDevice();
|
||||
Log.i("NAME", device.getName());
|
||||
if (device.getName()=="Van Lights"){
|
||||
Log.i("asdasd", "asdasd");
|
||||
}
|
||||
}
|
||||
private boolean hasPermissions() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (getApplicationContext().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
requestPermissions(new String[]{
|
||||
Manifest.permission.ACCESS_COARSE_LOCATION,
|
||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
||||
Manifest.permission.ACCESS_BACKGROUND_LOCATION
|
||||
}, ACCESS_COARSE_LOCATION_REQUEST);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBatchScanResults(List<ScanResult> results) {
|
||||
super.onBatchScanResults(results);
|
||||
// Ignore for now
|
||||
}
|
||||
private LightsService _lightsService;
|
||||
private boolean _lightsBound;
|
||||
private ServiceConnection _serviceConnection = new ServiceConnection() {
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
// We've bound to LocalService, cast the IBinder and get LocalService instance
|
||||
LightsService.LightsBinder binder = (LightsService.LightsBinder) service;
|
||||
_lightsService = binder.getService();
|
||||
_lightsBound = true;
|
||||
connect();
|
||||
Log.d("MAIN", "Lights service connected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanFailed(int errorCode) {
|
||||
super.onScanFailed(errorCode);
|
||||
// Ignore for now
|
||||
}
|
||||
};
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName arg0) {
|
||||
_lightsBound = false;
|
||||
Log.d("MAIN", "Lights service disconnected");
|
||||
}
|
||||
};
|
||||
|
||||
private void connect() {
|
||||
if (!_lightsBound) return;
|
||||
_lightsService.connect();
|
||||
}
|
||||
|
||||
private void disconnect() {
|
||||
if (!_lightsBound) return;
|
||||
_lightsService.disconnect();
|
||||
}
|
||||
|
||||
private void write(String message) {
|
||||
if (!_lightsBound) return;
|
||||
_lightsService.write(message);
|
||||
}
|
||||
|
||||
|
||||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
BluetoothDevice device = bluetoothAdapter.getRemoteDevice("9C:9C:1F:E3:C0:26");
|
||||
private BluetoothGattCharacteristic _characteristic;
|
||||
private BluetoothGatt _gatt;
|
||||
BluetoothGattCallback gattCallback=new BluetoothGattCallback() {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
hasPermissions();
|
||||
|
||||
@Override
|
||||
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
|
||||
gatt.discoverServices();
|
||||
_gatt=gatt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
|
||||
BluetoothGattService service = gatt.getService(UUID.fromString("4fafc201-1fb5-459e-8fcc-c5c9c331914b"));
|
||||
_characteristic = service.getCharacteristic(UUID.fromString("beb5483e-36e1-4688-b7f5-ea07361b26a8"));
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
//Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
|
||||
//getApplicationContext().startActivity(enableBtIntent);
|
||||
|
||||
hasPermissions();
|
||||
|
||||
//scanLeDevice();
|
||||
|
||||
device.connectGatt(this, true, gattCallback);
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
findViewById(R.id.seating_on_button).setOnClickListener(view -> write("seating on"));
|
||||
findViewById(R.id.seating_off_button).setOnClickListener(view -> write("seating off"));
|
||||
|
@ -93,52 +81,36 @@ public class MainActivity extends AppCompatActivity {
|
|||
|
||||
findViewById(R.id.all_on_button).setOnClickListener(view -> write("all on"));
|
||||
findViewById(R.id.all_off_button).setOnClickListener(view -> write("all off"));
|
||||
}
|
||||
}
|
||||
|
||||
private static final int ACCESS_COARSE_LOCATION_REQUEST = 2;
|
||||
private boolean hasPermissions() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (getApplicationContext().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
requestPermissions(new String[] { Manifest.permission.ACCESS_COARSE_LOCATION }, ACCESS_COARSE_LOCATION_REQUEST);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
|
||||
// Stops scanning after 10 seconds.
|
||||
private static final long SCAN_PERIOD = 10000;
|
||||
Intent intent = new Intent(this, LightsService.class);
|
||||
bindService(intent, _serviceConnection, Context.BIND_AUTO_CREATE);
|
||||
connect();
|
||||
}
|
||||
|
||||
private void scanLeDevice() {
|
||||
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
BluetoothLeScanner bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
disconnect();
|
||||
unbindService(_serviceConnection);
|
||||
_lightsBound = false;
|
||||
}
|
||||
|
||||
List<ScanFilter> filters = Collections.singletonList(new ScanFilter.Builder()
|
||||
//.setServiceUuid(ParcelUuid.fromString("4fafc201-1fb5-459e-8fcc-c5c9c331914b"))
|
||||
.setDeviceName("Van Lights")
|
||||
.build());
|
||||
|
||||
ScanSettings scanSettings = new ScanSettings.Builder()
|
||||
.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
|
||||
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
|
||||
.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
|
||||
.setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
|
||||
.setReportDelay(0L)
|
||||
.build();
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
connect();
|
||||
}
|
||||
|
||||
bluetoothLeScanner.startScan(leScanCallback);
|
||||
Log.i("BLE", "Scanning");
|
||||
|
||||
// Stops scanning after a predefined scan period.
|
||||
handler.postDelayed(() -> {
|
||||
bluetoothLeScanner.stopScan(leScanCallback);
|
||||
Log.i("BLE", "Stop scanning");
|
||||
}, SCAN_PERIOD);
|
||||
}
|
||||
|
||||
private void write(String value){
|
||||
_characteristic.setValue(value);
|
||||
_gatt.writeCharacteristic(_characteristic);
|
||||
}
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
disconnect();
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue