I have a service class and I fetch data from an Intent in the method "onHandleIntent" and pick up in a variable. I would to call the value of this variable in onCreate, but when I call this variable I get a NULL value. (for examole in onHandleIntent i have a variable a = True, but in onCreate this variable is not true). I would to take this variable from onHandleIntent to onCreate. This is my code:
public class LogService extends IntentService
{
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
SoundManager sm;
private boolean notifica = false;
private String id;
Boolean a = false;
private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 2100000000;
Handler handler;
public LogService()
{
super("LogService");
}
#Override
protected void onHandleIntent(Intent intent) {
id=(String) intent.getStringExtra("idc");
System.out.println("id1 e'" + id);
a = true;
}
#Override
public void onCreate() {
// ActiveBluetooth();
handler = new Handler();
super.onCreate();
// super.onCreate(savedInstanceState);
mHandler = new Handler();
System.out.println("Vero o falso?'" + a);
System.out.println("id e'" + id);
// Boolean a = getIntent().getExtras().getBoolean("ok");
// Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//startActivities(enableBtIntent, REQUEST_ENABLE_BT);
// Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
super.onDestroy();
}
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
super.onDestroy();
return;
}
// Checks if Bluetooth is supported on the device.
//onResume();
// BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
/* if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(this, "Auto attivazione blueooth: Bluetooth attivato.", Toast.LENGTH_SHORT).show();
mBluetoothAdapter.enable();
scanLeDevice(true);
Intent refresh = new Intent(LogService.this, LogService.class);
startService(refresh);
// Intent refresh = new Intent(this, LogService.class);
//startService(refresh);
Toast.makeText(this, "Refresh", Toast.LENGTH_SHORT).show();
}*/
// if (!mBluetoothAdapter.isEnabled()) {
// Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
// ab.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
//}
scanLeDevice(true);
}
/*
protected void onResume() {
// Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
// fire an intent to display a dialog asking the user to grant permission to enable it.
if (!mBluetoothAdapter.isEnabled()) {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
// Initializes list view adapter.
scanLeDevice(true);
}*/
private void scanLeDevice(final boolean enable) {
if (!mBluetoothAdapter.isEnabled() && notifica == false) {
Toast.makeText(this, "Auto attivazione blueooth: Bluetooth attivato.", Toast.LENGTH_SHORT).show();
mBluetoothAdapter.enable();
stopService(new Intent(this, LogService.class));
startService(new Intent(this, LogService.class));
}
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.i("Trovato", "Evento n.");
System.out.println("TROVATO");
notifica = true;
notifica(device.getAddress());
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
//System.out.println(device.getAddress());
onDestroy();
// mBluetoothAdapter.stopLeScan(mLeScanCallback);
try {
Thread.sleep(10000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
};
#Override
public void onDestroy()
{
Log.i("PROVA SERVICE", "Distruzione Service");
System.out.println("Distruzione");
// mScanning = false;
// mBluetoothAdapter.stopLeScan(mLeScanCallback); //� stato invocato il metodo onDestroy(), posso fermare la scansione
super.onDestroy();
}
private void runOnUiThread(Runnable runnable) {
handler.post(runnable);
}
private void notifica(String a) {
Log.i("Trovato", "Evento n.");
System.out.println("VAAAAAAAAA");
System.out.println("Indirizzo dispositivo" + a);
NotificationCompat.Builder n = new NotificationCompat.Builder(this);
// n.setLargeIcon(Imag);
n.setContentInfo("Affrettati!");
n.setContentTitle("La corriera e' in arrivo!");
n.setContentText(a);
n.setSmallIcon(R.drawable.bus);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, n.build());
sm.init(LogService.this);
sm.play();
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
Toast.makeText(this, "Auto disattivazione blueooth: Bluetooth disattivato.", Toast.LENGTH_SHORT).show();
mBluetoothAdapter.disable();
super.onDestroy();
}
}
Can someone help me? Thanks
mHandler = new Handler();
mHandler.onHandleIntent(Intent Var);
yes , when load your class .on create is the first run that method . so ,not initialized 'onHandleIntent' method.so , you call that method , within on create method.I think this will solve your problem.
note : you pass 'Intent' object as a parameter.
example :
Intent i = new Intent(LogService.this);
mHandler = new Handler();
mHandler.onHandleIntent(i);
Related
I want to be able to scan for BLE tags in the background.
I have read about using Services to do this. However, when the service is executed and then I run another application on my phone, the BLE scan callback stops executing but the service still runs as normal.
I know the BLE callback stops because the log cat stops producing the log data until I open the application again.
Below is my MainActiivity:
public class MainActivity extends AppCompatActivity {
BluetoothManager btManager;
BluetoothAdapter btAdapter;
BluetoothLeScanner btScanner;
Button startScanningButton;
Button stopScanningButton;
TextView peripheralTextView;
private NotificationManagerCompat notificationManager;
private final static int REQUEST_ENABLE_BT = 1;
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
private static final String TAG = "ExampleJobService";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate MAIN");
notificationManager = NotificationManagerCompat.from(this);
peripheralTextView = (TextView) findViewById(R.id.PeripheralTextView);
peripheralTextView.setMovementMethod(new ScrollingMovementMethod());
startScanningButton = (Button) findViewById(R.id.StartScanButton);
startScanningButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.d(TAG, "Start button");
startService(new Intent(MainActivity.this, ExampleService.class));
}
});
stopScanningButton = (Button) findViewById(R.id.StopScanButton);
stopScanningButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Log.d(TAG, "Stop 1");
Intent serviceIntent = new Intent(MainActivity.this, ExampleService.class);
stopScanning();
stopService(serviceIntent);
Log.d(TAG, "Stop 2");
}
});
btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
btAdapter = btManager.getAdapter();
btScanner = btAdapter.getBluetoothLeScanner();
if (btAdapter != null && !btAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent,REQUEST_ENABLE_BT);
}
// Make sure we have access coarse location enabled, if not, prompt the user to enable it
if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect peripherals.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_COARSE_LOCATION: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
System.out.println("coarse location permission granted");
} else {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Functionality limited");
builder.setMessage("Since location access has not been granted, this app will not be able to discover beacons when in the background.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
}
});
builder.show();
}
return;
}
}
}
public void startScanning() {
peripheralTextView.setText("");
AsyncTask.execute(new Runnable() {
#Override
public void run() {
btScanner.startScan(leScanCallback);
}
});
}
public void stopScanning() {
System.out.println("stopping scanning");
peripheralTextView.append("Stopped Scanning");
AsyncTask.execute(new Runnable() {
#Override
public void run() {
btScanner.stopScan(leScanCallback);
}
});
}
}
Below is the ExampleService:
public class ExampleService extends Service {
BluetoothManager btManager;
BluetoothAdapter btAdapter;
BluetoothLeScanner btScanner;
TextView peripheralTextView;
private NotificationManagerCompat notificationManager;
private static final String TAG = "ExampleJobService";
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
btManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
btAdapter = btManager.getAdapter();
btScanner = btAdapter.getBluetoothLeScanner();
//do heavy work on a background thread
AsyncTask.execute(new Runnable() {
#Override
public void run() {
btScanner.startScan(leScanCallback);
}
});
return START_REDELIVER_INTENT;
}
private ScanCallback leScanCallback = new ScanCallback() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onScanResult(int callbackType, ScanResult result) {
Log.d(TAG, "BLE executed");
if(result.getDevice().getAddress().equals("EE:7E:DE:9B:65:46") && result.getRssi() > -80){
Log.d(TAG, "Tag found");
}
}
};
#Override
public void onDestroy() {
Log.d(TAG, "Destroy");
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
EDIT 1:
String[] peripheralAddresses = new String[]{"EE:7E:DE:9B:65:46"};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Example Service")
.setContentText("input")
.setSmallIcon(R.drawable.ic_one)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
.build();
// Build filters list
List<ScanFilter> filters = null;
if (peripheralAddresses != null) {
filters = new ArrayList<>();
for (String address : peripheralAddresses) {
ScanFilter filter = new ScanFilter.Builder()
.setDeviceAddress(address)
.build();
filters.add(filter);
}
}
btScanner.startScan(filters, settings, leScanCallback);
return START_STICKY;
}
First, I recommend you to add Scan filters, because Android stops scan after some time if you scan without them.
Second, Your service will not live for a long time, because Android will kill it, if your device's Android versions is more or equal Android Oreo (Android 8).
So I recommend you to read this article for finding better solution.
Hope, this will help you!
I am trying to develop an Android app capable to connect to a BLE device. But i have a problem to find ble devices. The scanLeDevice methods run but I have no callback. You can find my code below: I use Log.i() to display ble devices.
With another app (downloaded from the store) I can find my ble device and others bluetooth around. So It's not my phone's problem.
Thanks for help!
public class MainActivity extends AppCompatActivity {
private BluetoothAdapter bluetoothAdapter;
private final int REQUEST_ENABLE_BT = 1;
private boolean mScanning;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 10000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.i("MainActivity", "Begin");
// Initializes Bluetooth adapter.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
Log.i("MainActivity", "End for permissions");
if(Build.VERSION.SDK_INT < 21){
scanLeDevice(true);
}else{
scanDevice(true);
}
}
private Handler handler = new Handler();
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
handler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
bluetoothAdapter.stopLeScan(leScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
bluetoothAdapter.startLeScan(leScanCallback);
Log.i("MainActivity", "scanning");
} else {
mScanning = false;
bluetoothAdapter.stopLeScan(leScanCallback);
}
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback leScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, int rssi,
byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//Ici///////////////////////////////////////
Log.i("MainActivity", "Nam: "+device.getName()+" Adresse: "+device.getAddress());
if(device.getName() != null && device.getName().equals("RN4871-85D7"))
scanLeDevice(false);
}
});
}
};
///////////////////Scan for API 21
private ScanSettings settings;
private List<ScanFilter> filters;
private BluetoothLeScanner mLEScanner;
private void scanDevice(final boolean enable){
if (mLEScanner==null){
mLEScanner = bluetoothAdapter.getBluetoothLeScanner();
settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
filters = new ArrayList<ScanFilter>();
}
if (enable) {
if (mScanning) return;
// Stops scanning after a pre-defined scan period.
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (!mScanning) return;
try {
mScanning = false;
//Log.d("MainActivity","STOP SCAN AFTER DELAY");
mLEScanner.stopScan(mScanCallback);
Log.i("MainActivity", "stop scanning API 21");
} catch (Exception e){Log.e("MainActivity",e.getMessage());}
}
}, SCAN_PERIOD);
mScanning = true;
//Log.d("MainActivity","START SCAN FROM EXPLICIT CALL");
mLEScanner.startScan(filters, settings, mScanCallback);
Log.i("MainActivity", "scanning API 21");
} else if (mLEScanner!=null){
if (!mScanning) return;
mScanning = false;
try {
//Log.d("MainActivity","STOP SCAN FROM EXPLICIT CALL");
mLEScanner.stopScan(mScanCallback);
Log.i("MainActivity", "stop scanning API 21");
} catch (Exception e){Log.i("MainActivity",e.getMessage());}
}
}
//call back for API 21
//#TargetApi(21)
private ScanCallback mScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
Log.i("MainActivity", "onScanResult API 21");
}
#Override
public void onBatchScanResults(List<ScanResult> results) {
super.onBatchScanResults(results);
Log.i("MainActivity", "onBatchScanResults API 21");
}
#Override
public void onScanFailed(int errorCode) {
super.onScanFailed(errorCode);
Log.i("MainActivity", "onScanFailed API 21");
}
};
}
Thanks for your help``
I found what was the problem about the location.
In fact, if you work with a API >= 23, you have to authorize you app to access to the location (not only in the Manifest file, but in you code it self).
So if you have the same problem:
First, manualy, go to your phon's setting and autorize your app to access to location: to be sure that was the problem.
Then add the code below so that, The application ask the user to authorize the application to access the location
/////////////////////////Location/////
#TargetApi(Build.VERSION_CODES.M)
private void loadPermissions(String perm,int requestCode) {
if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, perm)) {
ActivityCompat.requestPermissions(this, new String[]{perm},requestCode);
}
} else if (checkLocationEnabled())
initScanner();
}
private boolean checkLocationEnabled(){
LocationManager lm = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
boolean gps_enabled = false;
boolean network_enabled = false;
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch(Exception ex) {}
try {
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch(Exception ex) {}
if(!gps_enabled && !network_enabled) {
// notify user
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setMessage("GPS desabled");
dialog.setPositiveButton("Open GPS settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
//get gps
}
});
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
}
});
dialog.show();
return false;
} else return true;
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// granted
if (checkLocationEnabled())
initScanner();
}
else{
// no granted
}
return;
}
}
}
I had this problem too because I was using ACCESS_COARSE_LOCATION on the permission.
When I changed to ACCESS_FINE_LOCATION, it finally works for me!
Basically, I am an iOS developer. I have a requirement to scan, connect & disconnect BLE devices. Everything works fine in iOS. Then I tried the following code to scan in Android. None of the devices re scanned at anytime. Could anyone help me, if I am doing something wrong.
public class MainActivity extends AppCompatActivity {
BluetoothAdapter bluetoothAdapter;
TextView statusTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
statusTextView = (TextView)findViewById(R.id.statusTxtView);
}
#Override
protected void onStart() {
super.onStart();
enableBluetooth();
}
private void enableBluetooth() {
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
statusTextView.setText("BT disabled");
Intent enableBtIntent =
new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
} else {
statusTextView.setText("BT enabled");
}
boolean status = bluetoothAdapter.startDiscovery();
if (status == true) {
statusTextView.setText("Start scanning");
} else {
statusTextView.setText("Failed scanning");
}
}
BluetoothAdapter.LeScanCallback scanCallback = new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
statusTextView.setText(device.getName());
}
};
}
You've not started scanning. After starting bluetooth discovery using bluetoothAdapter.startDiscovery(), you have to start scanning in order to get scan results. Use the following code to start scan.
I've not tested it but it should work as follows:
BluetoothLeScanner scanner = bluetoothAdapter.getBluetoothLeScanner();
scanner.startScan(scanCallback);
where scanCallback is the above callback you have created but unused.
Make sure that you have BLUETOOTH_ADMIN permission.
First you have to scan device
#SuppressLint("NewApi")
private void turnonBLE() {
// TODO Auto-generated method stub
manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
mBLEAdapter = manager.getAdapter();
mLeScanner = mBLEAdapter.getBluetoothLeScanner();
mBLEAdapter.enable();
scanLeDevice(true);
Toast.makeText(getApplicationContext(), "BTLE ON Service",
Toast.LENGTH_LONG).show();
Log.e("BLE_Scanner", "TurnOnBLE");
}
If you are not using any uuid then scan without uuid
public void scanLeDevice(final boolean enable) {
if (enable) {
if (Build.VERSION.SDK_INT < 21) {
mBLEAdapter.startLeScan(mLeScanCallback);
} else {
ParcelUuid uuid = ParcelUuid.fromString(UUIDList.SENSOR_MAIN_SERVICE_UUID_STRING.toString());
ScanFilter scanFilter = new ScanFilter.Builder().setServiceUuid(uuid).build();
ScanSettings settings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.setReportDelay(0)
.build();
if (mLeScanner != null)
mLeScanner.startScan(Collections.singletonList(scanFilter), settings, mScanCallback);
}
} else {
if (Build.VERSION.SDK_INT < 21) {
mBLEAdapter.stopLeScan(mLeScanCallback);
} else {
mLeScanner.stopScan(mScanCallback);
}
}
}
From that call scanCallback
private ScanCallback mScanCallback = new ScanCallback() {
#Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice btDevice = result.getDevice();
connectToDevice(btDevice, result.getScanRecord().getBytes());
}
#Override
public void onBatchScanResults(List<ScanResult> results) {
for (ScanResult sr : results) {
Log.e("ScanResult - Results", sr.toString());
}
}
#Override
public void onScanFailed(int errorCode) {
Log.e("Scan Failed", "Error Code: " + errorCode);
}
};
for connect device call gattCallback
private synchronized void connectToDevice(BluetoothDevice device, byte[] scanRecord) {
mGatt = device.connectGatt(getApplicationContext(), false, mBtGattCallback);
}
private BluetoothGattCallback mBtGattCallback = new BluetoothGattCallback() {
// override all methods
}
I am having some trouble with BLE communication working on a foreground service.
Although the logic on the service works fine, if the activity is open, every time a Bluetooth device is in range my service does what it has to do. But after I close or suspend the activity, my service only works one time and it seems that it ignores the scan callback and doesn't do anything.
The expected behavior should be that even when the main activity is closed, the service should find and do the associated logic.
public class DeviceControlService extends Service implements BluetoothAdapter.LeScanCallback{
private String TAG = "In Service --> ";
private BluetoothAdapter mBluetoothAdapter; //BluetoothAdapter represents the radio in the Smartphone
private boolean mScanning; //Keep track of whether there is a scan in progress
private static final long SCAN_PERIOD = 100000; //Length of time in milliseconds to scan for BLE devices
private String wantedDevice = "00:1E:C0:29:2A:BE";
private boolean found = false;
InServiceControl deviceControl;
private boolean switchStatus = true;
BluetoothManager bluetoothManager;
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
private States state = IDLE;
private PendingIntent pendingIntent;
private BluetoothAdapter.LeScanCallback mLeScanCallback;
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
DeviceControlService getService() {
// Return this instance of LocalService so clients can call public methods
return DeviceControlService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public void stopThread(){
Log.d(TAG, "thread stoped");
stopScanning();
switchStatus = false;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
Log.d(TAG, "On start");
return START_STICKY;
}
#Override
public void onCreate(){
state = INIT;
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new Notification.Builder(this)
.setContentTitle("MBO")
.setContentText("Bluetooth is running.")
.setSmallIcon(R.drawable.tooth)
.setContentIntent(pendingIntent)
.build();
startForeground(101, notification);
adapterInit();
scanLeDevice();
new Thread(new Runnable() {
#Override
public void run() {
while(switchStatus)
states();
}
}).start();
}
#Override
public void onDestroy() {
deviceControl = null;
bluetoothManager = null;
mBluetoothAdapter = null;
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
public void adapterInit(){
Log.d(TAG, "in adapter init");
bluetoothManager = (android.bluetooth.BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); //Get the BluetoothManager
mBluetoothAdapter = bluetoothManager.getAdapter();
deviceControl = new InServiceControl(mBluetoothAdapter, this);
}
public void states(){
switch(state){
case IDLE:
break;
case INIT:
switchStatus = true;
Log.d(TAG, "init");
if(mBluetoothAdapter == null){
adapterInit();
}
state = PROCESSING;
break;
case PROCESSING:
if(!mScanning){
scanLeDevice();
}else{
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
break;
case DONE:
Log.d(TAG, "done");
state = PROCESSING;
break;
default:
break;
}
}
// ----------------------------------------------------------------------------------------------------------------
// Scan for BLE device for SCAN_PERIOD milliseconds.
// The mLeScanCallback method is called each time a device is found during the scan
private void scanLeDevice() {
Log.d(TAG, "Entered into scanning");
if(!mScanning){
Log.d(TAG, "started Scanning");
mBluetoothAdapter.startLeScan(this);
mScanning = true;
}
}
private void stopScanning(){
Log.d(TAG, "scanning stoped");
if(mScanning) {
mBluetoothAdapter.stopLeScan(this);
mScanning = false;
}
}
public void autoConnect(BluetoothDevice device){
//Stop the scan in progress
deviceControl.init(device.getName(), device.getAddress());
state = DONE;
}
#Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { //Android calls method with Bluetooth device advertising information
if(device.getAddress().equals(wantedDevice)){
stopScanning();
autoConnect(device);
Toast.makeText(getApplicationContext(), "found", Toast.LENGTH_SHORT).show();
}
Log.d(TAG, "Found BLE Device: " + device.getAddress() ); //Debug information to log the devices as they are found
}
Is it possible that android is ignoring the scan callback for some reason that i am missing?
Thanks in advance
I'm new on this and I don't know how I can print on the mobile phone the RSSI that I have scanned before. This is my code, tell me please what I'm making wrong.
I have to send this for a final project and I can't see the Rssi.
public class MainActivity extends AppCompatActivity {
//declare
private BluetoothAdapter mBluetoothAdapter;
private final static int REQUEST_ENABLE_BT = 1;
private BluetoothLeScanner mBluetoothLeScanner;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
//start and stop scan
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
// Checks if Bluetooth LE Scanner is available.
if (mBluetoothLeScanner == null)
{
Toast.makeText(this, "Can Not Find BLE Scanner", Toast.LENGTH_SHORT).show();
finish();
return;
}
}
public class DeviceScanActivity extends ListActivity {
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private android.os.Handler mHandler;
// Stops scanning after 10 seconds (10000).
private static final long SCAN_PERIOD = 1000;
private void scanLeDevice(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable()
{
#Override
public void run()
{
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
mScanning = false;
mBluetoothLeScanner.stopScan((ScanCallback) mLeScanCallback);
}
}, SCAN_PERIOD);
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
mScanning = true;
mBluetoothLeScanner.startScan((ScanCallback) mLeScanCallback);
} else
{
mScanning = false;
mBluetoothLeScanner.stopScan((ScanCallback) mLeScanCallback);
}
}
}
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run()
{
TextView SwitchOff = (TextView) findViewById(R.id.txonoff);
SwitchOff = (TextView) findViewById(R.id.txonoff);
SwitchOff.getText();
SwitchOff.setText("Potència= " + rssi + "dBm\n");
}
});
}
};
};