问题描述
我已阅读有关使用服务执行此操作的信息。但是,当服务被执行,然后我在手机上运行另一个应用程序时,BLE 扫描回调停止执行,但服务仍然正常运行。
我知道 BLE 回调停止是因为日志猫停止生成日志数据,直到我再次打开应用程序。
以下是我的主要活动:
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);
}
});
}
}
下面是示例服务:
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;
}
}
编辑 1:
String[] peripheralAddresses = new String[]{"EE:7E:DE:9B:65:46"};
@Override
public int onStartCommand(Intent intent,"onStartCommand");
Intent notificationIntent = new Intent(this,MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,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;
}
解决方法
首先,我建议您添加扫描过滤器,因为如果您没有扫描过滤器,Android 会在一段时间后停止扫描。
其次,您的服务不会长久存在,因为如果您设备的 Android 版本高于或等于 Android Oreo (Android 8),Android 会杀死它。
因此,我建议您阅读this article 以找到更好的解决方案。
希望能帮到你!