我试图创建一个服务,我想要检测用户的某些内容,让我们说当用户将设备放在桌子上时,问题是我检测到了这个动作,但我有它在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()'在空对象引用上
答案 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操作系统将终止您的服务