我可以在android中以编程方式挂断电话吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23097944/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 06:45:46  来源:igfitidea点击:

Can I hang up a call programmatically in android?

android

提问by HelloCW

I hope to block some crank call, so I need to hang up some call programmatically in android.

我希望阻止一些骚扰电话,所以我需要在android中以编程方式挂断一些电话。

The following fragment is from How to hang up outgoing call in Android?
Does it mean the technique of hang up call will be block at any time in further Android version?
Does it mean I can't write an app to hang up a call?

以下片段来自如何在 Android 中挂断拨出电话?
是不是意味着在以后的Android版本中,挂断电话的技术会随时被屏蔽?
这是否意味着我无法编写挂断电话的应用程序?

The only way to hang up that I've encountered so far, is to do so through Java Reflection. As it is not part of the public API, you should be careful to use it, and not rely upon it. Any change to the internal composition of Android will effectively break your application.

到目前为止,我遇到的唯一挂断方法是通过 Java 反射来挂断。由于它不是公共 API 的一部分,因此您应该小心使用它,而不是依赖它。对 Android 内部组成的任何更改都会有效地破坏您的应用程序。

回答by Kanaiya Katarmal

First, you need to declare this permission in AndroidManifest.xml

首先,您需要在 AndroidManifest.xml

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

Then you setup a BroadcastReceiverservice for android.intent.action.PHONE_STATE(incoming calls) and android.intent.action.NEW_OUTGOING_CALL(outgoing calls) by adding the following to AndroidManifest.xml

然后您通过添加以下内容来BroadcastReceiverandroid.intent.action.PHONE_STATE(来电)和android.intent.action.NEW_OUTGOING_CALL(去电)设置服务AndroidManifest.xml

AndroidManifest.xml

AndroidManifest.xml

<receiver android:name=".PhoneStateReceiver">
    <intent-filter android:priority="0">
        <action android:name="android.intent.action.PHONE_STATE" />
        <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
    </intent-filter>
</receiver>

PhoneStateReceiver.JAVA

电话状态接收器.JAVA

import java.lang.reflect.Method;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.TelephonyManager;
import android.util.Log;

public class PhoneStateReceiver extends BroadcastReceiver {

    public static String TAG="PhoneStateReceiver";
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().equals("android.intent.action.PHONE_STATE")) { 
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            Log.d(TAG,"PhoneStateReceiver**Call State=" + state);

            if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                Log.d(TAG,"PhoneStateReceiver**Idle");
            } else if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { 
                // Incoming call
                String incomingNumber = 
                        intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
                Log.d(TAG,"PhoneStateReceiver**Incoming call " + incomingNumber);

                if (!killCall(context)) { // Using the method defined earlier
                    Log.d(TAG,"PhoneStateReceiver **Unable to kill incoming call");
                }

            } else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
                Log.d(TAG,"PhoneStateReceiver **Offhook");
            }
        } else if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) { 
            // Outgoing call
            String outgoingNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
            Log.d(TAG,"PhoneStateReceiver **Outgoing call " + outgoingNumber);

            setResultData(null); // Kills the outgoing call

        } else {
            Log.d(TAG,"PhoneStateReceiver **unexpected intent.action=" + intent.getAction());
        }
    }

    public boolean killCall(Context context) {
        try {
            // Get the boring old TelephonyManager
            TelephonyManager telephonyManager =
                    (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

            // Get the getITelephony() method
            Class classTelephony = Class.forName(telephonyManager.getClass().getName());
            Method methodGetITelephony = classTelephony.getDeclaredMethod("getITelephony");

            // Ignore that the method is supposed to be private
            methodGetITelephony.setAccessible(true);

            // Invoke getITelephony() to get the ITelephony interface
            Object telephonyInterface = methodGetITelephony.invoke(telephonyManager);

            // Get the endCall method from ITelephony
            Class telephonyInterfaceClass =  
                    Class.forName(telephonyInterface.getClass().getName());
            Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod("endCall");

            // Invoke endCall()
            methodEndCall.invoke(telephonyInterface);

        } catch (Exception ex) { // Many things can go wrong with reflection calls
            Log.d(TAG,"PhoneStateReceiver **" + ex.toString());
            return false;
        }
        return true;
    }

}

MainActivity.JAVA

主Activity.JAVA

import android.Manifest;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

public static final int MY_PERMISSIONS_REQUEST_READ_PHONE_STATE = 101;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (ContextCompat.checkSelfPermission(this,
            Manifest.permission.READ_PHONE_STATE)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.READ_PHONE_STATE)) {

            // Show an explanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.READ_PHONE_STATE},
                    MY_PERMISSIONS_REQUEST_READ_PHONE_STATE);

            // MY_PERMISSIONS_REQUEST_READ_PHONE_STATE is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_PHONE_STATE: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay!

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}
}

回答by Drew

Does it mean the technique of hang up call will be block at any time in further Android version?

Does it mean the technique of hang up call will be block at any time in further Android version?

There's a possibility that Android Team would turn everything upside down for this concrete service. As for me, I think such possibility is pretty negligible.

Android 团队有可能将这项具体服务的一切都颠倒过来。至于我,我觉得这种可能性微乎其微。

Does it mean I can't write an app to hang up a call?

Does it mean I can't write an app to hang up a call?

If the proposed approach works, why not? Just do it, keeping in mind (somewhere in background of your mind, yeah :)) that somewhere in the distant future something could get complicated, and you'll have to look for another dirty hack breaking through the rustless API, which does not allow you to hang a call.

如果提议的方法有效,为什么不呢?就去做吧,记住(在你脑海中的某个地方,是的 :))在遥远的未来某处可能会变得复杂,你将不得不寻找另一个突破无锈 API 的肮脏黑客,它不会允许您挂断电话。

回答by dave

This is completely without testing but couldn't you just turn airplane mode off and on when a call that matches your blacklist appears?

这完全没有测试,但是当出现与您的黑名单匹配的呼叫时,您不能关闭和打开飞行模式吗?

Other than that, this seemed to work in pre kitkat http://androidsourcecode.blogspot.in/2010/10/blocking-incoming-call-android.html

除此之外,这似乎适用于 prekitkat http://androidsourcecode.blogspot.in/2010/10/blocking-incoming-call-android.html

回答by maestrino

If you are in JUnit test then this is how;

如果您在 JUnit 测试中,那么这就是方法;

mInstrumentation = InstrumentationRegistry.getInstrumentation();
mInstrumentation.getUiAutomation().executeShellCommand( "input keyevent " + KeyEvent.KEYCODE_ENDCALL );

It may work also from outside the test but I haven't tried it.

它也可能在测试之外工作,但我还没有尝试过。