简体   繁体   English

Android,TelephonyManager,PhoneStateListener和传入号码的乐趣

[英]Android, TelephonyManager, the joys of PhoneStateListener and incoming numbers

I've very newly gotten into Android development, and decided that my first conquest on this fresh field would be to grasp how the phone reacted to incoming calls. 我刚刚进入Android开发阶段,并决定我对这个新领域的首次征服将是掌握手机对来电的反应。

A little googling later led me to http://www.compiletimeerror.com/2013/08/android-call-state-listener-example.html#.Vi3Ren4vfwM (so my code shares a striking resemblance to his/hers). 稍微用谷歌搜索引导我到http://www.compiletimeerror.com/2013/08/android-call-state-listener-example.html#.Vi3Ren4vfwM (所以我的代码与他/她的代码有着惊人的相似之处)。

My main (and only) activity looks like this: 我的主要(也是唯一)活动如下所示:

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;
        }
    }

}
}

Now, here's where the fun stops. 现在,这里的乐趣停止了。 I got the app running on emulator, and used DDMS to spoof a few phone calls to my emulated device to see where the pieces landed. 我让应用程序在模拟器上运行,并使用DDMS欺骗我的模拟设备的几个电话,以查看碎片落在哪里。

And surely enough toast popped up and MyLittleDebugger flared up upon state swaps. 肯定有足够的吐司出现, MyLittleDebugger在州交换中爆发。 The listener was working, however no number was ever being shown in my log or my toast. 听众正在工作,但我的日志或吐司中没有显示任何数字。

It was just blank where the number should have been! 这个数字应该是空白的! Not null or anything, no, but blank! 不是空或任何东西,不,但空白!

After a little more googling, I realized that my AndroidManifest.xml might be the problem. 经过一番谷歌搜索,我意识到我的AndroidManifest.xml可能是问题所在。 It is as follows: 它如下:

<?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>

Now, here's the question: what am I missing? 现在,问题是:我错过了什么?

Clearly, a little fraction of a something has gone wrong somewhere, because I am able to have my TelephonyMgr object .listen() to call states, but I can't get the number to show. 很明显,某个地方的一小部分在某个地方出了问题,因为我可以让我的TelephonyMgr对象.listen()来调用状态,但我无法得到要显示的数字。

New information: 新的信息:

I've also tried this on my phone, without emulating to the exact same result. 我也在手机上试过这个,但没有仿真到完全相同的结果。

You probably need to make use of broadcast receiver which may help you what you trying to achieve. 您可能需要使用广播接收器,它可以帮助您实现您想要实现的目标。 create class extending broadcast receiver and in that try to catch the incoming number. 创建类扩展广播接收器,并尝试捕获传入的数字。

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);
    }

and in your manifest this line as well. 在你的清单中也是这一行。

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

I haven't used the listen function of TelephonyManager , but I did successfully use a BroadcastReceiver for getting the phone state changes and the phone number. 我没有使用TelephonyManagerlisten功能,但我成功使用BroadcastReceiver来获取手机状态更改和电话号码。

Register your receiver in the Activity or in the Manifest (if you want to receive updates when the app is in background): 在活动或清单中注册您的接收者(如果您希望在应用程序处于后台时接收更新):

Activity: 活动:

@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);
 }  

Manifest: 表现:

<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>

and a basic 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);
      }

   }

}

and in this SO answer you can find a nice implementation that also handles multiple calls: https://stackoverflow.com/a/15564021/348378 在这个SO答案中你可以找到一个很好的实现,也可以处理多个调用: https//stackoverflow.com/a/15564021/348378

I would advise you to run your app on a real working phone! 我会建议你在真正的工作电话上运行你的应用程序!

There are multiple reasons why a phone number is not available on all notifications, but you stand a much better chance of there being one if the call is from a real phone network that can provide the number. 所有通知都没有电话号码的原因有很多,但如果电话号码来自可以提供号码的真实电话网络,那么您有更好的机会。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android TelephonyManager和PhoneStateListener - Android TelephonyManager And PhoneStateListener PhoneStateListener onCallStateChanged方法在Android 9.0中将“传入号码”设为空? - PhoneStateListener onCallStateChanged method params “incoming number” empty in Android 9.0? 如何使用TelephonyManager类在android中接收来电? - how to receive an incoming call in android using TelephonyManager class? TelephonyManager.EXTRA_INCOMING_NUMBER 在 Android 9 上始终为 null - TelephonyManager.EXTRA_INCOMING_NUMBER always null on Android 9 Android TelephonyManager - Android TelephonyManager PhoneStateListener返回null作为传入号码 - PhoneStateListener returns null as incoming number 在Android中处理传入号码 - Working with incoming numbers in android 在Android中的TelephonyManager.CALL_STATE_RINGING上将默认传入呼叫屏幕移至背景 - Move the Default Incoming Calling Screen to Background on TelephonyManager.CALL_STATE_RINGING in Android 处理TelephonyManager(处理传入电话,已拨电话,未接电话):在2.3以上的Android版本中是否可能 - Handling TelephonyManager (Handling Incoming calls, Dialed, Missed calls) : Is this possible in Android versions from 2.3 Android服务+ BroadcastReceiver,PhoneStateListener - Android Service + BroadcastReceiver, PhoneStateListener
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM