Android

Android通过.nomedia文件禁止多媒体库扫描指定文件夹下的多媒体文件 Android应用内存泄露分析、改善经验总结 修改Eclipse导入项目的默认工程名 自定义Android Studio工程模板 使用Nexus Repository搭建属于自己公司的私有maven服务器 Android Studio编译过程中mergeDebugResources时报“png-cruncher_*”异常的解决方案 Eclipse转Android Studio的过程中有必要弄明白的一些问题 Android开发经验总结 Android Studio使用过程中遇到的一些问题及解决方案 Android各个Support Library介绍 调用AsyncTask的excute方法不能立即执行程序的原因分析及改善方案 提升进入界面的速度 使用软引用解决Handler内存泄露和显示Popupwindow、Dialog时提示"Unable to add Window-token is null"的问题 SharedPreferences在多进程中的使用及注意事项 Android性能测试工具列表 Android View双缓冲绘制时清除Bitmap上的内容的方法 解决JPinyin在APK被加密后不能正常使用的问题 Android APP内存优化之图片优化 Android EditText的使用及值得注意的地方 Android应用内多进程的使用及注意事项 Android设置应用内文字的默认颜色和大小 关于APK瘦身值得分享的一些经验 Android通过ClipDrawable实现图片裁剪功能 Android通过广播更新文件和文件夹到媒体库 每个Android开发者都应该了解的资源列表 selector的使用方法及注意事项 通过批处理批量clone代码 Android清除数据、清除缓存、一键清理的区别 Android将数据库保存到SD卡的实现 Android多分辨率适配经验总结 通过观察者模式监听媒体库的变化实现APP本地数据自动更新 Android ADB命令大全(通过ADB命令查看wifi密码、MAC地址、设备信息、操作文件、查看文件、日志信息、卸载、启动和安装APK等) Android通过ADB查看wifi密码 Android一个APK多个入口(多个桌面图标)的实现 使用Python脚本批量卸载第三方应用和清除log缓存 Android CheckList Android模仿打字机效果的自定义View实现 在Activity的onCreate方法中显示PopupWindow导致异常的原因分析及解决方案 Android手写优化-更为平滑的签名效果实现 Android手写优化-平滑的签名效果实现 不要在Android的Application对象中缓存数据! 大量Android面试题目来袭 一种不需要Google账号、不需要关联手机、不需要在手机上安装Google的服务直接能够下载Google Play上APK的方法 在Android library中不能使用switch-case语句访问资源ID的原因分析及解决方案 Android程序和数据分离的实现方案 按Home按键退出应用后重新启动该应用无法返回到最后打开页面的解决方案 Eclipse下Android项目不能生成R.java的解决方法汇总 android:descendantFocusability属性在ListView中的妙用 去掉SrollView、GrdiView、ListView、ViewPager等滑动到边缘的光晕效果 Android开发经验谈-Eclipse使用技巧 Android开发经验谈-很少有人会告诉你的Android开发基本常识 Android开发经验谈-Android工程目录介绍 在Android的string.xml中使用转义字符实现想要的显示效果 修改ViewPager调用setCurrentItem时,滑屏的速度 Android监听Home按键消息 Android手写开源项目和资料搜集 Android通过资源文件名获取资源ID Android中Bitmap、Drawable、bytes数组之间相互转换 想过但未实现的一些Idea 读写文件编码方式不一致导致文件乱码的解决方案 Android字符串格式化开源库phrase介绍 Android实现带箭头的自定义Progressbar Android模拟键盘输入功能的实现 与Android应用程序相关的各种文件存储路径介绍 Android开发者网址导航

标签

Android 65

