获取“<app_name> 无法拨打电话尝试使用其他呼叫重定向应用程序或联系开发人员寻求帮助”拨号时

问题描述

我正在构建一个认的来电显示垃圾邮件发送者应用程序,它将检索一个号码的来电详细信息并通过电话拦截详细信息。我使用的是 Android 10.0,不知道此代码如何在其他版本的 Android 上运行。安装应用程序后,我无法拨打任何外拨号码。我收到此错误消息:

Call can't be placed by <appname>. Try using a different call redirecting app or contacting the developer for help.

谁能告诉我如何解决这个问题?

This is the manifest file:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="xxxx.xxxxxxxx.xxxxxxxxxxx">
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.SYstem_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
    <uses-permission android:name="android.permission.READ_CALL_LOG" />
    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" tools:ignore="ProtectedPermissions"/>
    <uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
    <uses-feature
        android:name="android.hardware.telephony"
        android:required="true" />
    <uses-feature
        android:name="android.hardware.microphone"
        android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.GoDial">
        <activity android:name="xxxx.xxxx.xxxx.GetCallerInfoActivity" android:theme="@style/Theme.AppCompat.Transparent.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.DIAL" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.broWSABLE" />
                <data android:scheme="tel" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.DIAL" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <receiver android:name="xxxxxxxx.xxxxxxxx.xxxxxxxx.AnsCallbroadcastReceiver"
            android:permission="android.permission.BIND_SCREENING_SERVICE" >
            <intent-filter>
                <action android:name="android.telecom.CallScreeningService" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PHONE_STATE" />
                <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
            </intent-filter>
        </receiver>
        <service
            android:name="xxxxxxxx.xxxxxxxxx.xxxxxxx.CallMonitorService"
            android:permission="android.permission.BIND_CALL_REDIRECTION_SERVICE"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.telecom.CallRedirectionService"/>
            </intent-filter>
        </service>
    </application>
</manifest>

GetCallerInfoActivity.java

public class GetCallerInfoActivity extends Activity{
    private String number;
    public static int READ_PHONE_STATE=101;
    public static int REQUEST_CALL_LOG=102;
    public static int PERMISSION_DRAW_OVER_OTHER_APP=103;
    private RoleManager roleManager = null;
    private static final String[] PERMS = {Manifest.permission.READ_PHONE_STATE,Manifest.permission.READ_CALL_LOG};
    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        synchronized (this) {         
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(GetCallerInfoActivity.this)) {
                //If the draw over permission is not available open the settings screen to grant the permission.
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent,PERMISSION_DRAW_OVER_OTHER_APP);
            }else
                checkCallStates();
        }
        
        try {
            if (getApplicationContext().checkSelfPermission(Manifest.permission.READ_PHONE_STATE)
                    != PackageManager.PERMISSION_GRANTED) {
                //Permission has not been granted,therefore prompt the user to grant permission
                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_PHONE_STATE,Manifest.permission.READ_CALL_LOG},READ_PHONE_STATE);
            }
        } catch (Exception e) {
            e.printstacktrace();
        }         
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    protected void onActivityResult(int requestCode,int resultCode,Intent data) {
        if (requestCode == PERMISSION_DRAW_OVER_OTHER_APP) {
            //Check if the permission is granted or not.
                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
                        roleManager = (RoleManager) getSystemService(Context.ROLE_SERVICE);
                        Intent intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_REDIRECTION);
                        startActivityForResult(intent,1);
                    }
        } else if (requestCode == 1){
            finish();
        }else
            super.onActivityResult(requestCode,resultCode,data);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode,permissions,grantResults);
        if (requestCode == READ_PHONE_STATE && grantResults.length > 0) {
            if (grantResults[0] != PackageManager.PERMISSION_GRANTED|| grantResults[1] != PackageManager.PERMISSION_GRANTED) {
                if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(getApplicationContext(),"Please grant permission to read contacts",Toast.LENGTH_SHORT).show();
                } else if (grantResults[1] != PackageManager.PERMISSION_GRANTED) {
                    Toast.makeText(getApplicationContext(),"Please grant permission to get your contact number",Toast.LENGTH_SHORT).show();
                }
            }
        }
        if (requestCode==PERMISSION_DRAW_OVER_OTHER_APP&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //If the draw over permission is not available open the settings screen to grant the permission.
            checkCallStates();
        }
    }

    private void checkCallStates(){
        PhoneCallListener phoneListener = new PhoneCallListener();
        TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
        telephonyManager.listen(phoneListener,PhonestateListener.LISTEN_CALL_STATE);
    }

    class PhoneCallListener extends PhonestateListener {
        private boolean isPhoneCalling = false;

        @Override
        public void onCallStateChanged(int state,String incomingNumber) {
            if (TelephonyManager.CALL_STATE_RINGING == state) {
                // phone ringing
                Log.i("LOG_TAG","RINGING,number: " + incomingNumber);
            }

            if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
                // active
                Log.i("LOG_TAG","OFFHOOK");
                isPhoneCalling = true;
            }

            if (TelephonyManager.CALL_STATE_IDLE == state) {
                // run when class initial and phone call ended,need detect flag
                // from CALL_STATE_OFFHOOK
                Log.i("LOG_TAG","IDLE number");

                if (isPhoneCalling) {
                    Handler handler = new Handler();

                    //Put in delay because call log is not updated immediately when state changed
                    // The dialler takes a little bit of time to write to it 500ms seems to be enough
                    handler.postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            // get start of cursor
                            Log.i("CallLogDetailsActivity","Getting Log activity...");
                            String[] projection = new String[]{CallLog.Calls.NUMBER};
                            Cursor cur = getContentResolver().query(CallLog.Calls.CONTENT_URI,projection,null,CallLog.Calls.DATE + " desc");
                            cur.movetoFirst();
                            String lastCallnumber = cur.getString(0);
                        }
                    },500);

                    isPhoneCalling = false;
                }
            }
        }
    }
}

AnsCallbroadcastReceiver.java

public class AnsCallbroadcastReceiver extends broadcastReceiver {
    private boolean isPhoneCalling = false;
    @Override
    public void onReceive(Context arg0,Intent arg1) {
        TelephonyManager telephony = (TelephonyManager)arg0.getSystemService(Context.TELEPHONY_SERVICE);
        telephony.listen(new PhonestateListener(){
            @Override
            public void onCallStateChanged(int state,String incomingNumber) {
                super.onCallStateChanged(state,incomingNumber);
                System.out.println("incomingNumber : "+incomingNumber);

                if (TelephonyManager.CALL_STATE_RINGING == state) {
                    // phone ringing
                    Log.i("LOG_TAG",number: " + incomingNumber);
                    Toast.makeText(arg0,"CALL_STATE_RINGING: "+incomingNumber,Toast.LENGTH_LONG).show();

                    Intent intent = new Intent(arg0,PopUpDialog.class);
                    // To pass any data to next activity
                    intent.putExtra("message",incomingNumber);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    // start your next activity
                    arg0.startActivity(intent);
                }

                if (TelephonyManager.CALL_STATE_OFFHOOK == state) {
                    // active
                    Log.i("LOG_TAG","OFFHOOK");
                    isPhoneCalling = true;
                    Toast.makeText(arg0,"CALL_STATE_OFFHOOK: " +incomingNumber,Toast.LENGTH_LONG).show();
                    Intent intent = new Intent(arg0,incomingNumber);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    // start your next activity
                    arg0.startActivity(intent);
                }

                if (TelephonyManager.CALL_STATE_IDLE == state) {
                    // run when class initial and phone call ended,need detect flag
                    // from CALL_STATE_OFFHOOK
                    Log.i("LOG_TAG","IDLE number");

                    if (isPhoneCalling) {
                        Handler handler = new Handler();

                        //Put in delay because call log is not updated immediately when state changed
                        // The dialler takes a little bit of time to write to it 500ms seems to be enough
                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                // get start of cursor
                                Log.i("CallLogDetailsActivity","Getting Log activity...");
                                String[] projection = new String[]{CallLog.Calls.NUMBER};
                                Cursor cur = arg0.getContentResolver().query(CallLog.Calls.CONTENT_URI,CallLog.Calls.DATE + " desc");
                                cur.movetoFirst();
                                String lastCallnumber = cur.getString(0);
                                Toast.makeText(arg0,"CALL_STATE_OFFHOOK: " +lastCallnumber,Toast.LENGTH_LONG).show();
                            }
                        },500);

                        isPhoneCalling = false;
                    }
                }
            }
        },PhonestateListener.LISTEN_CALL_STATE);
    }
}

CallMonitorService.java

public class CallMonitorService extends CallRedirectionService {
    private static final String TAG = "CallMonitorService";

    public CallMonitorService() {
    }

    @Override
    public void onPlaceCall(Uri uri,PhoneAccountHandle phoneAccountHandle,boolean b) {
        Log.e(TAG,"onPlaceCall:### ");
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...