创建服务以检测用户

时间:2017-10-26 15:46:24

标签: java android service android-service sensor

我试图创建一个服务,我想要检测用户的某些内容,让我们说当用户将设备放在桌子上时,问题是我检测到了这个动作,但我有它在MainActivty上,我希望它放在Service上。 问题是在我的MainActivity()我的registerAction()和我的onResume()被调用了onPause()我从unregisterListener()拨打了sensor我还有一个HandlerThread,我在onCreate()上启动它,如何将其更改为Service?会有问题吗?我发现没有相同的方法......

我已经创建了我的Service并且我已经:

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

我的MainActivity我也放了implements SensorEventListener

我班的骨架是:

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

修改

我正在使用szamani20代码,但我遇到了runOnUiThread的问题,因为我也无法从我的Service拨打电话,我有这个问题

  

java.lang.RuntimeException:无法使用null启动服务com.example.developer.qwe.MyService@d8c613b:java.lang.NullPointerException:尝试调用虚方法' java.lang.String android.content .Intent.getAction()'在空对象引用上

2 个答案:

答案 0 :(得分:1)

首先,您需要决定是否希望用户了解您正在运行的服务。对Background Execution Limits in android Oreo进行审核:

  

为了改善用户体验,Android 8.0(API级别26)对应用程序在后台运行时可以执行的操作施加了限制。

因此,考虑到您的情况,在许多情况下似乎有很多工作要做,这将是使用前台服务的更好方法。正如android document says about foreground services

  

前台服务是用户主动了解的服务,并且在内存不足时不是系统要杀死的候选服务。前台服务必须为状态栏提供通知,该通知位于“正在进行”标题下。这意味着除非停止服务或从前台删除服务,否则无法解除通知。

由于您提到您已检测到操作,因此我不会输入您的代码部分。因此,您需要像您一样创建Service的子类,并使用startService方法调用它onCreate。您需要注意的一件事是,一旦您第一次在该服务上调用onCreate,就会调用startService服务方法,无论您再次调用startService多少次{ {1}}方法不会被调用,只会调用onCreate。我们使用这一事实,您可以在onStartCommand内提供字符串操作,以正确注册和取消注册您的听众。

intent

MainActivity.java

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

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); } 中取消注册你的监听器以防万一杀死你的服务(这是非常罕见的):

onDestroy

答案 1 :(得分:0)

您可以在OnStartCommand中注册SensorManager内部服务。也可以尝试使用startForeground,因为当操作系统被杀时,android操作系统将终止您的服务