android FM手动调频流程



首先来看一下流程图:

2.滑动刻度盘HorizontalNumberPicker控件在监听事件里使用方法valueToFrequency(newVal)

1.长按左右箭头居中的频率字符串,弹出FrequencyPickerDialog调频对话框确定调用tuneRadio(frequency)调频。

获取到频率

[java]  view plain  copy
 print ?
  1. protected int valueToFrequency(int value) {  
  2.        mFrequency = mPrefs.getLowerLimit() + value *  
  3.                              mPrefs.getFrequencyStepSize();  
  4.        return mFrequency;  
  5.    }  
发送一个handler 回调一个tuneRadio(frequency)调频。

[java]  view plain  copy
 print ?
  1. Runnable mRadioChangeFrequency = new Runnable(){  
  2.        public void run() {  
  3.            mUpdatePickerValue = false;  
  4.            tuneRadio(mFrequency);  
  5.        }  
  6.    };  

3.手动点击按钮左右箭头, 通过监听调用:


int frequency =FmSharedPreferences.getNextTuneFrequency();

int frequency =FmSharedPreferences.getPrevTuneFrequency();

tuneRadio(frequency);进行调频

getNextTuneFrequency()方法通过判断频率最大限制范围,后加200(刻度)

getPrevTuneFrequency()方法通过判断频率最小限制范围,后减200(刻度)


调频方法分析

private void tuneRadio(int frequency)


[java]  view plain  copy
 print ?
  1. private void tuneRadio(int frequency){  
  2.       /* Issue the tune command only if tuneCommand is already not active */  
  3.       if((mService != null) && (mCommandActive != CMD_TUNE) && isFmOn()) {  
  4.          boolean bStatus = false;  
  5.          try {  
  6.              bStatus = mService.tune(frequency);  
  7.              if (bStatus) {  
  8.                  postTimeoutHandler(CMD_TUNE);  
  9.              }else {  
  10.                if (isFmOn()) {  
  11.                   mCommandFailed = CMD_TUNE;  
  12.                   Log.e(LOGTAG, "mService.tune failed");  
  13.                   showDialog(DIALOG_CMD_FAILED);  
  14.                }  
  15.              }mTunedStation.setName("");  
  16.              mTunedStation.setPI(0);  
  17.              mTunedStation.setPty(0);  
  18.              updateStationInfoToUI();  
  19.          }catch (RemoteException e) {  
  20.             e.printStackTrace();  
  21.          }  
  22.       }else {  
  23.          Log.e(LOGTAG, "Delayed Tune handler stopped");  
  24.       }  
  25.    }  


通过回调引用类调用FMRadioService类的tune()方法进行调频

bStatus = mService.tune(frequency);

发送一个广播连接是否超时

postTimeoutHandler(CMD_TUNE);


设置调频名字,更新FMRadioUI界面信息

mTunedStation.setName("");

mTunedStation.setPI(0);

mTunedStation.setPty(0);

updateStationInfoToUI()

(通过IFMRadioSrevice.aidl通信机制onbind返回的类的引用调用FMRadioService中的调频方法)

FMRadioService中的tune方法

public boolean tune(int frequency)

[java]  view plain  copy
 print ?
  1. public boolean tune(int frequency) {  
  2.       boolean bCommandSent=false;  
  3.       double doubleFrequency = frequency/1000.00;  
  4.   
  5.       Log.d(LOGTAG, "tuneRadio:  " + doubleFrequency);  
  6.       if (mReceiver != null)  
  7.       {  
  8.          mReceiver.setStation(frequency);  
  9.          bCommandSent = true;  
  10.       }  
  11.       return bCommandSent;  
  12.    }  

调用FMReceiver类的setStation方法调频

public boolean setStation (intfrequencyKHz)


[java]  view plain  copy
 print ?
  1. public boolean setStation (int frequencyKHz) {  
  2.       int ret;  
  3.   
  4.       mControl.setFreq(frequencyKHz);  
  5.       ret = mControl.setStation(sFd);  
  6.       if(ret < 0 )  
  7.       {  
  8.          return false;  
  9.       }  
  10.       else  
  11.       {  
  12.          return true;  
  13.       }  
  14.    }  

调用FMRxControls类(FM读取控制台信息)设置频率

mControl.setFreq(frequencyKHz);


设置优化调频核心指定的频率

ret = mControl.setStation(sFd);

 

[java]  view plain  copy
 print ?
  1. public int setStation(int fd) {  
  2.     Log.d(TAG, "** Tune Using: "+fd);  
  3.     int ret = FmReceiverJNI.setFreqNative(fd, mFreq);  
  4.     Log.d(TAG, "** Returned: "+ret);  
  5.     return ret;  
  6.  }  

最后调用FmReceiverJNI类

setFreqNative(fd, mFreq); 本地方法 JNI到 cpp文件

[cpp]  view plain  copy
 print ?
  1. /*native interface */  
  2. static jint android_hardware_fmradio_FmReceiverJNI_setFreqNative  
  3.     (JNIEnv * env, jobject thiz, jint fd, jint freq)  
  4. {  
  5.     int err;  
  6.     double tune;  
  7.     struct v4l2_frequency freq_struct;  
  8.     freq_struct.type = V4L2_TUNER_RADIO;  
  9.     freq_struct.frequency = (freq*TUNE_MULT/1000);  
  10.     err = ioctl(fd, VIDIOC_S_FREQUENCY, &freq_struct);  
  11.     if(err < 0){  
  12.             return FM_JNI_FAILURE;  
  13.     }  
  14.     return FM_JNI_SUCCESS;  
  15. }  

