Android - 当服务收到呼叫且应用程序关闭时应用程序崩溃的原因是什么?

时间:2017-09-11 07:44:07

标签: java android android-service android-broadcastreceiver

我正在创建一个应用程序,当手机接到电话时会发生一些事情,所以经过大量搜索后我发现我可以使用BroadcastReceiverService,所以我创建了一个{{ 1}}调用Service

PhoneStateService

这是启动import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.IBinder; import android.telephony.TelephonyManager; import android.widget.Toast; public class PhoneStateService extends Service { private static BroadcastReceiver broadcastReceiver; @Override public IBinder onBind(Intent arg0) { return null; } @Override public void onCreate() { registerBroadcastReceiver(); } @Override public void onDestroy() { unregisterReceiver(broadcastReceiver); broadcastReceiver = null; } private void registerBroadcastReceiver() { broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE); if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){ new PhoneStateHandler().onIncomingCallStarted(context); } } }; IntentFilter filter = new IntentFilter(TelephonyManager.ACTION_PHONE_STATE_CHANGED); filter.addAction(Intent.ACTION_SCREEN_OFF); registerReceiver(broadcastReceiver, filter); } } PhoneStateService}内部的代码:

MainActivity

部分来自if(PermissionChecker.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PermissionChecker.PERMISSION_GRANTED) { startService(new Intent(getApplicationContext(), PhoneStateService.class)); } 文件:

Manifest

当手机接到电话并且应用程序正在运行时(它仍然没有销毁)一切正常,但在我关闭应用程序并且手机接到电话后,应用程序崩溃并向我发送应用程序已有消息停止工作。

请告诉我有什么问题,我没有找到答案。

编辑:

例外:

<service android:name=".Service.PhoneStateService" />

编辑:

我做了一些人说的话:

09-11 10:26:30.598 29461-29461/? E/AndroidRuntime: FATAL EXCEPTION: main
                                               Process: com.multiplies.multiring, PID: 29461
                                               java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.SCREEN_OFF flg=0x50000010 } in com.multiplies.multiring.Service.PhoneStateService$1@1924f18
                                                   at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:891)
                                                   at android.os.Handler.handleCallback(Handler.java:739)
                                                   at android.os.Handler.dispatchMessage(Handler.java:95)
                                                   at android.os.Looper.loop(Looper.java:148)
                                                   at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                   at java.lang.reflect.Method.invoke(Native Method)
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.os.Bundle.getString(java.lang.String)' on a null object reference
                                                   at com.multiplies.multiring.Service.PhoneStateService$1.onReceive(PhoneStateService.java:36)
                                                   at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:881)
                                                   at android.os.Handler.handleCallback(Handler.java:739) 
                                                   at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                   at android.os.Looper.loop(Looper.java:148) 
                                                   at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                   at java.lang.reflect.Method.invoke(Native Method) 
                                                   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

把这个解决不了问题。 我认为它不起作用,因为如果String stateStr = intent.getExtras() != null ? intent.getExtras().getString(TelephonyManager.EXTRA_STATE) : ""; 返回null,那么intent.getExtras()将无效,因为它返回null并且它需要if statement

TelephonyManager.EXTRA_STATE_RINGING

但是谢谢你的帮助。

巨大的编辑

if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){ new PhoneStateHandler().onIncomingCallStarted(context); } 的一部分:

Manifest

<service android:name=".PhoneState.PhoneStateService" /> <receiver android:name=".PhoneState.PhoneStateBroadcast"> <intent-filter> <action android:name="android.intent.action.PHONE_STATE" /> </intent-filter> </receiver>

PhoneStateBroadcast

import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.telephony.TelephonyManager; import android.util.Log; public class PhoneStateBroadcast extends BroadcastReceiver { Context context; public void onReceive(Context context, Intent intent) { this.context = context; try { TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE); switch (telephonyManager.getCallState()) { case TelephonyManager.CALL_STATE_RINGING: context.startService(new Intent(context, PhoneStateService.class)); break; } } catch (Exception e) { Log.e("Phone Receive Error", " " + e); } } }

PhoneStateService

在编辑之后我仍然会崩溃。

2 个答案:

答案 0 :(得分:2)

由于某种原因,额外的是空的。你正在做intent.getExtras().XXX但是intent.getExtras()返回null,在它上面调用.XXX会抛出错误。

更改

String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);

String stateStr = intent.getExtras() != null ? intent.getExtras().getString(TelephonyManager.EXTRA_STATE) : "";

会阻止崩溃的发生,但你可能想看看为什么你期望额外的原因是什么,但意图中没有。

答案 1 :(得分:2)

而不是运行服务总是把它变成一个BroadcastReciever,每当调用状态改变时就会触发它。(长时间运行服务不是一个好习惯)因此通过使用Broadcast接收器,你的服务会在你想要的时候运行。

public class PhoneStateService extends BroadcastReceiver{

       public void onReceive(Context context, Intent intent) {
            mContext = context;

                try {

                    TelephonyManager tm = (TelephonyManager) context.getSystemService(Service.TELEPHONY_SERVICE);
                    String deviceId=tm.getDeviceId();

                    switch (tm.getCallState()) {

                        case TelephonyManager.CALL_STATE_RINGING:  // incoming call

                     //do something on Incoming call event

                            break;

                        case TelephonyManager.CALL_STATE_IDLE:  //call Ends

                             //do something on Idle phone state i.e set your logic if an incoming call is complete then this block would execute.


                    }


                } catch (Exception e) {
                    Log.e("Phone Receive Error", " " + e);
                }

        }


    }

然后将此broadcastReciever添加到应用程序标记

下的Manifest中
  <receiver android:name="orbitsys.com.prospect_call.CallerState">
                <intent-filter>
                    <action android:name="android.intent.action.PHONE_STATE" />
                </intent-filter>