Service: 监听外部存储设备

有奖征资源,博文分享有内涵         4月推荐博文汇总          CSDN博客支持Windows Live Writer离线写博客啦

Service: 监听外部存储设备

分类: Android 技术笔记 2495人阅读 评论(0) 收藏 举报
service 存储 action string path 测试

博客声明:


1. 使用 android2.1 源码说明问题


2. 使用真机,操作系统是 android-2.1


3. 分享一下学习方法,不是为了测试而测试,请大家举一反三


结合 Service 与 Broadcast 监听外部存储设备的状态,通过测试主要想知道在我们操作外部存储设备时候发生了哪些事情、以及 Intent 几个 Action 到底是何意?


测试代码见 附录,至于如何启动这个 Service,随您意!


主要的 Action 


                                 



注册这 13 个 action,然后运行 app ,点击 back 服务退至后台。


now,ready!来操作 sdcard。


1.  直接拔掉 sdcard



2.  再次将 sdcard 插入卡槽





先大概 1-3 秒的 media checking,然后才是 mounted -- scanner started -- scanner finished


3.  在通知栏卸载 sdcard





紧接着,从卡槽拔出 sdcard(必须拔出,才会接收到下面的 action)




可以看出,这种情况属于正常卸载 sdcard,不是强制拔出。不同于 1.


这个时候,你将 sdcard 插入卡槽,发生的情况与 2 一致。



4. 在通知栏选择 "计算机与 sd 卡之间复制文件",即共享


在弹出的对话框选择 "装载"




然后,我们再次在通知栏选择 "关闭 usb 存储设备",接下来发生的与 2 一致。



从这几个测试,我们可以发现几个规律:


1.  不管以何种方式卸载(正常卸载拔出、正常卸载不拔出 sd 卡、直接拔出 sd 卡


系统都会发出下面的 action 广播


ACTION_MEDIA_EJECT


ACTION_MEDIA_UNMOUNTED



2.  不管以何种方式安装 sd 卡,系统都会发出下面的 action 广播




3.  ACTION_MEDIA_REMOVED 与 ACTION_MEDIA_UNMOUNTED 区别



ACTION_MEDIA_REMOVED 


表示 sdcard 已经从卡槽移除。


ACTION_MEDIA_UNMOUNTED 


只可以说明 sd 卡没有 mount 在文件系统上面,不可以说明其已经从卡槽移除。


从测试 4 就可以看出这个端倪。



4.  ACTION_MEDIA_REMOVED 与 ACTION_MEDIA_BAD_REMOVAL 区别



ACTION_MEDIA_BAD_REMOVAL 


只有在直接拔出 sd 卡时,系统才会发送这样的 action 广播。


ACTION_MEDIA_REMOVED 


不管何种方式从卡槽拔出 sd 卡时,系统就会发送这样的 action 广播。



5.  选择通过 usb 共享,系统一定会发出下面的 action 广播


ACTION_MEDIA_SHARED



ok,明白上面的道理(你基于的开发平台是否是这样,你还需要测试,我这里只是抛砖引玉),可以在接收到这些广播的时候,根据 action 写自己的逻辑代码了。如:


[java] view plain copy print ?
  1.        @Override  
  2. public void onReceive(Context context, Intent intent) {  
  3.     final String action = intent.getAction();  
  4.     if (Intent.ACTION_MEDIA_EJECT.equals(action)) {  
  5.         // 本人感觉 ACTION_MEDIA_EJECT 比  
  6.         //  ACTION_MEDIA_UNMOUNTED 好  
  7.           
  8.         // sd 卡不可用  
  9.     } else if (Intent.ACTION_MEDIA_REMOVED.equals(action)) {  
  10.         // sd 卡已经被移除卡槽  
  11.     } else if (Intent.ACTION_MEDIA_SHARED.equals(action)) {  
  12.         // 选择通过 usb 共享  
  13.     } else if (Intent.ACTION_MEDIA_MOUNTED.equals(action)) {  
  14.         // sd 卡可用  
  15.     }  
  16. }  

但是这里提醒一下:


接收到 ACTION_MEDIA_EJECT 广播之后,sd 卡还是可以读写的,

直到接收到 ACTION_MEDIA_REMOVED、ACTION_MEDIA_UNMOUNTED等广播之后,sd 卡才不可以读写。

可以借助 Music 源码 MediaPlaybackService.java 看看:


[java] view plain copy print ?
  1. @Override  
  2. public void onReceive(Context context, Intent intent) {  
  3.     String action = intent.getAction();  
  4.     if (action.equals(Intent.ACTION_MEDIA_EJECT)) {  
  5.         saveQueue(true);  
  6.         mQueueIsSaveable = false;  
  7.         closeExternalStorageFiles(intent.getData().getPath());  
  8.     } else if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {  
  9.         mMediaMountedCount++;  
  10.         mCardId = MusicUtils.getCardId(MediaPlaybackService.this);  
  11.         reloadQueue();  
  12.         mQueueIsSaveable = true;  
  13.         notifyChange(QUEUE_CHANGED);  
  14.         notifyChange(META_CHANGED);  
  15.     }  
  16. }  


到这个时候,我们应该搞明白是系统哪个类发出这样的广播?有没有新的发现?


android2.1/frameworks/base/services/java/com/android/server/MountService.java


与其相关的类是


android2.1/frameworks/base/services/java/com/android/server/MountListener.java


继续跟踪 MountService.java , 我们会发现实例化 intent:


intent = new Intent(Intent.ACTION_MEDIA_SHARED, Uri.parse("file://" + path));


都包含一个 scheme 为 file 的 path,那麽这个 path 是什么呢?


可以在 onReceive 方法里面得到这个值


final String path = intent.getData().getPath()


其实,就是 "/sdcard" (即 sd 卡路径)。


这个信息很有用!!!


比如你的手机可以外括除了 sd 卡的其它外部设备(如 u 盘、map 卡)

那麽这个返回的路径就不一样,可以根据返回的路径判断你当前操作的是哪个设备了!


耶耶,酷比嘞!


在 MountService.java 里面还有一个与众不同的地方:


[java] view plain copy print ?
  1. void notifyMediaMounted(String path, boolean readOnly) {  
  2.         setMediaStorageNotification(000falsefalsenull);  
  3.         updateUsbMassStorageNotification(falsefalse);  
  4.         Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED,   
  5.                 Uri.parse("file://" + path));  
  6.         intent.putExtra("read-only", readOnly);  
  7.         mMounted = true;  
  8.         mContext.sendBroadcast(intent);  
  9. }  


 intent.putExtra("read-only", readOnly)