首先来看一下流程图:

2.滑动刻度盘HorizontalNumberPicker控件在监听事件里使用方法valueToFrequency(newVal)

1.长按左右箭头居中的频率字符串,弹出FrequencyPickerDialog调频对话框确定调用tuneRadio(frequency)调频。

获取到频率

[java]  view plain  copy
 print ?
  1. protected int valueToFrequency(int value) {  
  2.        mFrequency = mPrefs.getLowerLimit() + value *  
  3.                              mPrefs.getFrequencyStepSize();  
  4.        return mFrequency;  
  5.    }  
发送一个handler 回调一个tuneRadio(frequency)调频。

[java]  view plain  copy
 print ?
  1. Runnable mRadioChangeFrequency = new Runnable(){  
  2.        public void run() {  
  3.            mUpdatePickerValue = false;  
  4.            tuneRadio(mFrequency);  
  5.        }  
  6.    };  

3.手动点击按钮左右箭头, 通过监听调用:


int frequency =FmSharedPreferences.getNextTuneFrequency();

int frequency =FmSharedPreferences.getPrevTuneFrequency();

tuneRadio(frequency);进行调频

getNextTuneFrequency()方法通过判断频率最大限制范围,后加200(刻度)

getPrevTuneFrequency()方法通过判断频率最小限制范围,后减200(刻度)


调频方法分析

private void tuneRadio(int frequency)


[java]  view plain  copy
 print ?
  1. private void tuneRadio(int frequency){  
  2.       /* Issue the tune command only if tuneCommand is already not active */  
  3.       if((mService != null) && (mCommandActive != CMD_TUNE) && isFmOn()) {  
  4.          boolean bStatus = false;  
  5.          try {  
  6.              bStatus = mService.tune(frequency);  
  7.              if (bStatus) {  
  8.                  postTimeoutHandler(CMD_TUNE);  
  9.              }else {  
  10.                if (isFmOn()) {  
  11.                   mCommandFailed = CMD_TUNE;  
  12.                   Log.e(LOGTAG, "mService.tune failed");  
  13.                   showDialog(DIALOG_CMD_FAILED);  
  14.                }  
  15.              }mTunedStation.setName("");  
  16.              mTunedStation.setPI(0);  
  17.              mTunedStation.setPty(0);  
  18.              updateStationInfoToUI();  
  19.          }catch (RemoteException e) {  
  20.             e.printStackTrace();  
  21.          }  
  22.       }else {  
  23.          Log.e(LOGTAG, "Delayed Tune handler stopped");  
  24.       }  
  25.    }  


通过回调引用类调用FMRadioService类的tune()方法进行调频

bStatus = mService.tune(frequency);

发送一个广播连接是否超时

postTimeoutHandler(CMD_TUNE);


设置调频名字,更新FMRadioUI界面信息

mTunedStation.setName("");

mTunedStation.setPI(0);

mTunedStation.setPty(0);

updateStationInfoToUI()

(通过IFMRadioSrevice.aidl通信机制onbind返回的类的引用调用FMRadioService中的调频方法)

FMRadioService中的tune方法

public boolean tune(int frequency)

[java]  view plain  copy
 print ?
  1. public boolean tune(int frequency) {  
  2.       boolean bCommandSent=false;  
  3.       double doubleFrequency = frequency/1000.00;  
  4.   
  5.       Log.d(LOGTAG, "tuneRadio:  " + doubleFrequency);  
  6.       if (mReceiver != null)  
  7.       {  
  8.          mReceiver.setStation(frequency);  
  9.          bCommandSent = true;  
  10.       }  
  11.       return bCommandSent;  
  12.    }  

调用FMReceiver类的setStation方法调频

public boolean setStation (intfrequencyKHz)


[java]  view plain  copy
 print ?
  1. public boolean setStation (int frequencyKHz) {  
  2.       int ret;  
  3.   
  4.       mControl.setFreq(frequencyKHz);  
  5.       ret = mControl.setStation(sFd);  
  6.       if(ret < 0 )  
  7.       {  
  8.          return false;  
  9.       }  
  10.       else  
  11.       {  
  12.          return true;  
  13.       }  
  14.    }  

调用FMRxControls类(FM读取控制台信息)设置频率

mControl.setFreq(frequencyKHz);


设置优化调频核心指定的频率

ret = mControl.setStation(sFd);

 

[java]  view plain  copy
 print ?
  1. public int setStation(int fd) {  
  2.     Log.d(TAG, "** Tune Using: "+fd);  
  3.     int ret = FmReceiverJNI.setFreqNative(fd, mFreq);  
  4.     Log.d(TAG, "** Returned: "+ret);  
  5.     return ret;  
  6.  }  

最后调用FmReceiverJNI类

setFreqNative(fd, mFreq); 本地方法 JNI到 cpp文件

[cpp]  view plain  copy
 print ?
  1. /*native interface */  
  2. static jint android_hardware_fmradio_FmReceiverJNI_setFreqNative  
  3.     (JNIEnv * env, jobject thiz, jint fd, jint freq)  
  4. {  
  5.     int err;  
  6.     double tune;  
  7.     struct v4l2_frequency freq_struct;  
  8.     freq_struct.type = V4L2_TUNER_RADIO;  
  9.     freq_struct.frequency = (freq*TUNE_MULT/1000);  
  10.     err = ioctl(fd, VIDIOC_S_FREQUENCY, &freq_struct);  
  11.     if(err < 0){  
  12.             return FM_JNI_FAILURE;  
  13.     }  
  14.     return FM_JNI_SUCCESS;  
  15. }  

你可能感兴趣的:(Radio)