FM 模块学习-----耳机(天线)相关处理
来源:互联网 发布:淘宝店名叫什么好 编辑:程序博客网 时间:2024/05/26 19:16
1.判断是否插入耳机:(FmRadioService.java)
AudioManager mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); /** * Check whether antenna is available * @return true or false indicate antenna available or not */public boolean isAntennaAvailable() { return mAudioManager.isWiredHeadsetOn();}
2.当然,要加个权限,不然一直是返回false。
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
private class FmServiceBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG, ">>> FmRadioService.onReceive"); String action = intent.getAction(); String command = intent.getStringExtra("command"); Log.d(TAG, "Action/Command: " + action + " / " + command); // other app want FM stop, stop FM if (Intent.ACTION_HEADSET_PLUG.equals(action)) { // switch antenna should not impact audio focus status mValueHeadSetPlug = (intent.getIntExtra("state", -1) == HEADSET_PLUG_IN) ? 0 : 1; switchAntennaAsync(mValueHeadSetPlug); if (SHORT_ANNTENNA_SUPPORT) { boolean isSwitch = (switchAntenna(mValueHeadSetPlug) == 0) ? true : false; Log.d(TAG, "onReceive.switch anntenna:isWitch:" + isSwitch); // Plug out->Speaker Mode; Plug in->Earphone Mode boolean plugInEarphone = (0 == mValueHeadSetPlug); // Need check to switch to earphone mode for audio will // change to AudioSystem.FORCE_NONE if (plugInEarphone) { mForcedUseForMedia = AudioSystem.FORCE_NONE; mIsSpeakerUsed = false; } //setSpeakerPhoneOn(!plugInEarphone); // Notify UI change to earphone mode, false means not speaker mode Bundle bundle = new Bundle(2); bundle.putInt(FmRadioListener.CALLBACK_FLAG, FmRadioListener.LISTEN_SPEAKER_MODE_CHANGED); bundle.putBoolean(FmRadioListener.KEY_IS_SPEAKER_MODE, !plugInEarphone); notifyActivityStateChanged(bundle); powerUpAutoIfNeed(); } else { // Avoid Service is killed,and receive headset plug in // broadcast again if (!mIsServiceInited) { Log.d(TAG, "onReceive.switch anntenna:service is not init"); powerUpAutoIfNeed(); return; } /* * If ear phone insert and activity is * foreground. power up FM automatic */ if ((0 == mValueHeadSetPlug) && isActivityForeground()) { Log.d(TAG, "onReceive.switch anntenna:need auto power up"); powerUpAsync(FmRadioUtils.computeFrequency(mCurrentStation)); } else if (1 == mValueHeadSetPlug) { Log.d(TAG, "plug out earphone, need to stop fm"); // ALPS01687760 Avoid sound from speaker after plug out earphone when recording // plug out earphone will power down or exit, need to mute first anyway setMute(true); mFmServiceHandler.removeMessages(FmRadioListener.MSGID_SCAN_FINISHED); mFmServiceHandler.removeMessages(FmRadioListener.MSGID_SEEK_FINISHED); mFmServiceHandler.removeMessages(FmRadioListener.MSGID_TUNE_FINISHED); mFmServiceHandler.removeMessages( FmRadioListener.MSGID_POWERDOWN_FINISHED); mFmServiceHandler.removeMessages( FmRadioListener.MSGID_POWERUP_FINISHED); stopFmFocusLoss(AudioManager.AUDIOFOCUS_LOSS); // Need check to switch to earphone mode for audio will // change to AudioSystem.FORCE_NONE setSpeakerPhoneOn(false); // Notify UI change to earphone mode, false means not speaker mode Bundle bundle = new Bundle(2); bundle.putInt(FmRadioListener.CALLBACK_FLAG, FmRadioListener.LISTEN_SPEAKER_MODE_CHANGED); bundle.putBoolean(FmRadioListener.KEY_IS_SPEAKER_MODE, false); notifyActivityStateChanged(bundle); } } }
4.弹出拔出耳机弹出框:(NoAntennaDialog.java)
/** * No antenna dialog, caller should implement NoAntennaListener */public class NoAntennaDialog extends DialogFragment { private static final String TAG = "FmRx/NoAntennaDialog"; private NoAntennaListener mListener = null; /** * Create no antenna dialog instance, caller should implement * NoAntennaListener */ public static NoAntennaDialog newInstance() { return new NoAntennaDialog(); } /** * No antenna listener */ public interface NoAntennaListener { /** * Continue to operate when no antenna */ void noAntennaContinue(); /** * Cancel operate when no antenna */ void noAntennaCancel(); } @Override public void onAttach(Activity activity) { super.onAttach(activity); try { mListener = (NoAntennaListener) activity; } catch (ClassCastException e) { e.printStackTrace(); } } @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setMessage(R.string.no_antenna_info) .setTitle(R.string.dlg_noantenna_title) .setPositiveButton(R.string.btn_yes, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { mListener.noAntennaContinue(); } }) .setNegativeButton(R.string.btn_no, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { mListener.noAntennaCancel(); } }); AlertDialog d = builder.create(); d.setCanceledOnTouchOutside(false); d.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) { Log.d(TAG, "click back key, need to exit fm"); mListener.noAntennaCancel(); } return false; } }); return d; }}
其中noAntennaContinus()、noAntennaCancel()两个方法在FmRadioActivity.java中实现,如下:
/** * No antenna continue to operate */ @Override public void noAntennaContinue() { // We let user use the app if no antenna. // But we do not automatically start FM. Log.d(TAG, " noAntennaContinue.onClick ok to continue"); if (isAntennaAvailable()) { powerUpFm(); } else { mService.switchAntennaAsync(1); } } /** * No antenna cancel to operate */ @Override public void noAntennaCancel() { if (mService != null && !mService.isInLockTaskMode()) { exitService(); } else { Log.d(TAG, "No need exit Service and Activity cause current is lock mode"); } }
5.显示dialog
/** * Show no antenna dialog */ public void showNoAntennaDialog() { NoAntennaDialog newFragment = NoAntennaDialog.newInstance(); newFragment.show(mFragmentManager, TAG_NO_ANTENNA); mFragmentManager.executePendingTransactions(); }
6.在启动FM时,先检测是否支持且插入耳机:
/** * handle power up, execute power up and call back to activity. * * @param bundle power up frequency */ private void handlePowerUp(Bundle bundle) { boolean isPowerup = false; boolean isSwitch = true; Log.d(TAG, "service handler power up start"); float curFrequency = bundle.getFloat(FM_FREQUENCY); if (!SHORT_ANNTENNA_SUPPORT && !isAntennaAvailable()) { mIsPowerUping = false; bundle = new Bundle(2); bundle.putInt(FmRadioListener.CALLBACK_FLAG, FmRadioListener.MSGID_SWITCH_ANNTENNA); bundle.putBoolean(FmRadioListener.KEY_IS_SWITCH_ANNTENNA, false); notifyActivityStateChanged(bundle); return; } //dongyang.li add for airplane mode. if(getAirplaneMode(getApplicationContext())) { mIsPowerUping = false; bundle = new Bundle(5); bundle.putInt(FmRadioListener.CALLBACK_FLAG, FmRadioListener.MSGID_AIRPLANE_MODE); bundle.putBoolean(FmRadioListener.FLAG_AIRPLANE_MODE, true); notifyActivityStateChanged(bundle); return; } if (powerUpFm(curFrequency)) { isPowerup = startPlayFm(curFrequency); mPausedByTransientLossOfFocus = false; } mIsPowerUping = false; bundle = new Bundle(2); bundle.putInt(FmRadioListener.CALLBACK_FLAG, FmRadioListener.MSGID_POWERUP_FINISHED); bundle.putBoolean(FmRadioListener.KEY_IS_POWER_UP, isPowerup); notifyActivityStateChanged(bundle); }
7.当检测到为插入耳机mService向FmRadioActivty.java发送消息更新UI:
bundle.putBoolean(FmRadioListener.KEY_IS_SWITCH_ANNTENNA, false);notifyActivityStateChanged(bundle);
接收到则显示Dialog:
case FmRadioListener.MSGID_SWITCH_ANNTENNA: bundle = msg.getData(); boolean isSwitch = bundle.getBoolean(FmRadioListener.KEY_IS_SWITCH_ANNTENNA); if (!isSwitch) { if (mIsActivityForeground) { dismissNoAntennaDialog(); showNoAntennaDialog(); } else { mIsNeedShowNoAntennaDlg = true; } stopAnimation(); refreshActionMenuPower(true); } else { mIsNeedShowNoAntennaDlg = false; dismissNoAntennaDialog(); } break;
今天研究一下FM模块搜索这个功能,界面中的Menu中的Search部分:
点击无天线提示框的确定按钮,响应函数为:noAntennaContinue()
如果isAntennaAvailable()为true,则启动FM,powerUpFm();
private void powerUpFm() { refreshImageButton(false); refreshActionMenuItem(false); refreshPopupMenuItem(false); refreshActionMenuPower(false); startAnimation(); mService.powerUpAsync(FmRadioUtils.computeFrequency(mCurrentStation)); }
如果isAntennaAvailable()为false, mService.switchAntennaAsync(1);
public void switchAntennaAsync(int antenna) { final int bundleSize = 1; mFmServiceHandler.removeMessages(FmRadioListener.MSGID_SWITCH_ANNTENNA); Bundle bundle = new Bundle(bundleSize); bundle.putInt(FmRadioListener.SWITCH_ANNTENNA_VALUE, antenna); Message msg = mFmServiceHandler.obtainMessage(FmRadioListener.MSGID_SWITCH_ANNTENNA); msg.setData(bundle); mFmServiceHandler.sendMessage(msg); }
class FmRadioServiceHandler extends Handler { public FmRadioServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { Bundle bundle; boolean isPowerup = false; boolean isSwitch = true; switch (msg.what) { // switch antenna case FmRadioListener.MSGID_SWITCH_ANNTENNA: bundle = msg.getData(); int value = bundle.getInt(FmRadioListener.SWITCH_ANNTENNA_VALUE); if (SHORT_ANNTENNA_SUPPORT) { isSwitch = (switchAntenna(value) == 0) ? true : false; } else { if (0 == value) { bundle.putInt(FmRadioListener.CALLBACK_FLAG, FmRadioListener.MSGID_SWITCH_ANNTENNA); bundle.putBoolean(FmRadioListener.KEY_IS_SWITCH_ANNTENNA, true); notifyActivityStateChanged(bundle); } else { if (mRecordState != FmRecorder.STATE_PLAYBACK) { bundle.putInt(FmRadioListener.CALLBACK_FLAG, FmRadioListener.MSGID_SWITCH_ANNTENNA); bundle.putBoolean(FmRadioListener.KEY_IS_SWITCH_ANNTENNA, false); notifyActivityStateChanged(bundle); } } } break; } //传到前台在处理,是否消失提示框,并且启动FM
这样就实现不停的检测天线是否插入
0 0
- FM 模块学习-----耳机(天线)相关处理
- FM radio_模块测试学习
- Android FM模块学习之四源码解析(一)
- Android FM模块学习之四源码解析(二)
- Android FM模块学习之四源码解析(三)
- Android FM模块学习之四源码解析(四)
- Android FM模块学习之四源码分析(五)
- Android FM模块学习之源码分析(六)
- Android FM模块学习之四源码分析(七)
- Android FM模块学习之四源码分析(八)
- Android FM模块学习之一 FM启动流程
- Android FM模块学习之二 FM搜索频率流程
- Android FM模块学习之三 FM手动调频
- Python图像处理相关模块学习文档
- Python相关模块学习1 处理文件名模块glob
- Python相关模块学习1 处理文件名模块glob
- OpenGLES 相关 - 10天线性代数学习总结
- AndroidFM模块学习之五关闭FM流程
- JSTL(fn函数)
- 优化SQL查询:如何写出高性能SQL语句
- leetcode Populating Next Right Pointers in Each Node 树 队列应用
- 安卓应用开发实战:[3]修改安卓应用程序图标
- java.lang.IllegalStateException: Cannot map handler
- FM 模块学习-----耳机(天线)相关处理
- Application类 的使用 ,设置全局变量
- C#多线程系列
- Linux Shell脚本面试问题大全
- Mongodb的windows服务安装和卸载
- 利用QtGraphicalEffects来使得自己的图像显示更加生动
- 常用排序--冒泡/快速排序
- sed 转译
- 安卓应用开发实战:[2]修改程序名称&标题