mtk硬體啟動關閉藍牙功能的項目:mtk上層操作GPIO應用示例
項目要求:
接上篇:
1:藍牙按鍵(KCOL2+KROW1)長按3秒,軟體上控制GPIO144拉高2秒後關閉,藍牙就開啟并搜尋配對。同時拉高GPIO98,控制音頻的模拟開關切換藍牙音源。
2:藍牙在工作狀态下,給出個1.8V的高電平,給GPIO145用來檢測藍牙的工作狀态。
3:藍牙在工作裝态下想要重新配對,在長按藍牙按鍵3秒,控制GPIO97拉高3秒後關閉,藍牙子產品在收到這個信号後執行清空清單和重新搜尋功能。
4:藍牙按鍵(KCOL2+KROW1)長按8秒,軟體上控制GPIO144拉高2秒後關閉,藍牙子產品就關閉了。
本篇講述如何控制。
1, 設定藍牙控制GPIO為初始狀态,GPIO97 98 144全部設定為GPIOOUT,且下拉。GPIO145設定為GPIOIN。
2,偵測開機事件boot_completed,在這個intent處理程式中,檢查bt的switched的狀态,如果為//checked狀态,那麼打開藍牙,如果為非checked狀态,則不理會。
第一步,在AndroidManifest.xml中添加:
<receiverandroid:name="BootCompletedReceiver">
<intent-filter>
<actionandroid:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
不要忘記加入權限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
另外,接收BOOT_COMPLETED,不能安裝,必須直接push到/system/app/
在目前包下面建立BootCompletedReceiver.java檔案
我們定義兩個SharedPreferences來儲存系統的bt和ethernet狀态,因為省電需求,我們每次開機都保持Ethernet和BT為關閉。
packagecom.mediatek.oobe;
importandroid.app.Activity;
importandroid.content.BroadcastReceiver;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.content.SharedPreferences;
importandroid.util.Log;
publicclassBootCompletedReceiverextendsBroadcastReceiver {
@Override
publicvoidonReceive(Context mContext, Intent arg1) {
Log.e("zcfdebug","wewill set BT and ethernet default to off!");
SharedPreferencesbtSwitchSharedPreferences=mContext.getSharedPreferences("OOBE_Settings",Activity.MODE_PRIVATE);
SharedPreferences.EditormEditor=btSwitchSharedPreferences.edit();
mEditor.putString("btSwitch","0");
mEditor.putString("eth0Switch","0");
}
}
//在這個類裡面,我們要檢測藍牙的目前設定是否為開或者關。
3,我們打開圖形界面,顯示以太網卡開關和藍牙開關的時候,需要根據這裡的SharedPreferences來決定開關顯示狀态,這個需要在開關的Enable類的初始化完成:
在藍牙的BtEnabler類裡面增加三個私有成員
privateSharedPreferencesbtSwitchSharedPreferences;
privateStringbtSwitchStatusString;
privateSharedPreferences.EditormEditor;
在Enable類的初始化函數中間根據SharedPreferences的狀态設定UISwitch開關狀态。
publicBtEnabler(Context context, Preference switchPref) {
mContext= context;
mBtSwitchPre= (SwitchPreference) switchPref;
//mBtSwitchPre.setChecked(false);
booleanret= EmGpio.gpioInit();
btSwitchSharedPreferences=context.getSharedPreferences("OOBE_Settings",Activity.MODE_PRIVATE);
btSwitchStatusString=btSwitchSharedPreferences.getString("btSwitch",null);
mEditor=btSwitchSharedPreferences.edit();
if(btSwitchStatusString=="0"){
mBtSwitchPre.setChecked(false);
}elseif(btSwitchStatusString=="1"){
mBtSwitchPre.setChecked(true);
}else{
mBtSwitchPre.setChecked(false);
}
}
在使用者打開關閉藍牙的處理函數中間,進行SharedPreferences的設定
OnPreferenceChangeListenermBtPreferenceChangeListener=newOnPreferenceChangeListener() {
@Override
publicbooleanonPreferenceChange(Preference preference, Object newValue) {
//TODOAuto-generated method stub
booleanisChecked = (Boolean) newValue;
if(isChecked){
mEditor.putString("btSwitch","1");
}else{
mEditor.putString("btSwitch","0");
}
setBtEnable(isChecked);
}
returntrue;
}
};
對于以太網,因為其他程式也會進行設定,是以,這裡也是類似操作。
(注意,為了系統省電的操作,我們沒有使用系統所提供的EthernetManager的開關,而是直接關閉電源)
4,接收系統發出的android.intent.action.onkey.BT_START
第一步,在AndroidManifest.xml中添加:
<receiverandroid:name="BtStartReciver">
<intent-filter>
<actionandroid:name="android.intent.action.onkey.BT_START"/>
</intent-filter>
</receiver>
在目前包裡面建立BtStartReciver.java,内容如下
packagecom.mediatek.oobe;
importandroid.app.PendingIntent;
importandroid.content.BroadcastReceiver;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.util.Log;
public classBtStartReciver extends BroadcastReceiver {
@Override
public voidonReceive(Context mContext, Intent arg1) {
Log.e("zcfdebug","wewill set BT according preference!");
}
}
在這裡檔案裡,我們将按照項目要求,如果目前藍牙處于關的狀态,則打開藍牙。否則,不理會。
藍牙開關狀态儲存在設定界面中,而且第一次開機必須為關閉狀态。
首先我們讀取藍牙的SharedPreferences,判斷目前的BT是否為關閉狀态,如果是,那麼打開藍牙,并且更新SharedPreferences。代碼如下:
packagecom.mediatek.oobe;
importcom.mediatek.engineermode.io.EmGpio;
importandroid.app.Activity;
importandroid.app.PendingIntent;
importandroid.content.BroadcastReceiver;
importandroid.content.Context;
importandroid.content.Intent;
importandroid.content.SharedPreferences;
importandroid.util.Log;
publicclass BtStartReciver extends BroadcastReceiver {
privateSharedPreferences btSwitchSharedPreferences;
privateString btSwitchStatusString;
privateSharedPreferences.Editor mEditor;
@Override
publicvoid onReceive(Context mContext, Intent arg1) {
Log.e("zcfdebug","wewill set BT according preference!");
btSwitchSharedPreferences=mContext.getSharedPreferences("OOBE_Settings",Activity.MODE_PRIVATE);
btSwitchStatusString=btSwitchSharedPreferences.getString("btSwitch",null);
mEditor=btSwitchSharedPreferences.edit();
if(btSwitchStatusString=="0"){
// mBtSwitchPre.setChecked(false);
mEditor.putString("btSwitch","1");
setBtEnable(true);
}
}
privatevoid setBtEnable(boolean isChecked){
EmGpio.setGpioOutput(144);
EmGpio.setGpioOutput(98);
if(isChecked){
newThread(new Runnable() {
publicvoid run() {
Log.e("zcfdebug","weset GPIO 144 and 98 high");
EmGpio.setGpioDataHigh(144);
EmGpio.setGpioDataHigh(98);
Log.e("zcfdebug","wewill pull 144 2senconds");
try{
Thread.sleep(2000);
}catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
Log.e("zcfdebug","wewill pull 144 down");
EmGpio.setGpioDataLow(144);
}
}).start();
}else{
newThread(new Runnable() {
publicvoid run() {
Log.e("zcfdebug","weset GPIO 144 high and 98 low");
EmGpio.setGpioDataHigh(144);
EmGpio.setGpioDataLow(98);
Log.e("zcfdebug","wewill pull 144 2senconds");
try{
Thread.sleep(2000);
}catch (InterruptedException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
Log.e("zcfdebug","wewill pull 144 down");
EmGpio.setGpioDataLow(144);
}
}).start();
}
}
}
4,接收系統發出的android.intent.action.onkey.BT_STOP
與上面的Start方法一樣的,就不累述。
5,上面的GPIO操作才有的mtk提供的方式,jni方法內建在系統so檔案中libem_gpio_jni.so
其接口代碼如下EmGpio.java:
packagecom.mediatek.engineermode.io;
publicclass EmGpio {
publicstatic native int getGpioMaxNumber();
publicstatic native boolean gpioInit();
publicstatic native boolean gpioUnInit();
publicstatic native boolean setGpioInput(int gpioIndex);
publicstatic native boolean setGpioOutput(int gpioIndex);
publicstatic native boolean setGpioDataHigh(int gpioIndex);
publicstatic native boolean setGpioDataLow(int gpioIndex);
publicstatic native int getCurrent(int hostNumber);
publicstatic native int newGetCurrent(int hostNumber, int opcode);
publicstatic native boolean setCurrent(int hostNumber, int currentDataIdx,
intcurrentCmdIdx);
publicstatic native boolean newSetCurrent(int hostNumber, int clkpu,
intclkpd, int cmdpu, int cmdpd, int datapu, int datapd,
inthopbit, int hoptime, int opcode);
publicstatic native boolean setSd30Mode(int hostNumber, int sd30Mode,
intsd30MaxCurrent, int sd30Drive, int sd30PowerControl);
static{
System.loadLibrary("em_gpio_jni");
}
}
注意:路徑和類名不能修改。
下面調試及可。