Android:如何在 Android 5.0+ 至 6.0 上阻止(或断开连接)调用

标签 android

我有一个工作代码可以断开 Android 4.4 (KitKat) 上的调用。 我使用了
中描述的“服务调用电话 5”技术 How to programmatically answer/end a call in Android 4.1?How can incoming calls be answered programmatically in Android 5.0 (Lollipop)?

但该代码无法断开 6.0 上的来电。我有一个在后台持续运行并监控电话号码列表并选择自动断开这些号码的后台服务。

如何以编程方式断开 Nexus5 和 Android 6.0 版的来电

编辑1

完整的代码 fragment 如下

       Executor eS = Executors.newSingleThreadExecutor();
       eS.execute(new Runnable() {
           @Override
           public void run() {               
               Runtime runtime = Runtime.getRuntime();
               try {
                   runtime.exec("service call phone 5 \n");
               } catch (Exception exc) {
                   Log.e("XX", exc.getMessage());
               }
           }
       });

Android.xml 中定义了以下权限

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.PROCESS_INCOMING_CALLS" />
<uses-permission android:name="android.permission.CALL_PHONE" />

EDIT2

我又添加了一个权限

 <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />

检测来电的类从 PhoneStateListener 扩展,我覆盖了该方法

    @Override
    public void onCallStateChanged(int state, String incomingNumber) {

        Log.e("XX","*************IncomingPhoneStateListener........"+state+"   incoming no:"+incomingNumber);             
       Executor eS = Executors.newSingleThreadExecutor();
       eS.execute(new Runnable() {
           @Override
           public void run() {

               Runtime runtime = Runtime.getRuntime();
               try {
                   Log.e("XX", "*DISCONNECTING THE CALL* \n" );
                   runtime.exec("service call phone 5 \n");
               } catch (Exception exc) {
                   Log.e("XX", exc.getMessage());
               }
           }
       });


        }

在 logcat 中,我注意到我正在从上面的代码打印输出语句(因此调用了服务),但我的调用从未断开。我在 marshmallow (nexus 5) 上测试过它。

EDIT3

我的目标是 AndroidManifest.xml 中的 API 19。

<uses-sdk
    android:minSdkVersion="19"
    android:targetSdkVersion="19" />

EDIT4

