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" />


3.实时检测耳机插入和拔出:

  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
原创粉丝点击