其中 readOnly 是一个 boolean 值,在 onReceive 里面 只有 action 是 ACTION_MEDIA_MOUNTED,接收到该值是 false.





------------- 附录 


PlayerService.java


[java] view plain copy print ?
  1. package mark.zhang;  
  2.   
  3. import android.app.Service;  
  4. import android.content.BroadcastReceiver;  
  5. import android.content.Context;  
  6. import android.content.Intent;  
  7. import android.content.IntentFilter;  
  8. import android.os.IBinder;  
  9. import android.util.Log;  
  10.   
  11. public class PlayerService extends Service {  
  12.     private static final String TAG = "PlayerService";  
  13.   
  14.     @Override  
  15.     public IBinder onBind(Intent intent) {  
  16.         return null;  
  17.     }  
  18.   
  19.     @Override  
  20.     public void onCreate() {  
  21.         super.onCreate();  
  22.         registerReceivers();  
  23.     }  
  24.   
  25.     @Override  
  26.     public int onStartCommand(Intent intent, int flags, int startId) {  
  27.         return super.onStartCommand(intent, flags, startId);  
  28.     }  
  29.   
  30.     @Override  
  31.     public void onDestroy() {  
  32.         Log.d(TAG, "onDestroy------");  
  33.         super.onDestroy();  
  34.         unregisterReceivers();  
  35.     }  
  36.   
  37.     private BroadcastReceiver externalStorageReceiver = null;  
  38.   
  39.     /** 
  40.      * 注册广播 
  41.      */  
  42.     private void registerReceivers() {  
  43.         if (externalStorageReceiver == null) {  
  44.             externalStorageReceiver = new BroadcastReceiver() {  
  45.   
  46.                 @Override  
  47.                 public void onReceive(Context context, Intent intent) {  
  48.                     final String action = intent.getAction();  
  49.                     final String path = intent.getData().getPath();  
  50.                     Log.d(TAG, "receive action = " + action);  
  51.                     boolean value = intent.getBooleanExtra("read-only"true);  
  52.                     Log.d(TAG, "external storage path = " + path);  
  53.                     Log.d(TAG, "external storage value = " + value);  
  54.                 }  
  55.             };  
  56.   
  57.             final IntentFilter filter = new IntentFilter();  
  58.             filter.addAction(Intent.ACTION_MEDIA_BAD_REMOVAL);  
  59.             filter.addAction(Intent.ACTION_MEDIA_BUTTON);  
  60.             filter.addAction(Intent.ACTION_MEDIA_CHECKING);  
  61.             filter.addAction(Intent.ACTION_MEDIA_EJECT);  
  62.             filter.addAction(Intent.ACTION_MEDIA_MOUNTED);  
  63.             filter.addAction(Intent.ACTION_MEDIA_NOFS);  
  64.             filter.addAction(Intent.ACTION_MEDIA_REMOVED);  
  65.             filter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);  
  66.             filter.addAction(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);  
  67.             filter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);  
  68.             filter.addAction(Intent.ACTION_MEDIA_SHARED);  
  69.             filter.addAction(Intent.ACTION_MEDIA_UNMOUNTABLE);  
  70.             filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);  
  71.             // 必须添加,否则无法接收到广播  
  72.             filter.addDataScheme("file");  
  73.   
  74.             registerReceiver(externalStorageReceiver, filter);  
  75.         }  
  76.     }  
  77.   
  78.     /** 
  79.      * 取消注册 
  80.      */  
  81.     private void unregisterReceivers() {  
  82.         if (externalStorageReceiver != null) {  
  83.             unregisterReceiver(externalStorageReceiver);  
  84.             externalStorageReceiver = null;  
  85.         }  
  86.     }  
  87.   
  88. }  









