Я разработал приложение для Android с фоновым сервисом, который работает бесконечно и сохраняет в локальной базе данных SqLite результаты сканирования по Bluetooth и GPS-положения. Только на устройствах Huawei этот сервис, кажется, приостановлен или остановлен на несколько минут (я заметил, что после вставки некоторого журнала в код): за эти минуты записывается любой журнал.
, Я безуспешно пытался изменить некоторые настройки устройства (оптимизация батареи).
Есть ли у вас какие-либо советы по решению проблемы?
Ниже вы можете найти фрагмент службы.
public class MyService extends Service {
public MyService() {
super();
}
@Override
public void onCreate() {
super.onCreate();
...
...
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForeground(1031, getNotification());
}
final Intent serviceIntent = new Intent(getApplicationContext(), MyService.class);
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
MyServiceBinder binder = (MyServiceBinder) service;
started = true;
}
@Override
public void onServiceDisconnected(ComponentName arg0) {
started = false;
}
};
bindService(serviceIntent, connection, Context.BIND_AUTO_CREATE);
}
@RequiresApi(Build.VERSION_CODES.O)
private Notification getNotification() {
NotificationChannel channel = new NotificationChannel("channel_01", "My Channel", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
Notification.Builder builder = new Notification.Builder(getApplicationContext(), "channel_01");
builder.setContentTitle(getString(R.string.app_name))
.setAutoCancel(true)
.setColor(getResources().getColor(R.color.colorAccent))
.setContentText(getString(R.string.app_name))
.setSmallIcon(R.drawable.ic_stat_onesignal_default);
return builder.build();
}
public class MyServiceBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
private void stopForegroundService()
{
// Stop foreground service and remove the notification.
stopForeground(true);
// Stop the foreground service.
stopSelf();
}
@Override
public void onDestroy() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
stopForegroundService();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//Restart after 5 secs
Handler h = new Handler(Looper.getMainLooper());
h.postDelayed(new Runnable() {
@Override
public void run() {
GenericUtility.launchService(MyService.class, getApplication());
}
}, 5000);
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
...
...
initScanLoop();
initLocationManager();
return Service.START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new MyServiceBinder();
}
@Override
public boolean onUnbind(Intent intent) {
boolean res = super.onUnbind(intent);
return res;
}
/*Init bluetooth handler*/
private void initScanLoop() {
final Handler h = new Handler(Looper.getMainLooper());
h.post(new Runnable() {
@Override
public void run() {
scanLeDevice();
hBeacon.postDelayed(this, SCAN_DURATION + 10000);
}
});
}
private void scanLeDevice() {
if(mLEScanner != null && !scanning.get() && !stopScan) {
scanning.set(true);
mLEScanner.startScan(null, settings, mScanCallback);
Handler mHandler = new Handler(Looper.getMainLooper());
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
if(scanning.get()) {
stopScanLeDevice();
}
}
}, SCAN_DURATION);
}
}
private void stopScanLeDevice() {
scanning.set(false);
if(mLEScanner != null) {
mLEScanner.stopScan(mScanCallback);
}
}
/*Finish bluetooth handler*/
/*Init GPS handler*/
private void initLocationManager() {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
createLocationChangedCallback();
locationListener = new BeaconScanLocationListener(locationChangedCallback);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
private void createLocationChangedCallback() {
locationChangedCallback = new LocationChangedCallback() {
@Override
public void callback(final Location location) {
try {
//GPS callcback
} catch(Exception e) {
}
}
@Override
public void enabledDisabled(boolean enabled) {
}
};
}
/*Finish GPS handler*/
}
UPDATE
Я улучшил функциональность приложения, заменив сканирование Bluetooth на маяк мониторинга в функции региона библиотеки Android Beacon.