3

ボタンが 1つの Bluetooth ヘッドセット(Jabra BT2045) を持っていますが、ボタンの押下をインターセプトしたいと考えています。バックグラウンドアシスタントServiceがユーザーの音声コマンドを解釈し、それに応じて行動できるようにするために、これが必要です。

(有線メディア ヘッドセットを使用して) 問題なくインターセプトできるBroadcastReceiver名前を定義しましたが、BT コール ボタンをインターセプトすることが重要です。私が読んだ別の提案に基づいてアクションをインターセプトしようとしましたが、これも失敗します。MediaButtonIntentReceiverACTION_MEDIA_BUTTONCALL_BUTTON

または、ボタンをダブルタップすると最新の人に電話がかかり、長押しすると音声ダイヤラーが表示されます.

単一のボタンまたはこれらの手順を傍受するにはどうすればよいですか (+それらを防ぐ)? アイデアのプロトタイピングなのでハックは大歓迎ですが、Android のバージョンに関係なく機能するソリューションが最適です。

Android 4.3 で Galaxy Nexus を使用しています。

AndroidManifest.xml (レシーバー定義を含む)

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="nz.ac.waikato.ssc10.BlindAssistant">

    <uses-sdk android:minSdkVersion="17"/>

    <uses-permission android:name="android.permission.ACCESS_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.INTERNET"/>

    <!-- Bluetooth Headset -->
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BROADCAST_STICKY"/>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>

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

    <application
        android:icon="@drawable/icon"
        android:label="@string/app_name">
        <activity
            android:name=".activities.VoicePromptActivity"
            android:screenOrientation="portrait"
            android:label="Voice Prompt">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>

        <service android:name=".services.BlindAssistantService"/>
        <service android:name=".services.WalkingDirectionsUpdateService"/>

        <receiver android:name=".receivers.MediaButtonIntentReceiver">
            <intent-filter>
                <action android:name="android.intent.action.CALL_BUTTON"/>
            </intent-filter>
        </receiver>
    </application>
</manifest>

レシーバーの定義:

public class CallButtonIntentReceiver extends BroadcastReceiver {
    private static String TAG = "CallButtonIntentReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        String intentAction = intent.getAction(); // I never get to this point in debugger (breakpoint set here)

        // Code to actually handle button press ...
    }
}

更新 1:

アクティビティに追加のインテント フィルター(以下を参照) を設定すると、(デフォルトとして設定した後) 長押しすると起動します。これは正しい方向に進んでいるように見えますが、今ではアクティビティが何度も開始され、奇妙な結果が生じています。

現在、アクティビティを 1 回だけ開始することを調査しています。アクティビティが再開されたときに、ランチャーから開始されたのか、VOICE_COMMANDアクションから開始されたのかを検出できる必要があります。このメソッドを機能させるには、アクティビティが 1 回だけ開始されるようにする必要があります (ボタンを押すと、アクティビティが再開されます)。

さらに、可能であれば、アクティビティがサービスの実行中のみデフォルトになるようにしたいと考えています。

<intent-filter>
    <action android:name="android.intent.action.VOICE_COMMAND"/>
    <category android:name="android.intent.category.DEFAULT"/>
</intent-filter>

更新 2:

残念ながら、Bluetooth ヘッドセットの SCO チャネルが有効になっている間は、アクティビティは作成されません。私のアプリケーションでは、ユーザーが BT ヘッドセットから発信されなければならない定期的な更新を (TTS 経由で) 受信するため、このチャネルを開く必要があります。この方法では、多くのオーバーヘッドが発生する可能性があります。

4

1 に答える 1

1

テスト アクティビティの onKeyDown メソッドを使用して、ヘッドセット ボタンのキーコードを識別することができます。

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
  Log.d("KeyCode", keycode + "");
  Log.d("KeyEvent", event + "");
  return super.onKeyDown(keyCode, event);
}

次に、アクティビティを実行し、logcat を見ながらヘッドセット ボタンを押します。http://developer.android.com/reference/android/view/KeyEvent.htmlを参照できます

onKeyDown からその動作をオーバーライドすることもできますが、明らかなセキュリティ上の理由から、Service はもちろん、Activity の外部で主要なイベントをリッスンすることはできないと思います。

于 2013-09-01T04:09:09.997 に答える