如何在Android中通过广播接收器停止一个服务?

6
我有一个 BroadcastReceiver,它接收 Google Cloud Messaging (GCM) 的 JSON,在传递参数时开始类的全局对象服务,该服务每隔一段时间向服务器发送单元格位置,然后在同一 GCM 上向服务器发送另一条消息以停止它。问题是,当我停止服务时,它会说这个服务为空,但仍然发送位置。我想停止服务以停止发送位置。
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {

String TAG = "MainActivity";
ServicioGPS service1;
int nroService;
@Override
public void onReceive(Context context, Intent intent) {
    // == I get the JSON
    Bundle extras= intent.getExtras();
    // == I check if I want to start the service
    if (extras.containsKey("Position")) {
        service1 = new ServiceGPS(context);
        nroService= service1.onStartCommand(intent, 0, 58);
        Log.i(TAG, String.valueOf(nroService));
    }
    else
    {
        // == I check if I want to stop the service
        if (extras.containsKey("stop")) {
            // == Exist error in this line(service1 is NULL)
            service1.stopSelf();
            // == Exist error in this line (service1 is NULL)
        }
        else
        {
            // == I Make a notification
            ComponentName comp = new ComponentName(context.getPackageName(),
                    GcmIntentService.class.getName());              
            Log.i(TAG, "Entro al else del broadcast");
            // Starts the service, keeping the device awake.
            startWakefulService(context, (intent.setComponent(comp)));
            setResultCode(Activity.RESULT_OK);
        }
    }

}

错误列表

错误清单

07-31 19:26:44.115: D/AndroidRuntime(3292): Shutting down VM
07-31 19:26:44.115: W/dalvikvm(3292): threadid=1: thread exiting with uncaught exception             (group=0x41ce0700)
07-31 19:26:44.120: E/AndroidRuntime(3292): FATAL EXCEPTION: main
07-31 19:26:44.120: E/AndroidRuntime(3292): java.lang.RuntimeException: Unable to start  receiver com.ubaldino.demo_gcm.GcmBroadcastReceiver: java.lang.NullPointerException
07-31 19:26:44.120: E/AndroidRuntime(3292):     at android.app.ActivityThread.handleReceiver(ActivityThread.java:2541)
07-31 19:26:44.120: E/AndroidRuntime(3292):     at android.app.ActivityThread.access$1600(ActivityThread.java:159)
07-31 19:26:44.120: E/AndroidRuntime(3292):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1392)
07-31 19:26:44.120: E/AndroidRuntime(3292):     at android.os.Handler.dispatchMessage(Handler.java:99)
07-31 19:26:44.120: E/AndroidRuntime(3292):     at android.os.Looper.loop(Looper.java:176)
07-31 19:26:44.120: E/AndroidRuntime(3292):     at android.app.ActivityThread.main(ActivityThread.java:5419)
07-31 19:26:44.120: E/AndroidRuntime(3292):     at java.lang.reflect.Method.invokeNative(Native Method)
07-31 19:26:44.120: E/AndroidRuntime(3292):     at java.lang.reflect.Method.invoke(Method.java:525)
07-31 19:26:44.120: E/AndroidRuntime(3292):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
07-31 19:26:44.120: E/AndroidRuntime(3292):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
07-31 19:26:44.120: E/AndroidRuntime(3292):     at dalvik.system.NativeStart.main(Native Method)
07-31 19:26:44.120: E/AndroidRuntime(3292): Caused by: java.lang.NullPointerException
07-31 19:26:44.120: E/AndroidRuntime(3292):     at com.ubaldino.demo_gcm.GcmBroadcastReceiver.onReceive(GcmBroadcastReceiver.java:34)
07-31 19:26:44.120: E/AndroidRuntime(3292):     at android.app.ActivityThread.handleReceiver(ActivityThread.java:2525)
07-31 19:26:44.120: E/AndroidRuntime(3292):     ... 10 more
3个回答

8

永远不要直接调用 onDestroy 或任何其他生命周期函数。 要停止服务,请使用context.stopService()

此外,要启动服务,您可以使用context.startService()。 我不确定您想做什么,但这不会真正启动服务,并且如果没有崩溃,将会导致框架出现问题。


谢谢您的输入,我把OnDestroy()放错了位置,也尝试了stopSelf(),但是仍然无法解决服务为空的问题。 - Ubaldino Huaman
1
因为你也没有正确地启动它。你需要通过startService来启动它。你永远不会直接创建服务或活动。 - Gabe Sechan

1
你可以随时访问该服务,因为该服务已在系统中注册(“Thread”),可以随时激活或停止。
示例:
      public class Phonecall extends BroadcastReceiver {

         @Override
             public void onReceive(Context context, Intent intent) {

        Intent song_wweather=  new Intent(context,Song_weather.class); //service class
            if(intent.getAction()=="android.intent.action.PHONE_STATE"){

            TelephonyManager telephonyManager =
    (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

         PhoneStateListener callStateListener = new PhoneStateListener() {
        public void onCallStateChanged(int state, String incomingNumber)
              {
           if(state==TelephonyManager.CALL_STATE_RINGING){
                context.stopService(song_wweather);
           }


               if(state==TelephonyManager.CALL_STATE_IDLE){
        context.startService(song_wweather);
                 }
                 }
             };
      telephonyManager.listen(callStateListener,PhoneStateListener.LISTEN_CALL_STATE);

     }}
       }

0

关于停止服务,@GabeSechan所提到的是正确的。

但从概念上看,你的代码似乎认为在一个onReceive回调到下一个之间,你的ServicioGPS service1实例仍然可用。事实并非如此,这就是为什么你会得到一个"NullPointerException"的原因。重要的是要理解,当BroadcastReceiver的onReceive方法完成时,它就会被销毁。这里有一些关于this的信息,它应该能帮助你理解。

看起来你在这个BroadcastReceiver中处理了两个服务。如果你想使用唤醒锁启动服务,你需要使用context.startService()和context.stopService,正如@GabeSechan所提到的,或者使用startWakefulService。永远不要手动创建或销毁你的服务。

我希望这能使你的理解更加清晰。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接