0

I wanted to save the sensor data in a text file. But my service can save the data only for few minutes and then stops. I added WakeLock but it does not save the sensor data into the file after few minutes. The activity and service class are-

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;
    }
}
}

I added wakelock into manifest file also. How can I run the service till my need and save the sensor data to file? I am building the app for android watch which support android 4.2.2.

An0mn
  • 27
  • 6

1 Answers1

1

Because of the recent changes android will put to sleep every service after a little while in order to preserve battery. The only way to assure the service will run would be to make it run with some kind of foreground UI. Add the following to your Service.

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);
}

By adding the notification the service will have UI and this will make it with higher priority in front of the OS. Which means that it will be killed only in rare occasions.

loshkin
  • 1,600
  • 2
  • 21
  • 38
  • Thanks for your answer. I tried with your procedure. It works for latest android version. But i am building app for an android watch which support android 4.2.2. I edited my question. – An0mn Feb 21 '18 at 13:47
  • Sensor data does not saved to file in android 4.2.2 – An0mn Feb 21 '18 at 14:24
  • Have you seen how to keep device awake section https://developer.android.com/training/scheduling/wakelock.html – loshkin Feb 21 '18 at 14:52
  • I looked your given link before. As I understand android less than 5 does not support Job scheduler. https://stackoverflow.com/questions/42963494/job-scheduler-vs-background-service – An0mn Feb 21 '18 at 15:35
  • Did you menage to prevent it from sleeping? – loshkin Feb 22 '18 at 15:23
  • I manged it for android version greater than 5. Although I applied the wakelock but I could not manage to prevent sleeping on android 4.2.2. I think its not possible android less than 5 because of job scheduler. – An0mn Feb 23 '18 at 10:40
  • There might not be such problem on 4.2.2 as it has no doze mode. – loshkin Feb 23 '18 at 11:59
  • Do you think is there any solution for prevent sleeping on android 4.2.2? – An0mn Feb 23 '18 at 14:58
  • I am telling you Doze mode is only from android 6 and upwards. https://developer.android.com/training/monitoring-device-state/doze-standby.html – loshkin Feb 23 '18 at 15:07