通过AppWidgetProvider判断耳机是不是插入,拔出时暂停音乐
Posted
技术标签:
【中文标题】通过AppWidgetProvider判断耳机是不是插入,拔出时暂停音乐【英文标题】:Determine if headphones are plugged in through AppWidgetProvider, pause music when unplugged通过AppWidgetProvider判断耳机是否插入,拔出时暂停音乐 【发布时间】:2014-02-06 04:39:29 【问题描述】:关于这方面的问题有一百万零五个,但我已经尝试将它们全部分类,但无法使其正常工作。我知道 AppWidgetProvider 只是扩展了 BroadcastReceiver,所以我认为我可以在我的 AppWidgetProvider 中做所有事情。我读过意图过滤器 ACTION_HEADSET_PLUG 是 Intent.FLAG_RECEIVER_REGISTERED_ONLY 并尝试遵循以下内容:Detecting whether a headset is plugged into an android device or not. 在代码中设置我的过滤器,但它非常混乱,我无法理解它。
我已经在 onReceive 方法中删除了 intent.getAction(),当我插入或拔出耳机时,什么都没有显示。但是,当我按下按钮时,我看到了与它们关联的 int 常量。我假设这是因为它被唯一注册的东西阻止了。
我还读到了一些粘性的东西或其他东西,并用它分叉了一段时间,但无济于事。
这是我的 AppWidgetManager:
package com.example.musicplayerforburrito;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.widget.RemoteViews;
import android.widget.Toast;
public class MyWidgetProvider extends AppWidgetProvider
public static String WIDGET_PLAY_BUTTON = "android.appwidget.action.PLAY_PAUSE_WIDGETS";
public static String NEXT_BUTTON = "android.appwidget.action.NEXT_WIDGETS";
public static String PREVIOUS_BUTTON = "android.appwidget.action.PREVIOUS_WIDGETS";
public static String RELOAD_BUTTON = "android.appwidget.action.RELOAD_WIDGETS";
static MusicPlayerClass mpc;
static String CurrentlyPlayingSong = "";
static Context cont;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
mpc = new MusicPlayerClass(context);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
ComponentName watchWidget = new ComponentName(context, MyWidgetProvider.class);
remoteViews.setOnClickPendingIntent(R.id.playpausewidget, getPendingSelfIntent(context, WIDGET_PLAY_BUTTON));
remoteViews.setOnClickPendingIntent(R.id.forwardwidget, getPendingSelfIntent(context, NEXT_BUTTON));
remoteViews.setOnClickPendingIntent(R.id.backwidget, getPendingSelfIntent(context, PREVIOUS_BUTTON));
remoteViews.setOnClickPendingIntent(R.id.reloadwidget, getPendingSelfIntent(context, RELOAD_BUTTON));
appWidgetManager.updateAppWidget(watchWidget, remoteViews);
@Override
public void onReceive(Context context, Intent intent)
// TODO Auto-generated method stub
super.onReceive(context, intent);
//if(intent.hasExtra("state"))
// Toast.makeText(context, "hi jimmy", 2000).show();
Toast.makeText(context, intent.getAction(), 2000).show();
try
String b = mpc.currentlyPlayingSong;
catch(Exception e)
mpc = new MusicPlayerClass(context);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews = new RemoteViews( context.getPackageName(), R.layout.widget_layout );
ComponentName watchWidget = new ComponentName(context, MyWidgetProvider.class);
cont = context;
if (WIDGET_PLAY_BUTTON.equals(intent.getAction()))
if(!mpc.hasFolders)
mpc.Initialize();
mpc.mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
public void onCompletion(MediaPlayer mp)
mpc.songIndex++;
CurrentlyPlayingSong = mpc.StartSong();
UpdateTitle(cont);
);
if(mpc.isPlaying)
mpc.isPlaying = false;
mpc.PauseMusic();
remoteViews.setImageViewResource(R.id.playpausewidget, R.drawable.play);
else if(mpc.currentPosition != 0)
mpc.isPlaying = true;
mpc.ResumeMusic();
remoteViews.setImageViewResource(R.id.playpausewidget, R.drawable.pause);
else
remoteViews.setTextViewText(R.id.mp3filename, mpc.StartSong());
remoteViews.setImageViewResource(R.id.playpausewidget, R.drawable.pause);
else if (NEXT_BUTTON.equals(intent.getAction()))
mpc.songIndex++;
remoteViews.setTextViewText(R.id.mp3filename, mpc.StartSong());
else if (PREVIOUS_BUTTON.equals(intent.getAction()))
mpc.songIndex--;
remoteViews.setTextViewText(R.id.mp3filename, mpc.StartSong());
else if (RELOAD_BUTTON.equals(intent.getAction()))
mpc.Reload();
mpc.mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
public void onCompletion(MediaPlayer mp)
mpc.songIndex++;
CurrentlyPlayingSong = mpc.StartSong();
UpdateTitle(cont);
);
remoteViews.setTextViewText(R.id.mp3filename, mpc.StartSong());
remoteViews.setImageViewResource(R.id.playpausewidget, R.drawable.pause);
appWidgetManager.updateAppWidget(watchWidget, remoteViews);
private void UpdateTitle(Context context)
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews = new RemoteViews( context.getPackageName(), R.layout.widget_layout );
ComponentName watchWidget = new ComponentName(context, MyWidgetProvider.class);
remoteViews.setTextViewText(R.id.mp3filename, CurrentlyPlayingSong);
appWidgetManager.updateAppWidget(watchWidget, remoteViews);
protected PendingIntent getPendingSelfIntent(Context context, String action)
Intent intent = new Intent(context, getClass());
intent.setAction(action);
return PendingIntent.getBroadcast(context, 0, intent, 0);
这是我的清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.musicplayerforburrito"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="MyWidgetProvider" >
<intent-filter >
<action
android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.PLAY_PAUSE_WIDGETS" />
<action android:name="android.appwidget.action.NEXT_WIDGETS" />
<action android:name="android.appwidget.action.PREVIOUS_WIDGETS" />
<action android:name="android.appwidget.action.RELOAD_WIDGETS" />
<action android:name="android.appwidget.action.ACTION_HEADSET_PLUG" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.ACTION_HEADSET_PLUG"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_info" />
</receiver>
<activity
android:name="com.example.musicplayerforburrito.MusicPlayer"
android:label="@string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
我已经为此奋斗了好几个小时,这似乎真的很愚蠢,因为在拔下耳机时暂停音乐甚至不是那么大的“功能”。您可以分享的任何指导将不胜感激。
TIA
【问题讨论】:
【参考方案1】:https://***.com/a/9682818/1682419 的答案引用了 Dianne Hackborn(Android 核心团队的成员)的话。只要您对这些广播消息感兴趣,您就需要一个保持运行的服务或活动,并且它需要调用registerReceiver()
来注册这些消息。
注意 1:当您创建 Intent 操作时,您应该使用自己的包名,而不是android.intent.action
,以避免名称冲突。
注意 2: 小部件提供者的 <intent-filter>
应该只列出公共操作 android.appwidget.action.APPWIDGET_UPDATE
。包含私人点击操作和android.intent.action.ACTION_HEADSET_PLUG
没有任何好处。
【讨论】:
以上是关于通过AppWidgetProvider判断耳机是不是插入,拔出时暂停音乐的主要内容,如果未能解决你的问题,请参考以下文章
如何监控设备的音频输出以判断声音是不是来自扬声器/耳机插孔?
扩展 AppWidgetProvider 的 Widget 中是不是可以使用 TextView Marquee?