Create a service to detect any user activity

I'm trying to create a service where I want to find something about the user, say, when the user puts the device on the table, the fact is that I found this action, but I have it on MainActivty and I want him to put on the Service . The thing is, on my MainActivity() I got my registerAction() and on my onResume() was called, and onPause() I call unregisterListener() from my sensor , I also have HandlerThread , where I run it on to my onCreate() , how can I change it to Service ? Would that be a problem? I see that there are not the same methods ...

I created my Service and I have:

 public class MyService extends Service { public MyService() { } @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } @Override public void onCreate() { super.onCreate(); Log.d("CREATE","ONCREATE"); } @Override public void onDestroy() { super.onDestroy(); Log.d("DESTROY","ONDESTROY"); } } 

Also my MainActivity I set implements SensorEventListener .

The skeleton of my class:

  public class MainActivity extends Activity implements SensorEventListener { private HandlerThread mSensorThread; private SensorManager mSensorManager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mSensorThread = new HandlerThread("sensor_thread"); mSensorThread.start(); } private void registerSensorListener() { mSensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_FASTEST, new Handler(mSensorThread.getLooper())); } @Override public void onSensorChanged(SensorEvent event) { //DO stuff if (isLayed()) { runOnUiThread(new Runnable() { @Override public void run() { Log.d("LAY","LAYLAY"); } }); mSensorManager.unregisterListener(this); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } private boolean isLayed() { return stuff; } @Override protected void onResume() { super.onResume(); registerSensorListener(); } @Override protected void onPause() { super.onPause(); mSensorManager.unregisterListener(this); } } 

EDIT

I use szamani20 code, but I have problems with runOnUiThread , because I cannot call from my Service , I also have this problem

java.lang.RuntimeException: cannot start com.example.developer.qwe.MyService@d8c613b service with zero: java.lang.NullPointerException: attempt to call the virtual method 'java.lang.String android.content.Intent. getAction () 'by null object reference

+2
java android service android-service sensor
Oct 26 '17 at 15:46 on
source share
2 answers

First of all, you need to decide whether you want the user to know about your running service or not. Check out Background Execution Limitations in android Oreo :

To improve the user interface, Android 8.0 (API level 26) imposes restrictions on what applications can execute while running in the background.

So, given your case, when there seems to be a lot of work in many situations, it would be better to use the foreground service. As the Android doc says about front-end services :

A foreground service is a service that the user is actively aware of and is not a candidate for that system can kill when it is in memory. The foreground service should provide a notification for the status bar, which is placed under the "Current" heading. This means that the notification cannot be rejected unless the service is stopped or removed from the foreground.

Since you mentioned that you have detected an action, I will not enter this part of your code. Therefore, you need to subclass Service as you did, and use the startService method to call it onCreate . You should notice that the onCreate service onCreate is called as soon as you call startService in this service for the first time, no matter how many times you call startService again, the onCreate method onCreate not be called and only onStartCommand will be called. We use this fact along with the fact that you can provide a string action in your intent to correctly register and unregister your listener.

In MainActivity.java :

 String action = "start"; // Or to unregister listener "stop"! final Intent intent = new Intent(this, MyService.class); intent.setAction(action); startService(intent); 

and then in MyService.java :

 @Override public void onCreate() { super.onCreate(); // Do initialization or whatever here (executed once per service lifecycle) } @Override public int onStartCommand(Intent intent, int flags, int startId) { if (intent.getAction().equals("start")) { // Register your listener or whatever showForegroundNotification(); } if (intent.getAction().equals("stop")) { // Unregister your listener or whatever stopForeground(true); stopSelf(); } return START_STICKY; } private void showForegroundNotification() { Intent myServiceNotificationIntent = new Intent(this, MainActivity.class); myServiceNotificationIntent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent .getActivity(this, MY_SERVICE_REQUEST_CODE, myServiceNotificationIntent, MY_SERVICE_FLAG); Notification notification = new NotificationCompat.Builder(this) .setContentTitle(MY_SERVICE_NOTIFICATION_CONTENT_TITLE) .setTicker(MY_SERVICE_NOTIFICATION_TICKER) .setContentText(MY_SERVICE_NOTIFICATION_CONTENT_TEXT) .setSmallIcon(R.drawable.ic_whatever) .setContentIntent(pendingIntent) .setOngoing(true) .build(); startForeground(MY_SERVICE_NOTIFICATION_ID, notification); } 

Finally, do not forget to unregister your listener in onDestroy if the android killed your service (which is very rare):

 @Override public void onDestroy() { super.onDestroy(); // Unregister your listener } 
+1
Oct 27 '17 at 8:51 on
source share

You can register the SensorManager service inside the OnStartCommand service. Also try using startForeground, as android os will kill your service when the application is killed

0
Oct 26 '17 at 16:07 on
source share



All Articles