Android通过.nomedia文件禁止多媒体库扫描指定文件夹下的多媒体文件 Android应用内存泄露分析、改善经验总结 修改Eclipse导入项目的默认工程名 自定义Android Studio工程模板 使用Nexus Repository搭建属于自己公司的私有maven服务器 Android Studio编译过程中mergeDebugResources时报“png-cruncher_*”异常的解决方案 Eclipse转Android Studio的过程中有必要弄明白的一些问题 Android开发经验总结 Android Studio使用过程中遇到的一些问题及解决方案 Android各个Support Library介绍 调用AsyncTask的excute方法不能立即执行程序的原因分析及改善方案 提升进入界面的速度 使用软引用解决Handler内存泄露和显示Popupwindow、Dialog时提示"Unable to add Window-token is null"的问题 SharedPreferences在多进程中的使用及注意事项 Android性能测试工具列表 Android View双缓冲绘制时清除Bitmap上的内容的方法 解决JPinyin在APK被加密后不能正常使用的问题 Android APP内存优化之图片优化 Android EditText的使用及值得注意的地方 Android应用内多进程的使用及注意事项 Android设置应用内文字的默认颜色和大小 关于APK瘦身值得分享的一些经验 Android通过ClipDrawable实现图片裁剪功能 Android通过广播更新文件和文件夹到媒体库 每个Android开发者都应该了解的资源列表 selector的使用方法及注意事项 通过批处理批量clone代码 Android清除数据、清除缓存、一键清理的区别 Android将数据库保存到SD卡的实现 Android多分辨率适配经验总结 通过观察者模式监听媒体库的变化实现APP本地数据自动更新 Android ADB命令大全(通过ADB命令查看wifi密码、MAC地址、设备信息、操作文件、查看文件、日志信息、卸载、启动和安装APK等) Android通过ADB查看wifi密码 Android一个APK多个入口(多个桌面图标)的实现 使用Python脚本批量卸载第三方应用和清除log缓存 Android CheckList Android模仿打字机效果的自定义View实现 在Activity的onCreate方法中显示PopupWindow导致异常的原因分析及解决方案 Android手写优化-更为平滑的签名效果实现 Android手写优化-平滑的签名效果实现 不要在Android的Application对象中缓存数据! 大量Android面试题目来袭 一种不需要Google账号、不需要关联手机、不需要在手机上安装Google的服务直接能够下载Google Play上APK的方法 在Android library中不能使用switch-case语句访问资源ID的原因分析及解决方案 Android程序和数据分离的实现方案 按Home按键退出应用后重新启动该应用无法返回到最后打开页面的解决方案 Eclipse下Android项目不能生成R.java的解决方法汇总 android:descendantFocusability属性在ListView中的妙用 去掉SrollView、GrdiView、ListView、ViewPager等滑动到边缘的光晕效果 Android开发经验谈-Eclipse使用技巧 Android开发经验谈-很少有人会告诉你的Android开发基本常识 Android开发经验谈-Android工程目录介绍 在Android的string.xml中使用转义字符实现想要的显示效果 修改ViewPager调用setCurrentItem时,滑屏的速度 Android监听Home按键消息 Android手写开源项目和资料搜集 Android通过资源文件名获取资源ID Android中Bitmap、Drawable、bytes数组之间相互转换 想过但未实现的一些Idea 读写文件编码方式不一致导致文件乱码的解决方案 Android字符串格式化开源库phrase介绍 Android实现带箭头的自定义Progressbar Android模拟键盘输入功能的实现 与Android应用程序相关的各种文件存储路径介绍 Android开发者网址导航

Android通过广播更新文件和文件夹到媒体库

2015年03月28日

Android媒体库

  Android的媒体库其实就是一个数据库文件,当系统启动完成、SD卡插拔或者接收到“Intent.ACTION_MEDIA_SCANNER_SCAN_FILE”广播消息时,系统会扫描文件系统中的数据,将新增和删除的文件信息更新到这个数据库中,这样当其它程序获取文件系统中的文件信息时,直接操作这个数据库就行了,不用去文件系统中取,接收媒体库扫描广播和触发扫描文件系统的源码如下:

	public class MediaScannerReceiver extends BroadcastReceiver {
    private final static String TAG = "MediaScannerReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        final Uri uri = intent.getData();
        if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
            // Scan both internal and external storage
            scan(context, MediaProvider.INTERNAL_VOLUME);
            scan(context, MediaProvider.EXTERNAL_VOLUME);

        } else {
            if (uri.getScheme().equals("file")) {
                // handle intents related to external storage
                String path = uri.getPath();
                String externalStoragePath = Environment.getExternalStorageDirectory().getPath();

                Log.d(TAG, "action: " + action + " path: " + path);
                if (Intent.ACTION_MEDIA_MOUNTED.equals(action)) {
                    // scan whenever any volume is mounted
                    scan(context, MediaProvider.EXTERNAL_VOLUME);
                } else if (Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action) &&
                        path != null && path.startsWith(externalStoragePath + "/")) {
                    scanFile(context, path);
                }
            }
        }
    }

    private void scan(Context context, String volume) {
        Bundle args = new Bundle();
        args.putString("volume", volume);
        context.startService(
                new Intent(context, MediaScannerService.class).putExtras(args));
    }    

    private void scanFile(Context context, String path) {
        Bundle args = new Bundle();
        args.putString("filepath", path);
        context.startService(
                new Intent(context, MediaScannerService.class).putExtras(args));
    }    

