通过BroadcastReceiver获取SDcard,Usb连接和开机事件
2015-11-26 15:04
417 查看
安装和卸载SD卡,通过usb和电脑建立或者断开连接,手机开机这些情况都是系统中比较重要的事件,我们很可能在这些事件发生的时候需要做某些事情。比如说在手机开机的时候自动运行某个服务,安装SD卡的时候删除一些没有的文件等等。那怎么样才能获取到这些事件呢?我们知道在android系统中很多信息的传输是通过broadcast来实现的,那么能不能也用BroadCastReceiver来获取到这些事件呢?答案是肯定的。
1.对于开机事件,可以通过接收Intent.ACTION_BOOT_COMPLETED广播来获取。手机在启动完毕后,会发出这个广播,这也是这个广播唯一的发送方。但是需要注意的是要接收这个广播必须在Manifest文件中注册权限。
2.对于安装和卸载SD卡的事件,可以通过接收Intent.ACTION_MEDIA_MOUNTED和Intent.ACTION_MEDIA_UNMOUNTED广播来获取。这个在网上已经有不少的相关文章了,需要注意的就是需要加入DataScheme才能正确地接收广播。
3.对于USB的连接事件,我在网上找了找,发现基本没有这方面的文章。通过分析USB连接时的log文件,我发现在这个事件发生的时候会出来相应的log信息,分别是01-09 02:50:07.308: DEBUG/Vold(104): USB disconnected和01-09 02:50:07.589: DEBUG/Vold(104):
USB connected。但是在源码中搜索“Vold”这个关键词却并没有结果,进入adb shell后使用ps命令查看运行的进程,104号进程是system/bin/vold进程,属于底层的服务,想要参考这部分代码的实现恐怕就没那么容易了。查看了一下Intent的成员中并没有这方面的内容,那这个事件到底要怎么获取才行呢?最后我发现原来在android系统中已经有了一个USB.java的类,可以处理相关的事件,但是这个类好像是比较新的SDK才会有。
现在知道如果获取这些事件了,那实现上就简单得多了,我实现了一个简单的例子,可以做一下参考。
1.首先创建android工程BroadCastReceverTest,包名为com.test。这个工程并不需要创建Activity。
2.创建新类BootReceiver.java,用于接收手机的启动广播。前面已经说过了,接收这个广播需要注册权限,具体见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信息,并启动一个服务,在这个服务中将接收SD卡和USB的事件。
2.创建服务类dirtStartService.java。在这个服务中创建了一个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才能正确运行程序。
对于程序的运行要首先将程序安装到手机上,然后重新启动手机,重启后程序会收到的启动事件并启动服务,这个时候如果进行USB的连接和断开以及SD卡的加载和卸载操作服务都会收到广播,并输出log信息。输出的信息如下图所示:
1.对于开机事件,可以通过接收Intent.ACTION_BOOT_COMPLETED广播来获取。手机在启动完毕后,会发出这个广播,这也是这个广播唯一的发送方。但是需要注意的是要接收这个广播必须在Manifest文件中注册权限。
2.对于安装和卸载SD卡的事件,可以通过接收Intent.ACTION_MEDIA_MOUNTED和Intent.ACTION_MEDIA_UNMOUNTED广播来获取。这个在网上已经有不少的相关文章了,需要注意的就是需要加入DataScheme才能正确地接收广播。
3.对于USB的连接事件,我在网上找了找,发现基本没有这方面的文章。通过分析USB连接时的log文件,我发现在这个事件发生的时候会出来相应的log信息,分别是01-09 02:50:07.308: DEBUG/Vold(104): USB disconnected和01-09 02:50:07.589: DEBUG/Vold(104):
USB connected。但是在源码中搜索“Vold”这个关键词却并没有结果,进入adb shell后使用ps命令查看运行的进程,104号进程是system/bin/vold进程,属于底层的服务,想要参考这部分代码的实现恐怕就没那么容易了。查看了一下Intent的成员中并没有这方面的内容,那这个事件到底要怎么获取才行呢?最后我发现原来在android系统中已经有了一个USB.java的类,可以处理相关的事件,但是这个类好像是比较新的SDK才会有。
现在知道如果获取这些事件了,那实现上就简单得多了,我实现了一个简单的例子,可以做一下参考。
1.首先创建android工程BroadCastReceverTest,包名为com.test。这个工程并不需要创建Activity。
2.创建新类BootReceiver.java,用于接收手机的启动广播。前面已经说过了,接收这个广播需要注册权限,具体见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信息,并启动一个服务,在这个服务中将接收SD卡和USB的事件。
2.创建服务类dirtStartService.java。在这个服务中创建了一个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才能正确运行程序。
对于程序的运行要首先将程序安装到手机上,然后重新启动手机,重启后程序会收到的启动事件并启动服务,这个时候如果进行USB的连接和断开以及SD卡的加载和卸载操作服务都会收到广播,并输出log信息。输出的信息如下图所示:
相关文章推荐
- 转发与重定向
- HTTP头部详解
- 链表实现栈、队列
- [LeetCode]Minimum Height Trees
- [国嵌攻略][065][DM9000驱动程序设计]
- 终于解决了IE8不支持数组的indexOf方法,array的IndexOf方法
- SqlSessionDaoSupport与SqlSessionTemplate对比
- 程序优化——位运算
- php Spl的常用函数 链式操作
- Mongodb索引分析工具Dex 安装与使用
- 将DataGridVIew数据导出到Excel中的两种方法
- 让程序在远程主机后台运行 (&、nohuo、 screen)Linux 使用技巧
- php 一致性hash
- java读取xml文件
- LeetCode()Minimum Window Substring 超时,但觉得很清晰。
- (c++) int 转 string,char*,const char*和string的相互转换
- 在Java的Struts框架下进行web编程的入门教程
- mongo 集群时间不同步异常
- swift学习笔记-3
- adb shell 命令