在android PIE 9中结束通话后,来电号码为null [英] Incoming number is null after ending the call in android PIE 9

查看:134
本文介绍了在android PIE 9中结束通话后,来电号码为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自几周以来,我一直在研究这个问题.我正在制作一个应用程序,该应用程序可以选择传入的号码,并在通话结束后将其显示在对话框中.在android PIE 9.0以下,一切正常.在android PIE中,该数字始终为null.我已授予所有权限,包括READ_CALL_LOGS,但存在相同的问题.传入号码为空.所以请任何人帮助我...

I have been working on this problem since weeks. I am making an app which picks the incoming number and shows it in a dialog box after the call is ended. Everything is working fine below android PIE 9.0. The number is always null in android PIE. I have given all permissions including READ_CALL_LOGS but same problem. The incoming number is null. So please anyone help me...

这是我的清单文件:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.softixtechnologies.phonemanager">

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PROFILE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<application
    android:allowBackup="true"
    android:icon="@drawable/calllogo"
    android:label="@string/app_name"
    android:persistent="true"
    android:roundIcon="@drawable/calllogo"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:usesCleartextTraffic="true">
    <activity android:name=".activities.CallLogEntryActivity"></activity>
    <activity android:name=".activities.CallLogsActivity" />
    <activity android:name=".activities.IgnoredNumbersActivity" />
    <activity android:name=".activities.IContactsActivity" />
    <activity android:name=".activities.SplashActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".activities.CategoryPhoneActivity" />
    <activity
        android:name=".activities.LogsActivity"
        android:label="@string/title_activity_logs"
        android:theme="@style/AppTheme.NoActionBar" />
    <activity
        android:name=".activities.CategoryActivity"
        android:label="@string/title_activity_category"
        android:theme="@style/AppTheme.NoActionBar" />
    <activity android:name=".MainActivity" />

    <receiver
        android:name=".callhelpers.CallReciever"
        android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.PHONE_STATE" />
        </intent-filter>
    </receiver>

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths" />
    </provider>
</application>

这是我的代码:

    public class PhoneCallReceiver extends BroadcastReceiver {
    private static int lastState = TelephonyManager.CALL_STATE_IDLE;
    private static Date callStartTime;
    private static boolean isIncoming;
    private static String savedNumber;
    public String phoneNr ;
    DatabaseHelper databaseHelper ;

    @Override
    public void onReceive(final Context context, Intent intent) {
        databaseHelper = new DatabaseHelper(context);


    if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
                savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
            } else {
                String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
                String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);

                int state = 0;
                if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                    state = TelephonyManager.CALL_STATE_IDLE;
                } else if (stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
                    state = TelephonyManager.CALL_STATE_OFFHOOK;
                } else if (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                    state = TelephonyManager.CALL_STATE_RINGING;
                }
                onCallStateChanged(context, state, number);
            }
    }

    protected void onIncomingCallStarted(Context ctx, String number, Date start){}

    protected void onOutgoingCallStarted(Context ctx, String number, Date start){}

    protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end){}

    protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end){}

    protected void onMissedCall(final Context ctx, final String number, Date start){}

    public void onCallStateChanged(Context context, int state, String number){
            if (lastState == state) {
                return;
            }
            switch (state) {
                case TelephonyManager.CALL_STATE_RINGING:
                    isIncoming = true;
                    callStartTime = new Date();
                    savedNumber = number;

                    onIncomingCallStarted(context, number, callStartTime);
                    break;

                case TelephonyManager.CALL_STATE_OFFHOOK:
                    if (lastState != TelephonyManager.CALL_STATE_RINGING) {
                        isIncoming = false;
                        callStartTime = new Date();
                        onOutgoingCallStarted(context, savedNumber, callStartTime);
                    }
                    break;

                case TelephonyManager.CALL_STATE_IDLE:

                    if (lastState == TelephonyManager.CALL_STATE_RINGING) {
                            onMissedCall(context, savedNumber, callStartTime);
                    } else if (isIncoming) {

                        onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
                    } else {
                        onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());
                    }
                    break;
            }
            lastState = state;
    }
    public boolean contactExists(Context context, String number) {
        Uri lookupUri = Uri.withAppendedPath(
                ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
                Uri.encode(number));
        String[] mPhoneNumberProjection = { ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.NUMBER, ContactsContract.PhoneLookup.DISPLAY_NAME };
        Cursor cur = context.getContentResolver().query(lookupUri,mPhoneNumberProjection, null, null, null);
        try {
            if (cur.moveToFirst()) {
                return true;
            }
        } finally {
            if (cur != null)
                cur.close();
        }
        return false;
    }
}

非常感谢您的帮助!

推荐答案

电话状态接收器有两种不同的类型",即具有Manifest.permission.READ_CALL_LOG权限的接收器和没有Manifest.permission.READ_CALL_LOG许可的接收器.

There are two different "types" of phone state receivers, receivers that have Manifest.permission.READ_CALL_LOG permission and receivers that don't.

如果接收者没有Manifest.permission.READ_CALL_LOG权限,则将调用所有状态一次,而无需EXTRA_INCOMING_NUMBER额外.

If a receiver doesn't have the Manifest.permission.READ_CALL_LOG permission, it will be called for all state changed once, without the EXTRA_INCOMING_NUMBER extra.

如果接收者确实具有上述权限,就像您的情况一样,则每次状态更改两次都会被调用,一个状态没有EXTRA_INCOMING_NUMBER许可,而另一个状态被调用.

If a receiver does have that above permission, like in your case, it will be called for every state changed twice, one without the EXTRA_INCOMING_NUMBER permission, and another time with it.

由于您拥有以下代码:

if (lastState == state) {
    return;
}

在您的onCallStateChanged方法中,您基本上跳过了第二个调用,因此丢失了EXTRA_INCOMING_NUMBER信息.

in your onCallStateChanged method, you're basically skipping the second call, and thus losing the EXTRA_INCOMING_NUMBER info.

如果您确定拥有READ_CALL_LOG权限,则可以尝试完全不重复重复的接收方呼叫(但是请注意,获取该额外部分的空"值是有区别的,这意味着私有号码是有区别的呼叫,而根本没有得到额外的收益),就像这样:

If you're sure you have the READ_CALL_LOG permission, you can try skipping the duplicated receiver call without that extra completely (however note that there's a difference between getting a "null" value for that extra which means a private number call, and not getting that extra at all), like so:

String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
if (!intent.getExtras().containsKey(TelephonyManager.EXTRA_INCOMING_NUMBER)) {
    Log.i("Call receiver", "skipping intent=" + intent + ", extras=" + intent.getExtras() + " - no number was supplied");
    return;
}
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);

请参阅以下官方文档: https://developer.android.com/reference/android/telephony/TelephonyManager#ACTION_PHONE_STATE_CHANGED

See the official docs at: https://developer.android.com/reference/android/telephony/TelephonyManager#ACTION_PHONE_STATE_CHANGED

这篇关于在android PIE 9中结束通话后,来电号码为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