我正在实现呼叫阻止功能。但是我在调用endCall()方法时遇到异常。
W/System.err: java.lang.SecurityException: Neither user 10083 nor current process has android.permission.CALL_PHONE.
W/System.err: at android.os.Parcel.readException(Parcel.java:2004)
W/System.err: at android.os.Parcel.readException(Parcel.java:1950)
W/System.err: at com.android.internal.telephony.ITelephony$Stub$Proxy.endCall(ITelephony.java:2025)
W/System.err: at veclar.map.callandsmsblocking.PhoneStateReceiver.onReceive(PhoneStateReceiver.java:109)
W/System.err: at android.app.ActivityThread.handleReceiver(ActivityThread.java:3187)
W/System.err: at android.app.ActivityThread.-wrap17(Unknown Source:0)
W/System.err: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1672)
W/System.err: at android.os.Handler.dispatchMessage(Handler.java:106)
W/System.err: at android.os.Looper.loop(Looper.java:164)
W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6494)
W/System.err: at java.lang.reflect.Method.invoke(Native Method)
W/System.err: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
我在清单中放下了权限,并在主活动中也显式调用了该权限,但是我仍然遇到某种权限错误,并且找不到任何解决方案。
AndroidManifest.xml
<?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="veclar.map.callandsmsblocking">
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.Manifest.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.CALL_PRIVILEGED"
tools:ignore="ProtectedPermissions" />
<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/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".PhoneStateReceiver"
android:enabled="true"
android:permission="android.permission.BROADCAST_SMS">
<intent-filter android:priority="9999">
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
</manifest>
PhoneStateReceiver.java
public class PhoneStateReceiver extends BroadcastReceiver {
private String blockingNumber = "xxxxxxxxxxx";
@Override
public void onReceive(final Context context, final Intent intent) {
ITelephony telephonyService;
try {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)){
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Method m = tm.getClass().getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(tm);
if ((number.equals(blockingNumber))) {
telephonyService.endCall();
Toast.makeText(context, "Ending the call from: " + number, Toast.LENGTH_SHORT).show();
Log.i("App Update","call Ended: "+number);
}
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(context, "Ring " + number, Toast.LENGTH_SHORT).show();
Log.i("App Update","Ring "+number);
}
if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_OFFHOOK)){
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Method m = tm.getClass().getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(tm);
Toast.makeText(context, "Answered " + number, Toast.LENGTH_SHORT).show();
Log.i("App Update","Answered "+number);
if ((number.equals(blockingNumber))) {
telephonyService.endCall();
Toast.makeText(context, "Ending the call from: " + number, Toast.LENGTH_SHORT).show();
Log.i("App Update","call Ended: "+number);
}
}
if(state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_IDLE)){
Toast.makeText(context, "Idle "+ number, Toast.LENGTH_SHORT).show();
Log.i("App Update","Idle "+number);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
ITelephony.java
package com.android.internal.telephony;
public interface ITelephony {
boolean endCall();
void answerRingingCall();
void silenceRinger();
}
MainActivity.java
{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
hello = findViewById(R.id.hello);
hello.setText("WE are testing call and sms blocking. have patience");
if (Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_PHONE_STATE)
!= PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, android.Manifest.permission.PROCESS_OUTGOING_CALLS)
!= PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, android.Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
requestPermissions(new String[]{android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.PROCESS_OUTGOING_CALLS,android.Manifest.permission.CALL_PHONE}, 10);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 10: {
try {
if (grantResults[0] == (PackageManager.PERMISSION_GRANTED) && grantResults[1] == (PackageManager.PERMISSION_GRANTED) && grantResults[2] == (PackageManager.PERMISSION_GRANTED)) {
Toast.makeText(this, "PERMISSION GRANTED ", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "PERMISSION NOT GRANTED ", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
}
}
}
}
}