Фоновая служба идет спать
Я хотел сохранить данные датчика в текстовом файле. Но мой сервис может сохранить данные только на несколько минут, а затем останавливается. Я добавил WakeLock, но он не сохраняет данные датчика в файл через несколько минут. Деятельность и класс обслуживания
MainActivity.Class
public class MainActivity extends AppCompatActivity {
private MyService mBoundService;
boolean mIsBound;
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
mBoundService = ((MyService.LocalBinder)service).getService();
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Fabric.with(this, new Crashlytics());
setContentView(R.layout.activity_main);
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},
10);
bindService(new Intent(this, MyService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
}
MyService.class
public class MyService extends Service implements SensorEventListener{
SensorManager mSensorManager;
Sensor mAccelerometer;
PowerManager.WakeLock cpuWakeLock;
public class LocalBinder extends Binder{
MyService getService(){
return MyService.this;
}
}
private final IBinder mBinder = new LocalBinder();
private void registerListener() {
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
private void unregisterListener() {
mSensorManager.unregisterListener(this);
}
public BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "onReceive("+intent+")");
if (!intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
return;
}
Runnable runnable = new Runnable() {
public void run() {
Log.i(TAG, "Runnable executing.");
unregisterListener();
registerListener();
}
};
new Handler().postDelayed(runnable, 500);
}
};
@Override
public void onCreate() {
super.onCreate();
mSensorManager=(SensorManager)getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
PowerManager pm= (PowerManager) getApplicationContext().getSystemService(getApplicationContext().POWER_SERVICE);
cpuWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
unregisterListener();
registerListener();
registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
registerListener();
cpuWakeLock.acquire();
return Service.START_STICKY;
}
@Override
public void onSensorChanged(SensorEvent sensorEvent) {
String entryAcc = System.currentTimeMillis() + ", " + sensorEvent.values[0] + "," + sensorEvent.values[1] + ", " + sensorEvent.values[2] + "\n";
Log.e("String", "value" + entryAcc);
String dataPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyWear_Data/";
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm");
Date now = new Date();
String fileName = "acc_" + formatter.format(now) + ".txt";
writeToPath(fileName, entryAcc, dataPath);
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
private String writeToPath(String fileName, String data, String path) {
FileOutputStream fos = null;
try {
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
File myFile = new File(dir, fileName);
fos = new FileOutputStream(myFile, true);
fos.write(data.getBytes());
fos.close();
Log.e("WriteToFile", "filename : " + fileName);
return myFile.getPath();
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
Я также добавил wakelock в файл манифеста. Как я могу запустить сервис до моей потребности и сохранить данные датчика в файл? Я строю приложение для Android часы, которые поддерживают Android 4.2.2.
1 ответ
Из-за недавних изменений андроид через некоторое время уложит каждую службу в спячку, чтобы сохранить заряд батареи. Единственный способ убедиться, что служба будет работать, - это запустить ее с каким-либо интерфейсом переднего плана. Добавьте следующее к вашему Сервису.
public static final int NOTIFICATION_ID = 1337;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
runAsForeground();
return START_NOT_STICKY;
}
private void runAsForeground() {
Intent notificationIntent = new Intent(this, MyService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0,
notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setOngoing(true)
.setSmallIcon(R.drawable.your_icon_here)
.setContentTitle("Service title here")
.setColor(ContextCompat.getColor(this, R.color.white))
.setContentIntent(pendingIntent)
.build();
startForeground(NOTIFICATION_ID, notification);
}
При добавлении уведомления сервис будет иметь пользовательский интерфейс, и это сделает его с более высоким приоритетом перед ОС. Это означает, что он будет убит только в редких случаях.