检测耳机是否插入Android设备。

时间:2011-06-06 07:40:34

标签: android audio android-intent

如何确定耳机是否已插入Android设备?

6 个答案:

答案 0 :(得分:43)

您可以使用广播接收器。

因此,您可以在“AndroidManifest.xml”

中编写此代码
<receiver android:name="com.juno.brheadset.HeadsetStateReceiver">
    <intent-filter>
        <action android:name="android.intent.action.HEADSET_PLUG"/>
    </intent-filter>
</receiver>-->

但是,这不起作用。当OS发送此“HEADSET_PLUG”意图时,OS会设置标志“Intent.FLAG_RECEIVER_REGISTERED_ONLY”因此,您应该在Activity或Service类中编写如下代码,而不是“AndroidManifest”。

public class BRHeadsetActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    IntentFilter receiverFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
    HeadsetStateReceiver receiver = new HeadsetStateReceiver();
    registerReceiver( receiver, receiverFilter );


}

我希望这篇文章可以帮到你。再见!

这是“HeadsetObserver.java”,Android SDK Source。

的一部分
private final void sendIntent(int headset, int headsetState, int prevHeadsetState, String headsetName) {
    if ((headsetState & headset) != (prevHeadsetState & headset)) {
        //  Pack up the values and broadcast them to everyone
        Intent intent = new Intent(Intent.ACTION_HEADSET_PLUG);

        **intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);**

        int state = 0;
        int microphone = 0;

        if ((headset & HEADSETS_WITH_MIC) != 0) {
            microphone = 1;
        }
        if ((headsetState & headset) != 0) {
            state = 1;
        }
        intent.putExtra("state", state);
        intent.putExtra("name", headsetName);
        intent.putExtra("microphone", microphone);

        if (LOG) Slog.v(TAG, "Intent.ACTION_HEADSET_PLUG: state: "+state+" name: "+headsetName+" mic: "+microphone);
        // TODO: Should we require a permission?
        ActivityManagerNative.broadcastStickyIntent(intent, null);
    }
}

答案 1 :(得分:29)

当您说“耳机”时,您的意思是“有线耳机”吗?如果是这样,则有意检测是否正在插入或拔出插头:ACTION_HEADSET_PLUG

要检查状态,您可以使用AudioManager.isWiredHeadsetOn(),但如果还有蓝牙耳机可能会返回false,而音频会被路由到此。

答案 2 :(得分:15)

AudioManager.isWiredHeadsetOn()始终返回false,因为它需要用户权限MODIFY_AUDIO_SETTINGS

我花了几天时间找到答案。官方文档中没有关于此的信息。此bug已在BugTracker中注册。

答案 3 :(得分:4)

答案 4 :(得分:0)

首先,在清单中创建接收方:

    <receiver android:name="com.yourapplication.BroadcastReceiver">
        <intent-filter>
            <action android:name="android.intent.action.HEADSET_PLUG"/>
        </intent-filter>
    </receiver>

不要忘记根据您的项目名称更改com.your应用程序

在活动的开头创建两个变量:

private  BroadcastReceiver mReceiver  ;
boolean Microphone_Plugged_in = false;

在活动的onCreate内定义接收方:

        mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            final String action = intent.getAction();
            int iii=2;
            if (Intent.ACTION_HEADSET_PLUG.equals(action)) {
                iii=intent.getIntExtra("state", -1);
                if(Integer.valueOf(iii)==0){
                    Microphone_Plugged_in = false;
                    Toast.makeText(getApplicationContext(),"microphone not plugged in",Toast.LENGTH_LONG).show();
                }if(Integer.valueOf(iii)==1){
                    Microphone_Plugged_in = true;
                    Toast.makeText(getApplicationContext(),"microphone plugged in",Toast.LENGTH_LONG).show();
                }
            }
        }};
        IntentFilter receiverFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
        registerReceiver( mReceiver, receiverFilter );

添加onResume和onStope:

@Override
  protected void onResume() {
    super.onResume();
    IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
    getApplicationContext().registerReceiver(mReceiver, filter);
}

@Override
protected void onStop() {
    super.onStop();
    getApplicationContext().unregisterReceiver(mReceiver);
}

答案 5 :(得分:0)

要添加到其他答案中,来自 Android 文档:

<块引用>

警告:限制您在应用中设置的广播接收器数量。 广播接收器过多会影响应用的性能 以及用户设备的电池寿命。有关更多信息 您可以使用 API 代替 BroadcastReceiver 类进行调度 后台工作,请参阅后台优化。

https://developer.android.com/guide/topics/manifest/receiver-element

这意味着您应该创建尽可能少的广播接收器,以防止您的应用出现内存问题。

我建议在这个接收器上使用单例类。在科特林中:

class HeadsetReceiver private constructor(): BroadcastReceiver() {

    // instances
    var callback: HeadsetReceiverCallback? = null

    //region singleton
    private object HOLDER {
        val INSTANCE = HeadsetReceiver()
    }

    companion object {
        val instance: HeadsetReceiver by lazy { HOLDER.INSTANCE }
    }
    //endregion

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == Intent.ACTION_HEADSET_PLUG) {
            if(intent.getIntExtra("state", -1) == 0) {
                callback?.onHeadsetDisconnected()
            } else {
                callback?.onHeadsetConnected()
            }
        }
    }

    fun register(context: Context) {
        val receiverFilter = IntentFilter(Intent.ACTION_HEADSET_PLUG)
        context.registerReceiver(this, receiverFilter)
    }

    fun unregister(context: Context) {
        context.unregisterReceiver(this)
        callback = null
    }

    interface HeadsetReceiverCallback {
        fun onHeadsetConnected()
        fun onHeadsetDisconnected()
    }
}

注册:

HeadsetReceiver.instance.register(context)
        HeadsetReceiver.instance.callback = object : HeadsetReceiver.HeadsetReceiverCallback {
            override fun onHeadsetConnected() {
                println("connected!")
            }

            override fun onHeadsetDisconnected() {
                println("disonnected!")
            }
        }

注销:

HeadsetReceiver.instance.unregister(context)