这是我当前的代码库(现在修改了 sdkversion 以使整个工作正常。我仍然没有取得任何进展(同样的老问题)

构建.gradle

apply plugin: 'com.android.application'

 android {
   compileSdkVersion 23
   buildToolsVersion "23.0.3"

defaultConfig {
    applicationId "com.XX.disconnectcall"
    minSdkVersion 19
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dependencies {
  compile fileTree(dir: 'libs', include: ['*.jar'])
  testCompile 'junit:junit:4.12'
  compile 'com.android.support:appcompat-v7:23.4.0'
 }

主 Activity .java

  public class MainActivity extends AppCompatActivity {

private IncomingPhoneStateListener phoneStateListener;
public static final int PERMISSION_REQUEST_CODE = 1001;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.e("TAG ","onCreate");
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        Log.e("TAG ","VERSION_CODES.M");
       /* if (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.READ_PHONE_STATE)
                != PackageManager.PERMISSION_GRANTED) {

             */
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[]{Manifest.permission.READ_PHONE_STATE,Manifest.permission.MODIFY_PHONE_STATE,Manifest
                            .permission.CALL_PHONE,Manifest.permission.PROCESS_OUTGOING_CALLS},
                    PERMISSION_REQUEST_CODE);

      //  }
    } else {
        phoneStateListener = new IncomingPhoneStateListener();
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

}

@Override
public void onResume() {
    super.onResume();

}

@Override
public void onDestroy() {
    super.onDestroy();
    TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
    telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    Log.e("TAG ","onRequestPermissionsResult");
    boolean permissionBoolean = true;

    if (requestCode == PERMISSION_REQUEST_CODE) {
        for (int i = 0; i < permissions.length; i++) {
            if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                permissionBoolean = false;
            }
        }
        if (permissionBoolean) {
            phoneStateListener = new IncomingPhoneStateListener();

        }
    }
}

IncomingPhoneStateListener

public class IncomingPhoneStateListener extends PhoneStateListener {

int callState;
String callNumber;


public IncomingPhoneStateListener() {
    super();

}


@Override
public void onCallStateChanged(int state, final String incomingNumber) {


    callState = state;
    callNumber = incomingNumber;

    Log.e("TAG", "callState  "+callState);
    Executor eS = Executors.newSingleThreadExecutor();
    eS.execute(new Runnable() {
        @Override
        public void run() {

            Runtime runtime = Runtime.getRuntime();
            try {
                Log.e("TAG", "DISCONNECTING THE CALL From Number "+incomingNumber);
                runtime.exec("service call phone 5 \n");
            } catch (Exception exc) {
                Log.e(" ", exc.getMessage());
            }
        }
    });


}
}

最佳答案

我搜索了文档,发现 MODIFY_PHONE_STATE 仅适用于系统应用程序。 Protected permissions .So atleast for detecting incoming call 你不需要这个。您应该在 list 中添加所有这些权限。

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.PROCESS_INCOMING_CALLS" />
<uses-permission android:name="android.permission.CALL_PHONE"/>

如果您在 Marshmallow 上工作,您也必须在运行时授予这些权限。像这样。把它放在 onCreate

///  granting permission  ////
    if(!checkPermission())
    {
        requestPermission();
    }
 /////////////////////////////

然后在类里面添加这些

    ///////////////////////   permission for marshmallow  ///////////////////

private boolean checkPermission(){
    int result1 = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
    int result3 = ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS);
    int result4 = ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_INCOMING_CALLS);
    int result5   = ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE);

    if (result1 == PackageManager.PERMISSION_GRANTED && result3 == PackageManager.PERMISSION_GRANTED && result4 == PackageManager.PERMISSION_GRANTED
            && result5 == PackageManager.PERMISSION_GRANTED){

        return true;

    } else {

        //Toast.makeText(this,"You don't have permission to use further features",Toast.LENGTH_LONG).show();
        return false;

    }
}

private void requestPermission(){

    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_PHONE_STATE) &&
            ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.PROCESS_OUTGOING_CALLS)  &&
            ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.PROCESS_INCOMING_CALLS) &&
                    ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CALL_PHONE)){

        Toast.makeText(this,"Application needs permission to use your camera, calls, storage and location.",Toast.LENGTH_LONG).show();

    } else {

        ActivityCompat.requestPermissions(this,new String[{Manifest.permission.READ_PHONE_STATE,Manifest.permission.PROCESS_OUTGOING_CALLS,
                Manifest.permission.PROCESS_INCOMING_CALLS, Manifest.permission.CALL_PHONE},1);

    }
}


@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[1] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[2] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[3] == PackageManager.PERMISSION_GRANTED) {

                Toast.makeText(this,"Permission Granted.",Toast.LENGTH_LONG).show();

            } else {

                Toast.makeText(this,"Permission Denied.",Toast.LENGTH_LONG).show();

            }
            break;
    }
}

////////////////////////////////////////////////////////////////////////

关于Android:如何在 Android 5.0+ 至 6.0 上阻止(或断开连接)调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38211762/

相关文章:

android - 如何振动 Android 中的系统默认模式?

java - 通过拦截键盘来编写Android键盘记录器?

javascript - 直接在WebView或MapView中使用Google Maps JavaScript API?优点和缺点?

java - 如何使用 eclipse 在云上进行开发?

java - Android 中是否有用于将 Cookie 格式化为 CookieManager 值的类?

android - 仅向新用户显示屏幕 react 导航 v3

Android:我怎样才能完全中止/删除粘性广播

android - 如何将此文本添加到 Android Studio 中的 xml 文件中?

java - 如何加载原始位图,而不在 Android 上缩放?

android - Chrome 扩展 : Authenticate with backend without user interaction