创建服务以检测用户的任何操作 [英] Create service to detect any action from the user

查看:46
本文介绍了创建服务以检测用户的任何操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个我想检测有关用户的服务,比如说,当用户将设备放在桌子上时,我检测到了该动作,但是我将其放置在了MainActivty上,我希望它放在Service上. 事实是,在我的MainActivity()上有我的registerAction()和我的onResume()上,在onPause()中我从我的sensor中调用了unregisterListener(),还有一个HandlerThread在我的onCreate()上启动它,如何将其更改为Service?有问题吗?我看到没有相同的方法...

I'm trying to create a service where I want to detect something about user, let's say when user lays the device on a table, the thing is that I have that action detected but I have it on a MainActivty and I want it to put on Service. The thing is that on my MainActivity() I had my registerAction() and on my onResume() were called and in onPause() I call the unregisterListener() from my sensor, as well I have a HandlerThread where I start it on my onCreate() how do I change it to Service? Would be a problem? I see that there aren't the same methods...

我已经创建了我的Service,我已经拥有了:

I've created my Service and I've got :

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打电话给我

EDIT

I'm using szamani20 code, but I'm having problems with runOnUiThread because I can not call from my Service also, I'm having this issue

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

java.lang.RuntimeException: Unable to start service com.example.developer.qwe.MyService@d8c613b with null: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Intent.getAction()' on a null object reference

推荐答案

首先,您需要确定是否希望用户知道您正在运行的服务.回顾 Android Oreo中的背景执行限制:

First of all you need to decide whether you want the user to be aware of your running service or not. Take a review on Background Execution Limits in android Oreo:

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

To improve the user experience, Android 8.0 (API level 26) imposes limitations on what apps can do while running in the background.

因此,考虑到您的情况,在许多情况下似乎有很多工作要做,这将是使用前台服务的更好方法.正如 Android文档所说的有关前台服务:

So considering your case where it seems there are lots of work to do in many situations, it would be a better approach to use a foreground service. As android document says about foreground services:

前台服务是用户主动意识到的服务,而不是内存不足时系统被杀死的候选对象.前台服务必须为状态栏提供一个通知,该通知位于正在进行"标题下.这意味着除非停止服务或从前台删除该服务,否则无法取消该通知.

A foreground service is a service that the user is actively aware of and is not a candidate for the system to kill when low on memory. A foreground service must provide a notification for the status bar, which is placed under the Ongoing heading. This means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.

由于您提到已检测到操作,因此我不会在代码中输入该部分.因此,您需要像以前一样创建Service的子类,并使用startService方法来调用它的onCreate.您需要注意的一件事是,第一次在该服务上调用startService时,将调用该服务的onCreate方法,无论您再次调用startService多少次,该onCreate方法都不会被调用,只有onStartCommand被调用.我们结合使用这一事实,即可以在intent中提供字符串操作来正确注册和注销注册侦听器.

Since you mentioned that you have the action detected I won't enter that part of your code. So you need to create a subclass of Service as you did and use the startService method to get it's onCreate called. One thing you need to notice is that the onCreate method of service is called once you call startService on that service for the first time, no matter how many times you call startService again the onCreate method won't get called and only the onStartCommand get called. We use that fact alongside that you could provide a string action within your intent to properly register and unregister your listener.

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中取消注册您的侦听器,以防Android杀死您的服务(这种情况很少见):

Finally don't forget to unregister your listener in onDestroy in case of android kill your service (which is very rare):

@Override
public void onDestroy() {
    super.onDestroy();
    // Unregister your listener
}

这篇关于创建服务以检测用户的任何操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