Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 创建服务以检测用户的任何操作_Java_Android_Service_Android Service_Sensors - Fatal编程技术网

Java 创建服务以检测用户的任何操作

Java 创建服务以检测用户的任何操作,java,android,service,android-service,sensors,Java,Android,Service,Android Service,Sensors,我正在尝试创建一个服务,我想在其中检测用户的某些信息,比如说,当用户将设备放在桌子上时,问题是我检测到了该操作,但我将其放在main活动上,并且我希望它放在服务上。 问题是,在我的MainActivity()上调用了我的registerAction()和我的onResume(),在onPause()中,我从我的传感器中调用了unregisterListener(),还有一个HandlerThread,我在onCreate()上启动它如何将其更改为服务?会有问题吗?我看到有不同的方法 我已经创建了

我正在尝试创建一个服务,我想在其中检测用户的某些信息,比如说,当用户将设备放在桌子上时,问题是我检测到了该操作,但我将其放在
main活动上,并且我希望它放在
服务上。
问题是,在我的
MainActivity()
上调用了我的
registerAction()
和我的
onResume()
,在
onPause()
中,我从我的
传感器中调用了
unregisterListener()
,还有一个
HandlerThread
,我在
onCreate()上启动它
如何将其更改为
服务
?会有问题吗?我看到有不同的方法

我已经创建了我的
服务
,我有:

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");
    }
}
还有我的
main活动
我已经将
实现了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方面遇到了问题,因为我无法从我的
服务中呼叫
,而且,我也遇到了这个问题

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


您可以在OnStartCommand中注册SensorManager inside service。还可以尝试使用startForeground,因为当应用程序被终止时,android操作系统将终止您的服务。首先,您需要决定是否希望用户知道您正在运行的服务。回顾一下:

为了改善用户体验,Android 8.0(API级别26)对应用程序在后台运行时的功能进行了限制

因此,考虑到您的情况,在许多情况下似乎有很多工作要做,使用前台服务将是一种更好的方法。作为:

前台服务是用户主动意识到的服务,当内存不足时,它不是系统要终止的候选服务。前台服务必须为状态栏提供通知,该状态栏位于正在进行的标题下。这意味着,除非服务停止或从前台删除,否则无法取消通知

既然你提到你检测到了这个动作,我就不输入你代码的那部分了。因此,您需要像以前一样创建
Service
的子类,并使用
startService
方法调用它的
onCreate
。您需要注意的一点是,服务的
onCreate
方法在您第一次对该服务调用
startService
时被调用,无论您调用
startService
多少次,
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);
@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);
}
然后在
MyService.java
中:

String action = "start";  // Or to unregister listener "stop"!
final Intent intent = new Intent(this, MyService.class);
intent.setAction(action);
startService(intent);
@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杀死您的服务(这是非常罕见的):


谢谢你的回答,我会尝试一下,但是我应该把代码放在哪里来检测事件呢?我在
onStartCommand
onCreate
中提供了一条评论,我对此进行了解释。您可能需要在
onCreate
中初始化数据,并在
onStartCommand
中注册和取消注册侦听器。我在服务内部的runOnUiThread中遇到问题。。。不是called@Stuart2041请提供更多信息,您在哪一行上到底遇到了什么错误?