Android, TelephonyManager, радости PhoneStateListener и входящих номеров

Я очень недавно получил развитие Android и решил, что мое первое завоевание в этом новом поле будет состоять в том, чтобы понять, как телефон реагировал на входящие вызовы.

Маленький googling позже привел меня к 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 разгорелось по государственным свопам. Слушатель работал, однако в моем журнале или моем тосте не показывалось ни одного номера.

Это было просто пустое место, где должно было быть! Не нуль или что-то еще, нет, но пусто!

После немного большего количества поисковых запросов я понял, что моя проблема 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() для вызова состояний, но я не могу получить номер для показа.

Новая информация:

Я также пробовал это на своем телефоне, не подражая точному такому же результату.

Ответ 1

Вероятно, вам необходимо использовать широковещательный приемник, который может помочь вам в достижении цели. создайте расширенный широковещательный приемник класса и попытайтесь поймать входящий номер.

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>

Ответ 2

Я бы посоветовал вам запустить приложение на настоящем рабочем телефоне!

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

Ответ 3

Я не использовал функцию listen TelephonyManager, но я успешно использовал 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 вы можете найти хорошую реализацию, которая также обрабатывает несколько вызовов: fooobar.com/info/67690/...