2015-12-31
11:16 AM
App 開發真的比 Web 還來得辛苦啊...
抱怨結束
在開發時常常需要有選擇圖片、檔案等等的功能
這時就需要啟動外部 App (啟動檔案瀏覽器) 來獲得選取檔案後的結果
例如點擊按鈕後啟動檔案管理員,選擇檔案後取得檔案路徑
再使用檔案路徑完成上傳檔案啦~ 圖片編輯等等的後續處理
搜尋 Intent file browser 可以得到很多資訊喔
接下來就開始介紹如何實現這項功能
4.4 版本以上由於 Android 修改了檔案的存取方式
請搭配這篇教學的方法使用 KitKat 以上版本從 URI 取得檔案實體路徑
程式碼範例
// 外部 App 回傳結果的類型判斷碼
private static final int FILE_SELECT_CODE = 0;
// 在按鈕上監聽點擊事件
settingsTypefaceButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fileBrowserIntent();
}
});
/**
* 啟動外部 App 的檔案管理員
*/
private void fileBrowserIntent(){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// 設定 MIME Type 但這裡是沒用的 加個心安而已
intent.setType("application/font-sfnt");
intent.addCategory(Intent.CATEGORY_OPENABLE);
try {
startActivityForResult( Intent.createChooser(intent, "選擇字型"), FILE_SELECT_CODE );
} catch (android.content.ActivityNotFoundException ex) {
// 若使用者沒有安裝檔案瀏覽器的 App 則顯示提示訊息
Toast.makeText(this, "沒有檔案瀏覽器 是沒辦法選擇字型的", Toast.LENGTH_SHORT).show();
}
}
/**
* 使用者選擇的結果將會作為參數傳遞至此
* @param requestCode 發出要求的代碼, 用以確定是取得何種結果
* @param resultCode 回傳結果的代碼, 用已確定是否請求成功
* @param data 回傳的資料
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// 檔案選擇代碼
case FILE_SELECT_CODE:
// 請求確認返回
if (resultCode == RESULT_OK) {
// 取得檔案路徑 Uri
Uri uri = data.getData();
// 取得路徑
String path = null;
try {
path = FileUtils.getPath(this, uri);
} catch (URISyntaxException e) {
Toast.makeText(this, "檔案不對勁!", Toast.LENGTH_SHORT).show();
logger.error("Get file path failed.", e);
return;
}
// 檢查檔案類型
String filename = FileUtils.typefaceChecker(path);
if( filename.isEmpty() ){
Toast.makeText(this, "檔案不對勁!", Toast.LENGTH_SHORT).show();
return;
}
// Do something here...
}
break;
}
super.onActivityResult(requestCode, resultCode, data);
}
眼尖的人就注意到了,FileUtils 是啥? 為什麼我沒有!!!
為什麼網路教學老是缺東缺西的啊!!! 崩潰啊啊啊啊啊啊啊啊!!!
我說寧王先別急著發飆啊
因為那是需要自己建立的 Class
原始碼如下
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import cmc.toolkit.FileKit;
import java.io.File;
import java.net.URISyntaxException;
public class FileUtils {
/**
* 由外部 Activity 回傳的資料取得檔案路徑
* @param context Activity
* @param uri Uri
* @return
* 檔案路徑
* @throws URISyntaxException
*/
public static String getPath(Context context, Uri uri) throws URISyntaxException {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = { "_data" };
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
// Do nothing
}
finally {
if( cursor != null ) cursor.close();
}
}
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
/**
* 檢查取回的檔案副檔名
* @param path 檔案路徑
* @return
* 若檔案類型正確則回傳檔案名稱, 反之則回傳空字串
*/
public static String typefaceChecker(String path){
if( path == null || path.isEmpty() ) return "";
File file = new File(path);
if( !file.exists() || !file.isFile() ) {
return "";
}
String filename = file.getName();
String ext = FileKit.getFileExt(filename);
if( !ext.equalsIgnoreCase(".ttf") ){
return "";
}
return filename;
}
}
// 一併附上取得副檔名的程式碼, FileKit 是我剛學 Java 時自己寫的小工具
public static String getFileExt(String fileName) {
int dotIndex = fileName.lastIndexOf(".");
return dotIndex == -1 ? "" : fileName.substring(dotIndex);
}
各項資料連結
Stackoverflow - Android file chooser
謝謝分享!
ReplyDelete