更多 0
5
0
主题推荐
存储 broadcastreceiver 文件系统 操作系统 frameworks
猜你在找
MediaScanner与音乐信息扫描==
android 修改默认时间为24小时格式
Android OOM ,回收布局文件中ImageView占用的内存.Bitmap OOM回收解决.
切换音效会导致有杂音
jquery 漂浮广告
JNI: Get/ReleaseStringUTFChars和Get/ReleaseIntArrayElements的区别,isCopy是否重新分配内存的问题
Tabhost里面的Activity刷新问题--(Activity生命周期)
Android中的RefBase,sp和wp
libjpeg 详解
Android程序 依赖库引用Gson 报java.lang.NoClassDefFoundError: com/google/gson/Gson 解决方法
查看评论

  暂无评论

* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
核心技术类目
全部主题 Java VPN Android iOS ERP IE10 Eclipse CRM JavaScript Ubuntu NFC WAP jQuery 数据库 BI HTML5 Spring Apache Hadoop .NET API HTML SDK IIS Fedora XML LBS Unity Splashtop UML components Windows Mobile Rails QEMU KDE Cassandra CloudStack FTC coremail OPhone CouchBase 云计算 iOS6 Rackspace Web App SpringSide Maemo Compuware 大数据 aptech Perl Tornado Ruby Hibernate ThinkPHP Spark HBase Pure Solr Angular Cloud Foundry Redis Scala Django Bootstrap
个人资料
Service: 监听外部存储设备_第1张图片
verycool
  • 访问:396307次
  • 积分:7280分
  • 排名:第695名
  • 原创:215篇
  • 转载:13篇
  • 译文:2篇
  • 评论:375条
文章分类
  • OpenSource(6)
  • Refactoring/Pattern(5)
  • Android 技术笔记(49)
  • Android packages/app(4)
  • Android View/UI(26)
  • Android 系统专题(15)
  • Algorithm(7)
  • linux/ubuntu(21)
  • JavaSE(46)
  • C/C++(5)
  • database(13)
  • WEB开发(7)
  • 7上8下(18)
  • FAQ(24)
评论排行
  • Handler:更新UI的方法(28)
  • Handler: 主线程如何通知子线程(24)
  • UI效果(5): 实现Activity刷新(17)
  • 情结- WiFi 直连(17)
  • Handler: Activity 之间通过 Handler 通信(15)
  • Java基础:IO 流中的 flush(14)
  • View编程(3): invalidate()源码分析(13)
  • 注意身体(12)
  • View编程(1): Window、View与setContentView()(11)
  • MySQL: 基于 android 远程连接(10)
阅读排行
  • Handler:更新UI的方法(16289)
  • UI效果(5): 实现Activity刷新(10687)
  • Handler: 主线程如何通知子线程(9169)
  • Spinner(3): OnItemSelectedListener 触发时机(9104)
  • network: android 使用广播监听网络状态(8530)
  • adb:) adb install(7529)
  • Handler: Activity 之间通过 Handler 通信(7403)
  • FAQ_07_android:clickable 问题(6840)
  • adb:) adb push、pull、logcat and etc(6156)
  • Java基础:IO 流中的 flush(6001)
推荐文章

公司简介| 招贤纳士| 广告服务| 银行汇款帐号| 联系方式| 版权声明| 法律顾问| 问题报告| 合作伙伴| 论坛反馈
网站客服 杂志客服 微博客服 [email protected] 400-600-2320
京 ICP 证 070598 号
北京创新乐知信息技术有限公司 版权所有
江苏乐知网络技术有限公司 提供商务支持
Copyright © 1999-2014, CSDN.NET, All Rights Reserved  GongshangLogo

你可能感兴趣的:(Android,Music)