安裝和卸載SD卡,通過usb和電腦建立或者斷開連接,手機開機這些情況都是系統(tǒng)中比較重要的事件,我們很可能在這些事件發(fā)生的時候需要做某些事情。比如說在手機開機的時候自動運行某個服務(wù),安裝SD卡的時候刪除一些沒有的文件等等。那怎么樣才能獲取到這些事件呢?我們知道在android系統(tǒng)中很多信息的傳輸是通過broadcast來實現(xiàn)的,那么能不能也用BroadCastReceiver來獲取到這些事件呢?答案是肯定的。 1.對于開機事件,可以通過接收Intent.ACTION_BOOT_COMPLETED廣播來獲取。手機在啟動完畢后,會發(fā)出這個廣播,這也是這個廣播唯一的發(fā)送方。但是需要注意的是要接收這個廣播必須在Manifest文件中注冊權(quán)限。
2.對于安裝和卸載SD卡的事件,可以通過接收Intent.ACTION_MEDIA_MOUNTED和Intent.ACTION_MEDIA_UNMOUNTED廣播來獲取。這個在網(wǎng)上已經(jīng)有不少的相關(guān)文章了,需要注意的就是需要加入DataScheme才能正確地接收廣播。
3.對于USB的連接事件,我在網(wǎng)上找了找,發(fā)現(xiàn)基本沒有這方面的文章。通過分析USB連接時的log文件,我發(fā)現(xiàn)在這個事件發(fā)生的時候會出來相應(yīng)的log信息,分別是01-09 02:50:07.308: DEBUG/Vold(104): USB disconnected和01-09 02:50:07.589: DEBUG/Vold(104): USB connected。但是在源碼中搜索“Vold”這個關(guān)鍵詞卻并沒有結(jié)果,進入adb shell后使用ps命令查看運行的進程,104號進程是system/bin/vold進程,屬于底層的服務(wù),想要參考這部分代碼的實現(xiàn)恐怕就沒那么容易了。查看了一下Intent的成員中并沒有這方面的內(nèi)容,那這個事件到底要怎么獲取才行呢?最后我發(fā)現(xiàn)原來在android系統(tǒng)中已經(jīng)有了一個USB.java的類,可以處理相關(guān)的事件,但是這個類好像是比較新的SDK才會有。 現(xiàn)在知道如果獲取這些事件了,那實現(xiàn)上就簡單得多了,我實現(xiàn)了一個簡單的例子,可以做一下參考。
1.首先創(chuàng)建android工程BroadCastReceverTest,包名為com.test。這個工程并不需要創(chuàng)建Activity。
2.創(chuàng)建新類BootReceiver.java,用于接收手機的啟動廣播。前面已經(jīng)說過了,接收這個廣播需要注冊權(quán)限,具體見Manifest文件。
- package com.test;
-
-
import android.content.BroadcastReceiver;
-
import android.content.Context;
-
import android.content.Intent;
-
import android.util.Log;
-
-
/**
-
* Receiver for receiving boot event. When boot completed, it will start the
-
* service for receiving Usb connect and SDcard events.
-
*
-
*/
-
public class BootReceiver extends BroadcastReceiver {
-
private static final String TAG = "BroadCastTest";
-
public void onReceive(Context context, Intent intent) {
-
// Log.d(TAG, intent.getAction());
-
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
-
Log.d(TAG, "Received phone Boot Event!");
-
Intent mintent=new Intent("com.test.dirStartService");
-
Log.d(TAG,"auto startservice");
-
context.startService(mintent);
-
}
-
}
-
-
}
我們可以看到這個類繼承了BroadcastReceiver,在收到Intent.ACTION_BOOT_COMPLETED廣播后會輸出log信息,并啟動一個服務(wù),在這個服務(wù)中將接收SD卡和USB的事件。
2.創(chuàng)建服務(wù)類dirtStartService.java。在這個服務(wù)中創(chuàng)建了一個BroadcastReceiver,并為其注冊SD卡和USB的事件。在收到這些事件后,會輸出log信息。
- package com.test;
-
-
import android.app.Service;
-
import android.content.BroadcastReceiver;
-
import android.content.Context;
-
import android.content.Intent;
-
import android.content.IntentFilter;
-
import android.hardware.Usb;
-
import android.os.IBinder;
-
import android.util.Log;
-
-
/**
-
* Service for receiving Usb connect and SDcard events.
-
*
-
*/
-
-
public class dirtStartService extends Service {
-
private static final String TAG = "BroadCastTest";
-
-
BroadcastReceiver mReceiver;
-
-
@Override
-
public IBinder onBind(Intent intent) {
-
return null;
-
}
-
-
public void onCreate() {
-
super.onCreate();
-
Log.d(TAG, "oncreate");
-
}
-
-
public void onStart(Intent intent, int startId) {
-
Log.d(TAG, "onstart");
-
mReceiver = new BroadcastReceiver() {
-
public void onReceive(Context context, Intent intent) {
-
// Log.d(TAG, intent.getAction());
-
if (intent.getAction().equals(Intent.ACTION_MEDIA_MOUNTED)) {
-
Log.d(TAG, "Received SDCard Mount Event!");
-
} else if (intent.getAction().equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
-
Log.d(TAG, "Received SDCard UnMount Event!");
-
}else if (intent.getAction().equals(Usb.ACTION_USB_STATE)) {
-
boolean connected = intent.getExtras().getBoolean(Usb.USB_CONNECTED);
-
Log.d(TAG,"Received Usb event, Usb connect status is:"+connected);
-
}
-
}
-
};
-
// Fileter for SDCard mounted and unmounted
-
IntentFilter filterSDCard = new IntentFilter();
-
filterSDCard.addAction(Intent.ACTION_MEDIA_MOUNTED);
-
filterSDCard.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
-
// must add so the receiver can receive the SD card mount and unmount
-
// event
-
filterSDCard.addDataScheme("file");
-
registerReceiver(mReceiver, filterSDCard);
-
-
//Filter for usb connect
-
IntentFilter filter = new IntentFilter();
-
filter.addAction(Usb.ACTION_USB_STATE);
-
registerReceiver(mReceiver, filter);
-
-
}
-
}
3. 此外就是Manifest文件,對于手機啟動的廣播也是在Manifest文件中注冊的。
- <?xml version="1.0" encoding="utf-8"?>
-
<manifest
-
xmlns:android="http://schemas.android.com/apk/res/android"
-
package="com.test"
-
android:versionCode="1"
-
android:versionName="1.0">
-
<application
-
android:icon="@drawable/icon"
-
android:label="@string/app_name">
-
-
<service
-
android:enabled="true"
-
android:name=".dirtStartService">
-
<intent-filter>
-
<action
-
android:name="com.test.dirStartService"></action>
-
</intent-filter>
-
</service>
-
-
<receiver
-
android:name="com.test.BootReceiver">
-
<intent-filter>
-
<action
-
android:name="android.intent.action.BOOT_COMPLETED">
-
</action>
-
<category
-
android:name="android.intent.category.HOME">
-
</category>
-
</intent-filter>
-
</receiver>
-
</application>
-
<uses-sdk
-
android:minSdkVersion="7" />
-
</manifest>
需要注意的是USB.java類是不包含在android.jar中的,需要為工程引入外部包framework.jar才能正確運行程序。
對于程序的運行要首先將程序安裝到手機上,然后重新啟動手機,重啟后程序會收到的啟動事件并啟動服務(wù),這個時候如果進行USB的連接和斷開以及SD卡的加載和卸載操作服務(wù)都會收到廣播,并輸出log信息。輸出的信息如下圖所示:
|