2016-02-18 1 views
4

Я не могу понять, что не так с приведенным ниже кодом. Я также дважды проверил регистрацию получателя. Но это тоже не так. или, может быть, я что-то упускаю. Может ли кто-нибудь помочь. Мне это действительно нужно. :(Android BroadcastReceiver onReceive() вызывается дважды на android 5.1.1 даже после одного регистра

import android.app.Service; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.telephony.TelephonyManager; 
import android.util.Log; 
import android.widget.Toast; 

/** 
* 
* @author Bharat 
* 
*/ 
public class CallNotifierService extends Service 
{ 
    private static final String ACTION_IN = "android.intent.action.PHONE_STATE"; 
    private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL"; 
    private CallBr br_call; 

    @Override 
    public IBinder onBind(Intent arg0) 
    { 
     return null; 
    } 

    @Override 
    public void onDestroy() 
    { 
     Log.d("service", "destroy"); 
     this.unregisterReceiver(this.br_call); 
     super.onDestroy(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     final IntentFilter filter = new IntentFilter(); 
     filter.addAction(ACTION_OUT); 
     filter.addAction(ACTION_IN); 
     this.br_call = new CallBr(); 
     this.registerReceiver(this.br_call, filter); 
     return START_NOT_STICKY; 
    } 

    public class CallBr extends BroadcastReceiver 
    { 
     Bundle bundle; 
     String state; 
     String inCall, outCall; 
     public boolean wasRinging = false; 
     public boolean answered = false; 
     public boolean outgoing = false; 

     @Override 
     public void onReceive(Context context, Intent intent) 
     { 
      if (intent.getAction().equals(ACTION_IN)) 
      { 
       if ((bundle = intent.getExtras()) != null) 
       { 
        state = bundle.getString(TelephonyManager.EXTRA_STATE); 

        if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) 
        { 
         inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER); 
         wasRinging = true; 
         Toast.makeText(context, "Incoming Call : " + inCall, Toast.LENGTH_LONG).show(); 
        } 
        else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) 
        { 
         if (wasRinging == true) 
         { 
          answered = true; 
          Toast.makeText(context, "Answered", Toast.LENGTH_LONG).show(); 
         } 
        } 
        else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) 
        { 
         wasRinging = false; 
         Toast.makeText(context, "Disconnected", Toast.LENGTH_LONG).show(); 
        } 
       } 
      } 
      else if (intent.getAction().equals(ACTION_OUT)) 
      { 
       if ((bundle = intent.getExtras()) != null) 
       { 
        outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); 
        Toast.makeText(context, "Outgoing Call : " + outCall, Toast.LENGTH_LONG).show(); 
        outgoing = true; 
       } 
      } 
     } 
    } 
} 

Ниже деятельность Я зову его от

public class MyActivity extends Activity 
{ 

@Override 
protected void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.roaming); 

    Intent intent = new Intent(this, CallNotifierService.class); 
    startService(intent); 
} 
. 
. 
. 
} 

Manifest

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="ind.cosmos.main" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-permission android:name="android.permission.READ_CALL_LOG" /> 
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> 

    <uses-sdk 
     android:minSdkVersion="22" 
     android:targetSdkVersion="22" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 

     <!-- android:theme="@style/AppTheme"> --> 
     <activity 
      android:name="ind.cosmos.main.MainActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <service android:name="ind.cosmos.callRecord.CallNotifierService" /> 
    </application> 

+0

Для какой из двух действий, как его называют в два раза? – Yashasvi

+0

Возможно, это связано с тем, что система будет отправлять его дважды. Это действительно так, когда вы слушаете трансляции для звонков или контактов. – Arslan

+0

его Toast.makeText (...) два раза каждый раз, когда приходит вызов или я набираю номер – Bharat

ответ

2

На самом деле .. нет ничего плохого с кодом. Его системы который вызывает это. Некоторое время его 2 раза .. в других случаях он касается 4 раза.

Так что лучше всего мы сможем справиться с этим в самом коде.

4

Поскольку Бхарат сказал, что лучше обращаться с ним в коде. Ниже приведена хитрость, найденная here, благодаря Майклу Марвику, который также дал подробное описание.

 public class PhoneStateBroadcastReceiver extends BroadcastReceiver { 

     public static final String TAG = "PHONE STATE"; 
     private static String mLastState; 

     @Override 
     public void onReceive(Context context, Intent intent) { 
      String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); 

      if (!state.equals(mLastState)) { 
       mLastState = state; 
       Log.e(TAG, state); 
      } 
     } 
    } 
+1

Предоставленная ссылка хороша и более подробно объясняет решение. – Abhi

+0

Но что, если состояние Входящие смс, этот код не сработает. – DumpsterDiver

0

У меня такое же поведение, и в вашем коде нет проблемы. android.intent.action.PHONE_STATE можно получить несколько раз, но расслоение Intent является всегда разные, например:

D/App(2001): Bundle{ state => OFFHOOK; subscription => 1; }Bundle 
D/App(2001): Bundle{ incoming_number => 555555555; state => OFFHOOK; subscription => 9223372036854775807; }Bundle 
Смежные вопросы