如何检测耳机插头事件"离线"模式 [英] How to detect headphone plug event in "offline" mode

查看:240
本文介绍了如何检测耳机插头事件"离线"模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道如何检测耳机插头的情况下,如果我的应用程序正在运行。你必须注册广播接收器ACTION_HEADSET_PLUG。但你不能使用清单声明广播接收器捕捉到这一行动。因此,唯一的选择来捕捉耳机插头的事件是后台服务。但它水渠电池等。

I know how to detect headphone plug in event if my application is running. You have to register broadcast receiver for ACTION_HEADSET_PLUG. But you can't capture this action using Manifest declaration for broadcast receiver. Therefore the only option to capture headphone plug in event is background service. But it drains battery and so on.

我查了一些音乐播放器和想通了,他们抓住该事件没有任何额外的服务。他们是怎么做到的?任何想法?

I checked out some music players and figured out that they capture that event without any additional services. How do they do that? Any ideas?

推荐答案

我已经在商店的应用程序,为三年来监控有线耳机和蓝牙状态,既没有人曾经抱怨电池消耗。但是,这是因为我成功地用一个单一的服务和广播接收器,用于检测来自两个事件。这里有两个关键的类:

I've had an app in the store for three years that monitors both the wired headset and bluetooth state and nobody has ever complained about battery drain. But that is because I am successfully using a single service and broadcast receiver for detecting events from both. Here's the two key classes:

public class HeadsetStateBroadcastReceiver extends BroadcastReceiver {

    public static final String[] HEADPHONE_ACTIONS = {
        Intent.ACTION_HEADSET_PLUG,
        "android.bluetooth.headset.action.STATE_CHANGED",
        "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED"
    };

    @Override
    public void onReceive(final Context context, final Intent intent) {

        boolean broadcast = false;

        // Wired headset monitoring
        if (intent.getAction().equals(HEADPHONE_ACTIONS[0]) {
            final int state = intent.getIntExtra("state", 0);
            AudioPreferences.setWiredHeadphoneState(context, state > 0);
            broadcast = true;
        }

        // Bluetooth monitoring
        // Works up to and including Honeycomb
        if (intent.getAction().equals(HEADPHONE_ACTIONS[1])) {
            int state = intent.getIntExtra("android.bluetooth.headset.extra.STATE", 0);
            AudioPreferences.setBluetoothHeadsetState(context, state == 2);
            broadcast = true;
        }

        // Works for Ice Cream Sandwich
        if (intent.getAction().equals(HEADPHONE_ACTIONS[2])) {
            int state = intent.getIntExtra("android.bluetooth.profile.extra.STATE", 0);
            AudioPreferences.setBluetoothHeadsetState(context, state == 2);
            broadcast = true;
        }

        // Used to inform interested activities that the headset state has changed
        if (broadcast) {
            LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("headsetStateChange"));
        }

    }

}

下面是服务,我用它来注册的广播接收器:

Here is the service I use to register the broadcast receiver:

public class HeadsetMonitoringService extends Service {

    HeadsetStateBroadcastReceiver headsetStateReceiver;

    @Override
    public void onCreate() {

        headsetStateReceiver = new HeadsetStateBroadcastReceiver();
        final IntentFilter filter = new IntentFilter();
        for (String action: HeadsetStateBroadcastReceiver.HEADPHONE_ACTIONS) {
            filter.addAction(action);
        }

        registerReceiver(headsetStateReceiver, filter);

    }

    @Override
    public int onStartCommand(final Intent intent, final int flags, final int startId) {
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        unregisterReceiver(headsetStateReceiver);
    }

    @Override
    public IBinder onBind(final Intent intent) {
        return null;
    }

}

和这里是我的清单条目:

And here is my manifest entry:

    <service
        android:name=".services.HeadsetMonitoringService"
        android:enabled="true"
        android:exported="false" >
        <intent-filter>
            <action android:name="initialiseHeadsetService" />
        </intent-filter>
    </service>

如何工作如下:我使用的引导广播接收器发送一个启动服务消息HeadsetMonitoringService(你不必做这种方式,你可能只是做到这一点,当你的应用程序启动代替)。反过来HeadsetMonitoringService注册了一个广播监听器监听到所有的耳机事件我很感兴趣的一个实例 - 他们是HEADPHONE_ACTIONS阵列中举行。因为服务是粘它挂周围 - 因此,所以没有广播听众。但是,因为无论是服务和广播听众是事件驱动,直到耳机的状态发生改变时,他们不消耗任何电量。此外,因为服务是粘性的,它会被由OS重新启动,如果它意外死亡。每当我收到一个耳机状态改变事件我也火了当地的广播让有兴趣的活动,可以检查新的状态,并在必要时采取行动。

How it works is as follows: I use an on boot broadcast receiver to send a start service message to the HeadsetMonitoringService (you don't have to do it this way, you could just do this when your application starts instead). The HeadsetMonitoringService in turn registers an instance of a broadcast listener that listens to all the headset events I am interested in - they are held in the HEADPHONE_ACTIONS array. Because the service is sticky it hangs around - and therefore so does the broadcast listener. But because both the service and the broadcast listener are event driven they do not consume any power until a headset state change occurs. Additionally, because the service is sticky, it will be restarted by the OS if it dies unexpectedly. Whenever I receive a headset state change event I also fire a local broadcast so that interested activities can check the new state and take action if required.

有关完整性我要指出,我使用另一个类(这里没有显示),音频preferences,保存为preferences无论是蓝牙和有线耳机的状态,然后可以每当我需要访问知道耳机的状态。

For completeness I should point out that I use another class (not shown here), AudioPreferences, to store as preferences both the bluetooth and wired headset state, which can then be accessed whenever I need to know the headset state.

您的应用程序将需要android.permission.BLUETOOTH权限,如果你有兴趣在一个蓝牙耳机的状态。如果没有,就掏出从HEADPHONE_ACTIONS阵列蓝牙相关行动,并删除相关的如果从的onReceive方法块。

Your application will need the android.permission.BLUETOOTH permission if you are interested in the state of a Bluetooth headset. If not, just take out the bluetooth related actions from the HEADPHONE_ACTIONS array and delete the associated if blocks from the onReceive method.

这篇关于如何检测耳机插头事件&QUOT;离线&QUOT;模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