android開發筆記之內建圖片到相簿
開發需求
客戶提了一個需求,內建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和FileOutputStream
http://blog.csdn.net/hfreeman2008/article/details/49159547
相關文章
- iOS開發-新建相簿並儲存圖片到該相簿iOS
- Android生成圖片並放入相簿Android
- Android本地圖片上傳(拍照+相簿)Android地圖
- 鴻蒙儲存圖片到相簿鴻蒙
- android短視訊開發,呼叫相機、相簿,壓縮圖片後上傳Android
- 短視訊帶貨原始碼,儲存圖片到相簿/相簿原始碼
- Qt for Android (三) 開啟Android相簿並選一個圖片進行顯示QTAndroid
- Android開發筆記[13]-圖案密碼Android筆記密碼
- Android開發筆記Android筆記
- 小程式–儲存圖片到相簿功能實現
- 開發筆記:PDF生成文字和圖片水印筆記
- 開源計劃之--Android繪相簿--LogicCanvasAndroidCanvas
- Android記憶體優化之圖片優化Android記憶體優化
- Android開發筆記——點選檢視大圖過渡動畫與圖片縮放與移動Android筆記動畫
- Android 開發學習筆記Android筆記
- Android 拍照及相簿選取圖片功能,已適配Android6.0、7.0、8.0Android
- onethink 開發版新增貼相簿 開放平臺 圖片上傳驅動
- hive學習筆記之七:內建函式Hive筆記函式
- Android儲存多張圖片到本地Android
- 直播app開發搭建,Android studio 圖片壓縮APPAndroid
- android短影片開發,圖片視差滾動Android
- canvas元件繪製的內容匯出生成圖片儲存到相簿後開啟異常Canvas元件
- Android開發筆記[10]-關於頁Android筆記
- Android開發筆記[17]-桌面小部件Android筆記
- Android開發筆記——TextView 多行時 ellipsizeAndroid筆記TextView
- Android筆記之Kotlin、Java的內部類?巢狀類?Android筆記KotlinJava巢狀
- Python學習筆記|Python之內建變數__name__Python筆記變數
- 短視訊平臺開發,將圖片、視訊儲存到本地的相簿中
- 教你一鍵下載微博相簿的所有圖片,自動批量採集微博相簿所有圖片
- 日常筆記三:將base64的圖片上傳到本地筆記
- Android 基礎之圖片載入(二)Android
- Android開發筆記[18]-使用本地模組Android筆記
- 小程式生成二維碼圖片儲存相簿並分享到朋友圈
- 直播平臺搭建,Android手機拍照和手機相簿選取圖片的工具Android
- Android 從手機相簿獲取圖片 uri 路徑 從相機獲取照片Android
- Android-壓縮大圖到容量超小的圖片Android
- 開發筆記:使用 mpvue 開發鬥圖小程式筆記Vue
- 國內開源發展迎政策利好,開源生態建設應徐徐圖之
- iOS開發筆記之Xcode9.2下SDK開發-生成Framework的圖解流程iOS筆記XCodeFramework圖解