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);
- }