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