获取媒体库中指定文件格式的文件列表

  这个过程其实就是查询数据库,具体实现如下:

	/**
     * 获取指定文件列表的全路径,如果对应文件存在则返回文件的路径,如果对应文件不存在,则路径为空
     * eg:
     * List<String> filePathList = FileUtils.getExistFiles(this,new String[]{"1.ptr","2.hst","3.dct"});
     * 如果1.ptr和3.dct存在,2.hst不存在则返回的结果是:
     * filePathList.get(0) = /mnt/sdcard/1.ptr
     * filePathList.get(1) = null
     * filePathList.get(2) = /mnt/sdcard/3.dct
     * */
    public static List<String> getExistFiles(final Context context, final String[] fileNames){
    	if( null == context || null == fileNames || fileNames.length == 0 ){
            return null;
        }

    	
    	String filePath = null;
		String suffix = null;
		String linkType = null;
    	List<String> filePathList = new ArrayList<String>();
    	for(String fileName : fileNames){
            suffix = fileName.substring(fileName.lastIndexOf('.')+1, fileName.length());
            linkType = " LIKE '%" + suffix + "'";

            ContentResolver contentResolver = context.getContentResolver( );
            if( null != contentResolver ){
                Uri uri = MediaStore.Files.getContentUri( "external" );
                // 为了效率起见不应当传入null,否则默认取出所有的字段。这里应当根据自己的需求来定,比如下面只需要路径、大小信息
                Cursor cursor = contentResolver.query( uri,
                                	new String[ ]{ MediaStore.Files.FileColumns.DATA, MediaStore.Files.FileColumns.SIZE },
                                	MediaStore.Files.FileColumns.DATA + linkType, null, null );

                if( cursor != null ){
                    if( cursor.moveToFirst( ) ){
                        do{
                        	filePath = cursor.getString( cursor.getColumnIndex( MediaStore.Files.FileColumns.DATA ) );
                            if(filePath.substring(filePath.lastIndexOf('/') + 1, filePath.length()).equals(fileName)){
                            	filePathList.add(filePath);
                                break;
                            }
                        }while( cursor.moveToNext( ) );
                    }

                    if( !cursor.isClosed( ) ){
                        cursor.close( );
                    }
                }
            }
    	}

        return filePathList;
    }

Android通过广播更新文件和文件夹到媒体库

  网上有很多介绍更新文件和文件夹到媒体库的,更新文件到媒体库很简单,直接按照下面的方式发送广播就可以:

	/**
     * 通知媒体库更新文件
     * @param context
     * @param filePath 文件全路径
     * 
     * */
	public void scanFile(Context context, String filePath) {
		Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
		scanIntent.setData(Uri.fromFile(new File(filePath)));
		context.sendBroadcast(scanIntent);
	}

  但更新文件夹就比较麻烦了,网上介绍通过发送”android.intent.action.MEDIA_SCANNER_SCAN_DIR”显然是不行的,通过查看MediaScannerReceiver.java的源码就会发现这根本行不通,所以只能另辟蹊径,但是从代码中发现可以通过发送“Intent.ACTION_MEDIA_MOUNTED”来更新文件夹,具体实现方式是:

	/**
     * 通知媒体库更新文件夹
     * @param context
     * @param filePath 文件夹
     * 
     * */
	public void scanFile(Context context, String filePath) {
		Intent scanIntent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
		scanIntent.setData(Uri.fromFile(new File(filePath)));
		context.sendBroadcast(scanIntent);
	}

More