Android获取手机本地图片缩略图

首先,提取图片和视频的缩略图可以直接访问Android系统数据库:

1 android.provider.MediaStore.Images.Thumbnails
2 android.provider.MediaStore.Video.Thumbnails
这两个数据库,即可查询出来缩略图
可以根据下面方法获取
 public long getDbId(String path, boolean isVideo) {
String volumeName = "external";
Uri uri = isVideo ? Video.Media.getContentUri(volumeName) : Images.Media.EXTERNAL_CONTENT_URI;
// .getContentUri(volumeName);
String selection = MediaColumns.DATA + "=?";
String[] selectionArgs = new String[] {
path
};

String[] columns = new String[] {
MediaColumns._ID, MediaColumns.DATA
};

Cursor c = mContext.getContentResolver()
.query(uri, columns, selection, selectionArgs, null);
if (c == null) {
return 0;
}
long id = 0;
if (c.moveToNext()) {
id = c.getLong(0);
}
c.close();
return id;
}
return Images.Thumbnails.getThumbnail(mContext.getContentResolver(), id, MICRO_KIND,
null);

但是现在有一个问题,自己通过代码下载的图在getDbId方法里获取不到id,这是问什么呢 ?!!

关于这个问题,我们貌似要了解一下,缩略图到底是如何实现的?这里有一个类:MediaScanner(详细要研究可见:http://blog.csdn.net/zqiang_55/article/details/7060171 )这个类是负责扫描所有的图片并将图片存储进入MediaStore(MediaScannerReceiver用来接收任务的,它收到广播后,会启动MediaService进行扫描工作。好复杂的样子。。。

MediaScanner可以通过手动控制,在ANDROID系统中,已经定制了三种事件会触发MediaScanner去扫描磁盘文件:ACTION_BOOT_COMPLETED、ACTION_MEDIA_MOUNTED、 ACTION_MEDIA_SCANNER_SCAN_FILE。其中ACTION_BOOT_COMPLETED是系统启动完后发出这个消息,ACTION_MEDIA_MOUNTED是插卡事件触发的消息,ACTION_MEDIA_SCANNER_SCAN_FILE消息一般是在一些文件操作后,开发人员手动发出的一个重新扫描多媒体文件的消息。发送消息通过sendBroadcast函数完成,比如广播一个ACTION_MEDIA_MOUNTED消息:

1 sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory())));

由上可知是通过发送了一个广播(传递对应的扫描要求)来触发重新扫描磁盘事件,那么可以猜测系统肯定存在一个广播接收器(何时何地注册?),在收到这个广播消息后,通过对应参数启动MediaScannerService。MediaScannerService调用一个公用类MediaScanner去处理真正的工作。MediaScannerReceiver维持两种扫描目录:一种是内部卷(internal volume)指向$(ANDROID_ROOT)/media. 另一种是外部卷(external volume)指向$(EXTERNAL_STORAGE),扫描的位置可以修改(一般外部不用修改,默认为SDCARD,内部根据驱动命名的INAND路经名做对应的修改)。

所以,如果你存储了图片但是没有启动磁盘扫描,就会造成缩略图不全

问题简单了,下载完文件后发送这个广播就好了?

NO!NO!NO!

发送这个广播的时候,app崩溃了!
java.lang.SecurityException: Permission Denial: not allowed to send broadcast android.intent.action.MEDIA_MOUNTED
原来4.4及以后的系统是不允许发送这个广播的,原因是你可能只增加可一个文件,然后就进行全盘扫描,这样很耗电,因此只有系统才能发送这个广播
        mContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.parse("file://" + Environment.getExternalStorageDirectory())));  
把你上面发送广播的所有代码换成这个试一下,大功告成了!

参考文献:
 
  
http://blog.csdn.net/java2009cgh/article/details/8364735
http://zhidao.baidu.com/link?url=-foiVdD7bqTRMHPXU0dOcJigasxZPsfLiOkgRwDIMT8A4hUMdAD-XSBQMtEAvlsM0XW_3L5ThsLtLy8ltpuATl7jO-1r-kWFmOQ3uTqg6cW
http://stackoverflow.com/questions/24072489/java-lang-securityexception-permission-denial-not-allowed-to-send-broadcast-an




你可能感兴趣的:(Android,Android,图片,缩略图)