web-dev-qa-db-ja.com

プログラムで着信を終了する方法Android 8.0 Oreo

最大Android 7.1 ITelephony.endCall()メソッドを使用してアプリに権限を付与することで、着信を終了することができました_Android.permission.CALL_PHONE_および_Android.permission.READ_PHONE_STATE_

Android 8.0 Oreo (API 26)で同じことをすると、このエラーが発生します

12-09 18:11:25.195 16833-16833/li.doerf.leavemealone E/TelephonyServiceCallHangup:アクセス許可MODIFY_PHONE_STATEがないため、通話を切断できません

_MODIFY_PHONE_STATE_は保護された権限であるため、アプリで取得できません。 _Android 8.0+_の着信呼び出しをプログラムで終了する方法はありますか?

14
doerfli

アプリのターゲットとコンパイルレベルを28に変更しました。

そして次の許可。

<uses-permission Android:name="Android.permission.ANSWER_PHONE_CALLS" />
<uses-permission Android:name="Android.permission.READ_CALL_LOG"/>

MyPhoneStateListenerクラスのonCallStateChangedメソッドに次のコードを追加します。

public void endCall() {
        if (Android.os.Build.VERSION.SDK_INT >= Android.os.Build.VERSION_CODES.P) {
            TelecomManager tm = (TelecomManager) mcontext.getSystemService(Context.TELECOM_SERVICE);
            if (tm != null) {
                boolean success = tm.endCall();
            }
            // success == true if call was terminated.
        } else {
            if (mcontext != null) {
                TelephonyManager telephony = (TelephonyManager) mcontext
                        .getSystemService(Context.TELEPHONY_SERVICE);
                try {
                    Class c = Class.forName(telephony.getClass().getName());
                    Method m = c.getDeclaredMethod("getITelephony");
                    m.setAccessible(true);
                    telephonyService = (ITelephony) m.invoke(telephony);
                    // telephonyService.silenceRinger();
                    telephonyService.endCall();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
1
Gaurav Agrawal

あなたに役立つ以下の2つのリンクを確認してください:

権限はマニフェストでシステムアプリにのみ付与されます

https://source.Android.com/devices/tech/config/perms-whitelist

上記のリンクは、MODIFY_PHONE_STATE権限のホワイトリストに使用されます。これはセキュリティ上の理由から、この種の権限にアクセスしたい場合は、オペレーションを呼び出した後に権限をホワイトリストに登録します。

Android oreoの最新の更新に従って、組み込みのメソッド実装を使用してアクティビティで電話を受けることができますが、これらはコールの終了を処理する開発者を提供していません。また、受信の電話番号を取得(読み取り)する呼び出しますが、許可を定義する必要があります。上記の説明で十分理解できると思います

この質問を理解して閉じてください。

1
Jyubin Patel

この権限をマニフェストに追加する必要があります-:

<uses-permission Android:name="Android.permission.MODIFY_PHONE_STATE"/>
0
Shivam Oberoi

提供された答え here のようなリフレクションを使用してみてください。

READ_PHONE_STATEおよびCALL_PHONE権限で動作します。 Android docs によると、これらの権限は非システムアプリケーションで使用できます。

0
canihazurcode

私が見つけた解決策があります。 NotificationListenerServiceとして登録し、アクションを解析して適切なPendingIntentsを送信する必要があります。

public class NotificationListener extends NotificationListenerService {
    private static final String TAG = "NotificationListener";
    private PendingIntent answerIntent;
    private PendingIntent hangupIntent;

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        String packageName = sbn.getPackageName();
        if ("com.google.Android.dialer".equals(packageName)) {
            Notification notification = sbn.getNotification();
            for (Notification.Action action : notification.actions) {
                String title = String.valueOf(action.title);
                if ("hang up".equalsIgnoreCase(title) || "decline".equalsIgnoreCase(title)) {
                    hangupIntent = action.actionIntent;
                } else if ("answer".equalsIgnoreCase(title)) {
                    answerIntent = action.actionIntent;
                }
            }
        }
    }

    @Override
    public void onListenerConnected() {
        Log.i(TAG, "Listener connected");
        for (StatusBarNotification sbn : getActiveNotifications()) {
            onNotificationPosted(sbn);
        }
    }

    public void answerCall() {
        try {
            answerIntent.send();
        } catch (PendingIntent.CanceledException e) {
            e.printStackTrace();
        }
    }

    public void endCall() {
        try {
            hangupIntent.send();
        } catch (PendingIntent.CanceledException e) {
            e.printStackTrace();
        }
    }
}

次に、AndroidManifest.xmlで以下を宣言します。

    <service
        Android:name=".NotificationListener"
        Android:label="@string/app_name"
        Android:permission="Android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
        <intent-filter>
            <action Android:name="Android.service.notification.NotificationListenerService" />
        </intent-filter>
    </service>

もう1つのステップがあります。ユーザーがアプリを通知リスナーとして手動で有効にする必要があります。手順を示すダイアログを表示し、次のコードを使用してユーザーを設定ページに送ることができます。

Intent intent = new Intent(Android.provider.Settings.ACTION_NOTIFICATION_LISTENER_SETTINGS);
startActivity(intent);
0
jspenguin