Search

Andoird - 啟動檔案瀏覽器選擇檔案

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

1 comment: