从 BroadcastReceiver phoneListener 启动服务

Start Service from BroadcastReceiver phoneListener

我想在 phone 响铃时停止 运行 服务,我想在接听电话时或刚刚响铃后重新启动服务。

如果 phone 通话结束,我总是会收到 java.lang.NullPointerException。 在 CALL_STATE_RINGING 中,alarmManager 取消并且服务停止,没有任何错误。再次启动服务,不起作用。我一直在关注 NullPointerException。

03-18 19:08:30.280  15795-15795/de.app.test E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: de.app.test, PID: 15795
    java.lang.RuntimeException: Unable to start service de.app.AppService@430fad88 with Intent { flg=0x4 cmp=de.ring.volume/de.ring.AppService (has extras) }: java.lang.NullPointerException
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2767)
            at android.app.ActivityThread.access00(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1343)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:212)
            at android.app.ActivityThread.main(ActivityThread.java:5137)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:718)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at de.app.AppService.play(AppService.java:724)
            at de.app.AppService.onStartCommand(AppService.java:159)
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2750)
            at android.app.ActivityThread.access00(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1343)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:212)
            at android.app.ActivityThread.main(ActivityThread.java:5137)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:718)
            at dalvik.system.NativeStart.main(Native Method)
03-18 19:08:34.970  15795-15795/de.app.test I/Process﹕ Sending signal. PID: 15795 SIG: 9
03-18 19:08:44.560  16362-16362/de.app.test I/dalvikvm﹕ Enabling JNI app bug workarounds for target SDK version 8...
03-18 19:08:44.620  16362-16362/de.app.test D/AppService﹕ SavePreferencesInt: 0
03-18 19:08:44.620  16362-16362/de.app.test D/AppService﹕ SavePreferencesInt: 0
03-18 19:08:44.630  16362-16362/de.app.test D/AppService﹕ SavePreferencesInt: 0
03-18 19:08:44.630  16362-16362/de.app.test D/AppService﹕ LoadPreferences: 2
03-18 19:08:44.630  16362-16362/de.app.test I/de.app.AppService﹕ play() Method
03-18 19:08:44.630  16362-16362/de.app.test D/AndroidRuntime﹕ Shutting down VM
03-18 19:08:44.630  16362-16362/de.app.test W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x41685d88)
03-18 19:08:44.640  16362-16362/de.app.test E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: de.app.test, PID: 16362
    java.lang.RuntimeException: Unable to start service de.app.AppService@42ef56f0 with Intent { flg=0x4 cmp=de.app.test/de.app.AppService (has extras) }: java.lang.NullPointerException
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2767)
            at android.app.ActivityThread.access00(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1343)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:212)
            at android.app.ActivityThread.main(ActivityThread.java:5137)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:718)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at de.app.AppService.play(AppService.java:724)
            at de.app.AppService.onStartCommand(AppService.java:159)
            at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2750)
            at android.app.ActivityThread.access00(ActivityThread.java:144)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1343)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:212)
            at android.app.ActivityThread.main(ActivityThread.java:5137)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:515)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:902)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:718)
            at dalvik.system.NativeStart.main(Native Method)

代码:

public class IncomingCall extends BroadcastReceiver {
    TelephonyManager telephony;
    static MyPhoneStateListener phoneListener;
    public static Boolean phoneRinging = false;
    static String phoneNumber;


    public void onReceive(Context context, Intent intent) {

        MyPhoneStateListener phoneListener = new MyPhoneStateListener(context);
        telephony = (TelephonyManager) context
                .getSystemService(Context.TELEPHONY_SERVICE);
        telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    public class MyPhoneStateListener extends PhoneStateListener {


        private Context context;
        MyPhoneStateListener(Context c) {
            super();
            context = c;
        }


        public void onCallStateChanged(int state, String incomingNumber) {

            phoneNumber = incomingNumber;
            AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
            Intent i = new Intent(context, AppService.class);
            PendingIntent pi = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);


            switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    Log.d("DEBUG", "IDLE" + incomingNumber);
                    //phoneRinging = false;
                    startAppService(context);
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    Log.d("DEBUG", "OFFHOOK" + incomingNumber);
                    //phoneRinging = false;
                    startAppService(context);
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    Log.d("DEBUG", "RINGING" + incomingNumber);
                    phoneRinging = true;

                    alarmManager.cancel(pi);
                    context.stopService(new Intent(context, AppService.class));

                        break;
                    }
            }
        }



        public void onDestroy() {
            telephony.listen(phoneListener, PhoneStateListener.LISTEN_NONE);
        }


    public void startAppService(Context c){

        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(c);
        Intent i = new Intent(c, AppService.class);
        PendingIntent pi = PendingIntent.getService(c, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
byte[] time_night = new byte[]{22, 0, 6, 0};
        boolean tB_Mo_i = sharedPreferences.getBoolean("TB_MO", true);
        boolean tB_Di_i = sharedPreferences.getBoolean("TB_DI", true);
        boolean tB_Mi_i = sharedPreferences.getBoolean("TB_MI", true);
        boolean tB_Do_i = sharedPreferences.getBoolean("TB_DO", true);
        boolean tB_Fr_i = sharedPreferences.getBoolean("TB_FR", false);
        boolean tB_Sa_i = sharedPreferences.getBoolean("TB_SA", false);
        boolean tB_So_i = sharedPreferences.getBoolean("TB_SO", true);
        time_night[0] = (byte) sharedPreferences.getInt("TIME_NIG_H_FROM", 0);
    time_night[1] = (byte) sharedPreferences.getInt("TIME_NIG_MIN_FROM", 0);
    time_night[2] = (byte) sharedPreferences.getInt("TIME_NIG_H_TO", 0);
    time_night[3] = (byte) sharedPreferences.getInt("TIME_NIG_MIN_TO", 0);
            i.putExtra(AppService.CHKBOX_ACT_CAL, sharedPreferences.getBoolean("RB_ACT_CAL", true));
            i.putExtra(AppService.CHKBOX_ACT_LOUD, sharedPreferences.getBoolean("RB_ACT_MIN", false));
            i.putExtra(AppService.CHKBOX_ACT_NIGHT, sharedPreferences.getBoolean("CB_ACT_NIGHT", false));
            i.putExtra(AppService.TIME, sharedPreferences.getInt("TIME_NEXT", 0));
            i.putExtra(AppService.TIME_NOW, sharedPreferences.getLong("TIME_NOW_SAVE", 0));
        i.putExtra(AppService.TEXT, sharedPreferences.getString("TEXT", "")); 
i.putExtra(AppService.TIME_NIGHT, time_night);

            int update_time = 15;
            try {
                update_time = Integer.valueOf(sharedPreferences.getString("pref_settings_update_time", "15"));
            } catch (Exception e) {

            }

            alarmManager.cancel(pi);
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * update_time, pi);


    }

    }

服务:

  public int onStartCommand(Intent intent, int flags, int startId) {


    set_calendar = intent.getBooleanExtra(CHKBOX_ACT_CAL, true);
    set_Loud_sil = intent.getBooleanExtra(CHKBOX_ACT_LOUD, true);
    set_night_mode = intent.getBooleanExtra(CHKBOX_ACT_NIGHT, true);
    time_loud = intent.getIntExtra(TIME, 0);
    displ_text=intent.getStringExtra(TEXT);

    play(displ_text); 
    run();

    return(START_REDELIVER_INTENT);
  }

private void play(String text) {
    if (!isPlaying) {
        if(D) Log.i(getClass().getName(), "play() Method");
      isPlaying=true;
        int time_from_min = time_night[0] * 60 + time_night[1];
int time_to_min = time_night[2] * 60 + time_night[3];


  note=new Notification(R.drawable.app_status,
          text, System.currentTimeMillis());

      i=new Intent(this, Activity.class);

      i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                 Intent.FLAG_ACTIVITY_SINGLE_TOP);

      pi=PendingIntent.getActivity(this, 0, i, 0);

      note.setLatestEventInfo(this, getString(R.string.app_name),text,pi);
      note.flags|=Notification.FLAG_NO_CLEAR;

      if(show_notification)startForeground(1505, note);

    }
  }

编辑:

如果我将 onCallStateChanged 更改为以下,它可以启动服务。那么如何停止服务和alarmManager???

    public void onCallStateChanged(int state, String incomingNumber) {

/*        Intent i=new Intent(context, AppService.class);
        PendingIntent pi = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
        AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);*/

        switch (state) {
            case TelephonyManager.CALL_STATE_IDLE:
                Log.d("DEBUG", "IDLE" + incomingNumber);
                //phoneRinging = false;
                if(!isServiceRunning(context)) {
                    startAppService(context);
                }
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                Log.d("DEBUG", "OFFHOOK" + incomingNumber);
                //phoneRinging = false;
                if(!isServiceRunning(context)) {

                }
                break;
            case TelephonyManager.CALL_STATE_RINGING:
                Log.d("DEBUG", "RINGING" + incomingNumber);
                phoneRinging = true;

              //  alarmManager.cancel(pi);
              //  context.stopService(new Intent(context, AppService.class));

                break;
        }
    }

解决方案:

public void startAppService(Context c, boolean stop){

        SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(c);
        Intent i = new Intent(c, AppService.class);

        AlarmManager alarmManager = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
        byte[] time_night = new byte[]{22, 0, 6, 0};
        boolean tB_Mo_i = sharedPreferences.getBoolean("TB_MO", true);
        boolean tB_Di_i = sharedPreferences.getBoolean("TB_DI", true);
        boolean tB_Mi_i = sharedPreferences.getBoolean("TB_MI", true);
        boolean tB_Do_i = sharedPreferences.getBoolean("TB_DO", true);
        boolean tB_Fr_i = sharedPreferences.getBoolean("TB_FR", false);
        boolean tB_Sa_i = sharedPreferences.getBoolean("TB_SA", false);
        boolean tB_So_i = sharedPreferences.getBoolean("TB_SO", true);
        time_night[0] = (byte) sharedPreferences.getInt("TIME_NIG_H_FROM", 0);
        time_night[1] = (byte) sharedPreferences.getInt("TIME_NIG_MIN_FROM", 0);
        time_night[2] = (byte) sharedPreferences.getInt("TIME_NIG_H_TO", 0);
        time_night[3] = (byte) sharedPreferences.getInt("TIME_NIG_MIN_TO", 0);

    if (stop){
        PendingIntent pi = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
        alarmManager.cancel(pi);
        context.stopService(new Intent(context, AppService.class));

    }else {
            i.putExtra(AppService.CHKBOX_ACT_CAL, sharedPreferences.getBoolean("RB_ACT_CAL", true));
            i.putExtra(AppService.CHKBOX_ACT_LOUD, sharedPreferences.getBoolean("RB_ACT_MIN", false));
            i.putExtra(AppService.CHKBOX_ACT_NIGHT, sharedPreferences.getBoolean("CB_ACT_NIGHT", false));
            i.putExtra(AppService.TIME, sharedPreferences.getInt("TIME_NEXT", 0));
            i.putExtra(AppService.TIME_NOW, sharedPreferences.getLong("TIME_NOW_SAVE", 0));
            i.putExtra(AppService.TEXT, sharedPreferences.getString("TEXT", "")); 
            i.putExtra(AppService.TIME_NIGHT, time_night);

            PendingIntent pi = PendingIntent.getService(c, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);

            int update_time = 15;
            try {
                update_time = Integer.valueOf(sharedPreferences.getString("pref_settings_update_time", "15"));
            } catch (Exception e) {

            }

            alarmManager.cancel(pi);
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * update_time, pi);

         }
    }