android开发笔记之内置图片到图库
2016-07-29 17:24
323 查看
开发需求
客户提了一个需求,内置22张客户提供的壁纸到launcher的壁纸中,并且要在图库中显示这22张壁纸初步实现
初步看,觉得这应该是一个非常简单的需求,只要在luncher中对应以前的壁纸中添加22张客户的壁纸就可以了理想非常丰满,现实是非常骨感!
我大公司研发部门实行开发平台化大战略,各个开发实行模块化战术,各个模块,各个应用实行释放apk,不提供源码的策略。
好政策啊!
领导英明啊!
我按照launcher apk提供配制壁纸的方法,将客户提供的22张壁纸成功内置到launcher中,在launcher中可以看到壁纸中有内置的客户22张壁纸,但是图库中不能显示。
我就去向launcher模块的负责人咨询相关的解决方法。launcher告知我这要去找图库模块。
好吧,去找图库的负责人,图库负责查看了我的图片内置的位置:
system/etc/iamgeswallpapers/
告知我说图片内置到system中,图片不能识别。要我去找以前做项目的人。
我提出疑问:图库应该提供一个内置图片到图库的方法。
图库的负责人直接回复:对于这种需求,我们不负责,这和图库没有关系。
好吧,是我错了,哥,对不起,麻烦你们了。
我再找以前做项目的人,问了一下此需求。他们告知我解决方案:
(1)先将图片复制到system目录下
(2)再内置一个apk,就可以了
(注,为什么这位告诉我这么详细,因为是熟人!)
我按照上面的方法来实现:
第一:内置图片到目录(system/media/bootupResource)下:
先将图片放到picture目录下,然后在mk文件中配置,复制图片到(system/media/bootupResource):
配制方法:
PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/picture/hd_0.jpg:system/media/bootupResource/hd_0.jpg \ $(LOCAL_PATH)/picture/hd_1.jpg:system/media/bootupResource/hd_1.jpg \ $(LOCAL_PATH)/picture/hd_2.jpg:system/media/bootupResource/hd_2.jpg \ $(LOCAL_PATH)/picture/hd_3.jpg:system/media/bootupResource/hd_3.jpg \ $(LOCAL_PATH)/picture/hd_4.jpg:system/media/bootupResource/hd_4.jpg \ $(LOCAL_PATH)/picture/hd_5.jpg:system/media/bootupResource/hd_5.jpg \ $(LOCAL_PATH)/picture/hd_6.jpg:system/media/bootupResource/hd_6.jpg \ $(LOCAL_PATH)/picture/hd_7.jpg:system/media/bootupResource/hd_7.jpg \ .................
第二:内置app应用BootupImage
此应用BootupImage主要的作用是二个,一是将(system/media/bootupResource)目录下的图片复制到我们定义的手机内存中,二是通知手机立刻扫描到新复制的图片,以在图库中显示。
坑人的是,我内置此apk,图库中就是没有显示图片,我debug了半天,才发现原来是高通和MTK的读取内置路径的方法不同,我再移植对应的高通项目的此应用,功能是实现了。
重新实现
看了一下BootupImage应用,代码面向具体实现,代码的可读性一般,没有什么规范性,没有什么扩展性和可移植性。我决定重写:
Util.java
关键方法说明:boolean copyFile(String src,String des) ---复制文件功能:把路径为src的文件复制到路径为des的位置 成功返回true,失败为false
public static boolean copyFile(String src,String des){ boolean result = true; FileInputStream fis = null; FileOutputStream fos = null; try { //定义输入和输出的文件 File fin = new File(src); File fout = new File(des); //定义输入流和输出流的对象 fis = new FileInputStream(fin); fos = new FileOutputStream(fout); //3.执行复制操作 byte[] b = new byte[1024]; int len; while ((len = fis.read(b)) != -1) { fos.write(b, 0, len); } }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); result = false; }finally{ //4.关闭对应的流,先关输出流,后关输入流 if (fos != null) { try { fos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); result = false; } } if(fis != null){ try { fis.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); result = false; } } } return result; }
public static boolean copyDirectory(String sourceDir, String destDir) ---复制文件夹功能:把路径为src的文件夹复制到路径为des的位置 成功返回true,失败为false
public static boolean copyDirectory(String sourceDir, String destDir){ boolean result = true; File sourceFile = new File(sourceDir); File destFile = new File(destDir); if(!sourceFile.exists()){ android.util.Log.i(TAG, "sourceFile do not exist"); return false; } if(!destFile.exists()){ if(!destFile.mkdirs()){ android.util.Log.i(TAG, "destFile mkdirs fail"); return false; } } if(!destFile.canRead()){ android.util.Log.i(TAG, "destFile can not Read"); return false; } File[] file = sourceFile.listFiles(); for(int i=0;i<file.length;i++){ if(file[i].isFile()){ File sourceFileItem = file[i]; File destFileItem = new File(destFile.getAbsolutePath()+File.separator+file[i].getName()); copyFile(sourceFileItem.getAbsolutePath(),destFileItem.getAbsolutePath()); } if(file[i].isDirectory()){ String source=sourceDir + File.separator + file[i].getName(); String dest=destDir + File.separator + file[i].getName(); result = copyDirectory(source, dest); } } return result; }
public static final void scanFile(final Context context,final String path) ---扫描文件,让手机可以实时识别变动的文件
public static final void scanFile(final Context context,final String path){ android.util.Log.i(TAG, "scanFile--:"+path); Intent scanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); scanIntent.setData(Uri.fromFile(new File(path))); context.sendBroadcast(scanIntent); }
public static final void scanDir(final Context context,final String path) ---扫描文件夹,让手机可以实时识别变动的文件夹
public static final void scanDir(final Context context,final String path){ android.util.Log.i(TAG, "scanDir"); android.util.Log.i(TAG, "scanDir---path:"+path); File file = new File(path); File[] fileItemFiles = file.listFiles(); for (int i = 0; i < fileItemFiles.length; i++) { String pathItem = fileItemFiles[i].getParent()+File.separator+fileItemFiles[i].getName(); if(fileItemFiles[i].isFile()){ scanFile(context,pathItem); } if(fileItemFiles[i].isDirectory()){ scanDir(context,pathItem); } } }
定义几个关键的变量:
public static final String TAG = "Util"; //public static final String sourceDir = "/system/media/bootupResource"; public static final String sourceDir = "/system/media"; public static final String destDir_Without_SDCARD = Environment.getExternalStorageDirectory().getAbsolutePath() +File.separator+ "Pictures_01"; public static final String destDir_With_SDCARD = "/storage/sdcard1/Pictures";
调用方法
启动线程,以Util.copyDirectory实现复制文件夹,并且以Util.scanDir扫描最新复制的文件夹,以方便手机识别变动的文件,以让图片可以在图库中显示:runnable = new Runnable() { @Override public void run() { // TODO Auto-generated method stub //复制文件夹到对应的位置 boolean result = Util.copyDirectory(Util.sourceDir,Util.destDir_Without_SDCARD); android.util.Log.i(TAG, "onClickDo:"+result); android.util.Log.i(TAG, "onClickDo:---scanDir"); //扫描最新复制的文件夹,以识别变动的文件 Util.scanDir(getApplicationContext(), Util.destDir_Without_SDCARD); } }; runnable.run();
Android.mk
配置app的android.mk文件LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := TinnoCopyResourceToStorage LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE)
AndroidManifest.xml
定义权限:<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission> <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
以上其实已经实现了内置图片到图库中,并且实时让手机识别,以在图库中显示。
扩展
那么,如果客户提出内置其它资源到特定的目录路径(比如铃声,音乐,视频,apk,zip等等),并且让手机实现识别到复制过来的资源,以让手机实时识别和显示。啊噢,哈哈。
告诉你一个好消息吧,以上方法,你只需要修改src和des的路径,就可以实现所有此类的需求。
并且已验证!!
参考:
1.java核心技术之IO流(二)FileInputStream和FileOutputStreamhttp://blog.csdn.net/hfreeman2008/article/details/49159547
相关文章推荐
- Android实现表情 抓取新浪表情
- 详解Android解析Xml的三种方式——DOM、SAX以及XMLpull
- android开发环境遇到adt无法启动的问题分析及解决方法
- Android开发 旋转屏幕导致Activity重建解决方法
- Android开发技巧之在a标签或TextView控件中单击链接弹出Activity(自定义动作)
- Android开发技巧之ViewStub控件惰性装载
- Android开发常用经典代码段集锦
- 分享10个很棒的学习Android开发的网站
- android开发之横向滚动/竖向滚动的ListView(固定列头)
- Android开发技巧之我的菜单我做主(自定义菜单)
- Windows下使用Apache Cordova开发ANDROID之HelloWorld
- 根据根据图片的url怎么取得图片ImageView对象
- [转] ADB server didn't ACK
- android开发的相关链接
- Android数据存储之SharedPreferences 共享首选项/偏好设置
- ListView的深入探讨
- 基于NDK的Android防破解
- 麦子学院android开发笔记:Android更换RatingBar图片
- android开发入门知识之AIDL详解