已注册的ACTION_HEADSET_PLUG侦听器仅触发几次

时间:2012-07-16 10:07:07

标签: android audio sense

我希望在插入耳机后显示通知,并在拔下插头后将其隐藏。因此,我在一个在BOOT_COMPLETED处触发的BroadCastReceiver中注册ACTION_HEADSET_PLUG Intent Listener。在我的情况下,我使用HTC Sense(HTC One S),只有当我在Sense加载时插入耳机时显示通知(WaitDialog),之后它将不再显示。

如果我在运行时通过'new OnBootreceiver()。onReceive(this,null)'在应用程序中触发OnBootListener,它就可以完美。

清单:

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

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        ...
    </activity>

    <receiver android:name=".OnBootReceiver" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>
 ...

OnBootReceiver:

public void onReceive(Context context, Intent intent) {
    IntentFilter receiverFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
    HeadsetStateReceiver receiver = new HeadsetStateReceiver();
    context.registerReceiver( receiver, receiverFilter );
}

HeadsetStateReceiver:

public void onReceive(Context context, Intent intent) {
    Toast.makeText(context,
            "" + (Integer) (intent.getExtras().get("state")),
            Toast.LENGTH_SHORT).show();
    mNotificationManager = (NotificationManager) context
            .getSystemService(Context.NOTIFICATION_SERVICE);

    Log.e(this.getClass().toString(), "Intent Headset_plug received "
            + intent);
    if ((Integer) (intent.getExtras().get("state")) != 0) {
        notification.flags = Notification.FLAG_ONGOING_EVENT;
        notification.contentIntent = PendingIntent.getActivity(
                context.getApplicationContext(), 0, new Intent(), 0);
        notification.setLatestEventInfo(context, title, message,
                notification.contentIntent);
        mNotificationManager.notify(0xBEA15, notification);
    } else {
        mNotificationManager.cancelAll();
    }

}

2 个答案:

答案 0 :(得分:1)

为什么需要BOOT_COMPLETED接收器?您是否尝试使用清单文件接收ACTION_HEADSET_PLUG?

<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 
    <activity 
        ... 
    </activity> 

    <receiver android:name=".HeadsetStateReceiver" > 
        <intent-filter> 
            <action android:name="android.intent.ACTION_HEADSET_PLUG" /> 
        </intent-filter> 
    </receiver> 

你的代码也有点麻烦:

public void onReceive(Context context, Intent intent) {
    boolean isConnected = intent.getIntExtra("state",0)==1; // Can also be 2 if headset is attached w/o mic.

    Toast.makeText(context, 
            isConnected?"connected":"disconnected"), 
            Toast.LENGTH_SHORT).show(); 
    mNotificationManager = (NotificationManager) context 
        .getSystemService(Context.NOTIFICATION_SERVICE); 

    if (isConnected) {
        Log.e(this.getClass().toString(), "Intent Headset_plug connected");
        notification.flags = Notification.FLAG_ONGOING_EVENT; 
        notification.contentIntent = PendingIntent.getActivity( 
                context.getApplicationContext(), 0, new Intent(), 0); 
        notification.setLatestEventInfo(context, title, message, 
                notification.contentIntent); 
        mNotificationManager.notify(0xBEA15, notification); 
    } else {
        Log.e(this.getClass().toString(), "Intent Headset_plug disconnected");
        mNotificationManager.cancelAll(); 
    } 
} 


Ok直接接收器不起作用(here is good explanation)。

我知道为什么你的接收器会在一段时间后停止工作。您的应用程序必须由系统清理。 为了使它工作,你必须做一些会阻止你的应用程序清理的东西。所以你必须创建一个服务。在BOOT_COMPLETED中启动一个服务,并在此服务中注册ACTION_HEADSET_PLUG的广播接收器。这应该可以防止应用程序被清除。

答案 1 :(得分:1)

您的代码是正确的,但据我所知,您不能将HEADSET_PLUG过滤器放在清单上。相反,从清单中删除接收器,并从应用程序的某些部分以编程方式执行。主活动的onCreate()方法应该没问题,例如:

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