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

时间:2015-10-26 07:35:56

标签: android telephonymanager phone-state-listener

我刚刚进入Android开发阶段,并决定我对这个新领域的首次征服将是掌握手机对来电的反应。

稍后有点谷歌搜索引导我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()来调用状态,但我无法显示该数字

新信息:

我也在手机上试过这个,但没有模仿完全相同的结果。

3 个答案:

答案 0 :(得分: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 :(得分:4)

我还没有使用listen的{​​{1}}功能,但我确实成功使用了BroadcastReceiver来获取手机状态更改和电话号码。

在活动或清单中注册您的接收者(如果您希望在应用程序处于后台时接收更新):

的活动:

TelephonyManager

清单:

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

在这个SO答案中你可以找到一个很好的实现,它也可以处理多个调用: https://stackoverflow.com/a/15564021/348378

答案 2 :(得分:3)

我建议你在真正的工作电话上运行你的应用程序!

有多种原因导致所有通知都没有电话号码,但如果来自可以提供该号码的真实电话网络,您可能会有更好的机会。