2015-10-26 24 views
12

我已經非常新進入Android開發,並決定我在這個新領域的第一次征服將是掌握電話如何響應來電。Android,TelephonyManager,PhoneStateListener和來電號碼的樂趣

稍後使用Google進行搜索導致我登錄到http://www.compiletimeerror.com/2013/08/android-call-state-listener-example.html#.Vi3Ren4vfwM(所以我的代碼與他/她有着驚人的相似之處)。

我的主要(唯一的)活動是這樣的:

import android.app.Activity; 
import android.content.Context; 
import android.os.Bundle; 
import android.telephony.PhoneStateListener; 
import android.telephony.TelephonyManager; 
import android.util.Log; 
import android.view.Menu; 
import android.widget.Toast; 

public class MainActivity extends Activity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    TelephonyManager TelephonyMgr = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 
    TelephonyMgr.listen(new TeleListener(), 
      PhoneStateListener.LISTEN_CALL_STATE); 
} 
@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.activity_main, menu); 
    return true; 
} 
class TeleListener extends PhoneStateListener { 
    public void onCallStateChanged(int state, String incomingNumber) { 
     super.onCallStateChanged(state, incomingNumber); 
     switch (state) { 
      case TelephonyManager.CALL_STATE_IDLE: 
       // CALL_STATE_IDLE; 
       Log.d("MyLittleDebugger", "I'm in " + state + " and the number is " + incomingNumber); 
       Toast.makeText(getApplicationContext(), "CALL_STATE_IDLE", 
         Toast.LENGTH_LONG).show(); 
       break; 
      case TelephonyManager.CALL_STATE_OFFHOOK: 
       // CALL_STATE_OFFHOOK; 
       Log.d("MyLittleDebugger", "I'm in " + state + " and the number is " + incomingNumber); 
       Toast.makeText(getApplicationContext(), "CALL_STATE_OFFHOOK", 
         Toast.LENGTH_LONG).show(); 
       break; 
      case TelephonyManager.CALL_STATE_RINGING: 
       // CALL_STATE_RINGING 
       Log.d("MyLittleDebugger", "I'm in " + state + " and the number is " + incomingNumber); 
       Toast.makeText(getApplicationContext(), incomingNumber, 
         Toast.LENGTH_LONG).show(); 
       Toast.makeText(getApplicationContext(), "CALL_STATE_RINGING", 
         Toast.LENGTH_LONG).show(); 
       break; 
      default: 
       break; 
     } 
    } 

} 
} 

現在,這裏的樂趣停在那裏。我的應用程序在仿真器上運行,並使用DDMS欺騙幾個電話到我的仿真設備,以查看碎片落在哪裏。

當然,足夠的敬酒彈出和MyLittleDebugger爆發了國家掉期。聽衆正在工作,但是我的日誌或烤麪包上沒有顯示任何號碼。

這只是空白的數字應該是!不爲空或任何東西,不,但是空白!

經過多一點Google搜索,我意識到我的AndroidManifest.xml可能是問題所在。這是因爲如下:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.example.x.xy" > 

<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme" > 
    <activity android:name=".MainActivity" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

現在,這裏的問題:我缺少什麼?

顯然,某個東西的一小部分在某處出錯了,因爲我可以讓我的TelephonyMgr對象.listen()調用狀態,但我無法獲取要顯示的數字。

新的信息:

我也試着這樣我的手機上,而不會仿效完全相同的結果。

+0

我跑你的代碼,它爲我工作。 #出現使用ddm僞造的電話。 – JJF

+0

另外我的應用程序甚至不會運行,如果我沒有給它READ_PHONE_STATE權限。這聽起來不同於你所看到的。你嘗試過哪些版本的Android? – JJF

+0

我有完全相同的問題,但廣播接收器不適合我。 – Mainak

回答

4

您可能需要使用廣播接收器,它可以幫助您嘗試實現。 創建類擴展廣播接收器,並嘗試捕獲來電號碼。

public class MyReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(final Context context, Intent intent) { 
     TelephonyManager mtelephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
     mtelephony.listen(new PhoneStateListener(){ 
      @Override 
      public void onCallStateChanged(int state, String incomingNumber) { 
       super.onCallStateChanged(state, incomingNumber); 
       switch (state) { 
       case TelephonyManager.CALL_STATE_RINGING: 
       // CALL_STATE_RINGING 
       Log.d("MyLittleDebugger", "I'm in " + state + " and the number is " + incomingNumber); 
      Toast.makeText(getApplicationContext(), incomingNumber, 
        Toast.LENGTH_LONG).show(); 
      Toast.makeText(getApplicationContext(), "CALL_STATE_RINGING", 
        Toast.LENGTH_LONG).show(); 
      break; 
     default: 
      break; 
       } 
      } 
     },PhoneStateListener.LISTEN_CALL_STATE); 
    } 

並且在您的清單中也包含這一行。

 <receiver android:name=".MyReceiver" > 
      <intent-filter> 
       <action android:name="android.intent.action.PHONE_STATE" /> 
      </intent-filter> 
     </receiver> 
+1

非常好的答案! +1和賞金去找你!謝謝! – ViRALiC

+0

通過這樣做,我的問題沒有解決。它仍然有時候來電號碼是空白的。 – Naved

3

我會建議你在真實的工作電話上運行你的應用程序!

電話號碼在所有通知中都不可用的原因有很多,但如果電話來自可提供號碼的真實電話網絡,則存在更好的機會。

+0

最初發布問題後,我確實嘗試過。這不是錯誤。我會給你一個好的建議+1,這可能是錯誤,但它不是在這種情況下。 – ViRALiC

2

我沒有使用過的TelephonyManagerlisten功能,但我沒有成功使用一個BroadcastReceiver用於獲取手機狀態變化和電話號碼。

填寫您的接收器在活動或在清單(如果你想收到更新時,應用程序在後臺):

活動:

@Override 
protected void onResume() { 
    super.onResume(); 
    BroadcastReceiver receiver = new PhoneStateBroadcastReceiver(); 
    IntentFilter filter= new IntentFilter(); 
    filter.addAction("android.intent.action.PHONE_STATE"); 
    filter.addAction("android.intent.action.NEW_OUTGOING_CALL"); 
    registerReceiver(reciever, filter); 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    unregisterReceiver(reciever); 
} 

清單:

<receiver 
    android:name=".PhoneStateBroadcastReceiver" 
    android:permission="android.permission.READ_PHONE_STATE" > 
    <intent-filter> 
     <action android:name="android.intent.action.PHONE_STATE" /> 
     <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> 
    </intent-filter> 
</receiver> 

和一個基本的接收器:

public class PhoneStateBroadcastReceiver extends BroadcastReceiver { 
    private final String TAG = getClass().getName(); 
    private static String number = null; 

    @Override 
    public void onReceive(final Context context, final Intent intent) { 
     if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { 
     String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); 
     Log.d(TAG, intent.getAction() + ", EXTRA_STATE: " + state); 
     // on ringing get incoming number 
     if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { 
      number = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); 
      Log.d(TAG, "EXTRA_INCOMING_NUMBER: " + number); 

     } 
     } 

     if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) { 
     number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); 
     Log.d(TAG, intent.getAction() + ", EXTRA_PHONE_NUMBER: " + number); 
     } 

    } 

} 

在這個SO回答你可以找到一個很好的實現,也可以處理多個調用: https://stackoverflow.com/a/15564021/348378

+1

謝謝你,這是一個很好的解釋,但是我用了danwcode的回答。 +1! – ViRALiC

+1

不客氣,他在我之前回答了,但我覺得需要更多一點。您應該注意到,PHONE_STATE本身不會爲您提供外出電話號碼,因此您還需要註冊NEW_OUTGOING_CALL。此外,清單解決方案還會讓您的應用程序在您的應用程序不在前臺時收到事件。 – Raanan