Android中如何使用代碼打開各種類型的文件

介紹

本篇用于介紹Android中如何打開各種類型的文件,如:音樂文件(mp3、wav、ogg等)、視頻文件(3gp、mp4等)、圖片文件(jpg、png、gif等)、安裝包(apk)、文檔(txt、doc、ppt、pdf、xls等),已經封裝成工具類OpenFileUtils,末尾有源碼地址。

注意

打開音樂、視頻、圖片、文檔等文件是需要有讀取SD卡的權限的,如果是6.0以下的系統,則直接在清單文件中聲明SD卡讀取權限即可;如果是6.0或以上,則需要動態申請權限。

為了兼容Android7.0,獲取文件Uri需要使用到FileProvider,由于本篇只是介紹如何打開文件,就不再介紹如何使用FileProvider,不清楚的同學可以查看我寫過的一篇關于Android7.0適配的博客,里面有介紹到該內容,博客地址:

http://blog.csdn.net/chay_chan/article/details/57083383

OpenFileUtils封裝好的獲取文件Uri的方法getUri()的代碼為:

 /**
 * 獲取對應文件的Uri
 * @param intent 相應的Intent
 * @param file 文件對象
 * @return
 */
private static Uri getUri(Intent intent, File file) {
    Uri uri = null;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        //判斷版本是否在7.0以上
        uri =
                FileProvider.getUriForFile(mContext,
                        mContext.getPackageName() + ".fileprovider",
                        file);
        //添加這一句表示對目標應用臨時授權該Uri所代表的文件
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    } else {
        uri = Uri.fromFile(file);
    }
    return uri;
}

OpenFileUtils的使用

OpenFileUtils是封裝好的用于打開本機各類文件的工具類,使用方式為:OpenFileUtils.getInstance(Context context).openFile(String filePath)。

各種文件的類型的DataType

DataType用于指定Intent中的數據類型,不同類型的文件有不同的DataType,傳入相應類型的DataType,系統會搜尋可以打開該文件的軟件,比如傳入視頻的DataType,即"video/*",那么系統將會搜尋本機中可以播放視頻的軟件,如果沒有安裝其他視頻播放軟件,則系統會默認使用自帶的播放視頻軟件,如果你還安裝了其他視頻播放軟件,如手機QQ影音,那么就會彈出選擇框讓你選擇使用哪個軟件打開。

下面第一個DataType未指定明確的文件類型,那么此時系統會彈出所有可以打開文件的軟件,需要用戶自己判斷使用哪個軟件才可以打開。

/**聲明各種類型文件的dataType**/
private static final String DATA_TYPE_ALL = "*/*";//未指定明確的文件類型,不能使用精確類型的工具打開,需要用戶選擇
private static final String DATA_TYPE_APK = "application/vnd.android.package-archive";
private static final String DATA_TYPE_VIDEO = "video/*";
private static final String DATA_TYPE_AUDIO = "audio/*";
private static final String DATA_TYPE_HTML = "text/html";
private static final String DATA_TYPE_IMAGE = "image/*";
private static final String DATA_TYPE_PPT = "application/vnd.ms-powerpoint";
private static final String DATA_TYPE_EXCEL = "application/vnd.ms-excel";
private static final String DATA_TYPE_WORD = "application/msword";
private static final String DATA_TYPE_CHM = "application/x-chm";
private static final String DATA_TYPE_TXT = "text/plain";
private static final String DATA_TYPE_PDF = "application/pdf";

打開文件的方法

/**
 * 打開文件
 * @param filePath 文件的全路徑,包括到文件名
 */
private static void openFile(String filePath) {
    File file = new File(filePath);
    if (!file.exists()){
        //如果文件不存在
        Toast.makeText(mContext, "打開失敗,原因:文件已經被移動或者刪除", Toast.LENGTH_SHORT).show();
        return;
    }
    /* 取得擴展名 */
    String end = file.getName().substring(file.getName().lastIndexOf(".") + 1, file.getName().length()).toLowerCase(Locale.getDefault());
    /* 依擴展名的類型決定MimeType */
    Intent intent = null;
    if (end.equals("m4a") || end.equals("mp3") || end.equals("mid") || end.equals("xmf") || end.equals("ogg") || end.equals("wav")) {
        intent =  generateVideoAudioIntent(filePath,DATA_TYPE_AUDIO);
    } else if (end.equals("3gp") || end.equals("mp4")) {
        intent = generateVideoAudioIntent(filePath,DATA_TYPE_VIDEO);
    } else if (end.equals("jpg") || end.equals("gif") || end.equals("png") || end.equals("jpeg") || end.equals("bmp")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_IMAGE);
    } else if (end.equals("apk")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_APK);
    }else if (end.equals("html") || end.equals("htm")){
        intent = getHtmlFileIntent(filePath);
    } else if (end.equals("ppt")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_PPT);
    } else if (end.equals("xls")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_EXCEL);
    } else if (end.equals("doc")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_WORD);
    } else if (end.equals("pdf")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_PDF);
    } else if (end.equals("chm")) {
        intent = generateCommonIntent(filePath,DATA_TYPE_CHM);
    } else if (end.equals("txt")) {
        intent = generateCommonIntent(filePath, DATA_TYPE_TXT);
    } else {
        intent = generateCommonIntent(filePath,DATA_TYPE_ALL);
    }
    mContext.startActivity(intent);
}   

打開文件的處理步驟如下:

  1. 截取得到文件的后綴名
  2. 根據后綴名判斷對應的文件屬于哪種DataType,調用對應產生封裝好的intent的方法,獲取到intent;
  3. 調用startActivity()方法,傳入intent

其中,generateVideoAudioIntent(String filePath, String dataType)是產生打開視頻和音頻類型文件的Intent的方法,代碼如下:

/**
 * 產生打開視頻或音頻的Intent
 * @param filePath 文件路徑
 * @param dataType 文件類型
 * @return
 */
 private static Intent generateVideoAudioIntent(String filePath, String dataType){
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.putExtra("oneshot", 0);
    intent.putExtra("configchange", 0);
    File file = new File(filePath);
    intent.setDataAndType(getUri(intent,file), dataType);
    return intent;
}

generateHtmlFileIntent()是產生打開網頁類型文件的Intent的方法,代碼如下:

 /**
 * 產生打開網頁文件的Intent
 * @param filePath 文件路徑
 * @return
 */
private static Intent generateHtmlFileIntent(String filePath) {
    Uri uri = Uri.parse(filePath)
            .buildUpon()
            .encodedAuthority("com.android.htmlfileprovider")
            .scheme("content")
            .encodedPath(filePath)
            .build();
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(uri, DATA_TYPE_HTML);
    return intent;
}

打開其他類型文件的方法generateCommonIntent(String filePath, String dataType),代碼如下:

/**
 * 產生除了視頻、音頻、網頁文件外,打開其他類型文件的Intent
 * @param filePath 文件路徑
 * @param dataType 文件類型
 * @return
 */
private static Intent generateCommonIntent(String filePath, String dataType) {
    Intent intent = new Intent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.setAction(Intent.ACTION_VIEW);
    File file = new File(filePath);
    Uri uri = getUri(intent, file);
    intent.setDataAndType(uri, dataType);
    return intent;
}

OpenFileUtils的源碼,可以點擊下面的網址跳轉查看和下載:

點擊查看源碼)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 在安卓中打開音樂、視頻、圖片、文檔等文件是需要有讀取SD卡權限的,如果是6.0以下的系統,則直接在清單文件中聲明S...
    努力與幸運閱讀 3,628評論 0 1
  • 用兩張圖告訴你,為什么你的 App 會卡頓? - Android - 掘金 Cover 有什么料? 從這篇文章中你...
    hw1212閱讀 12,958評論 2 59
  • ¥開啟¥ 【iAPP實現進入界面執行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,523評論 0 17
  • 我們每一個人都想做一個高情商的人,但是很難。盡管很難,還是有的人做到了。 (1) 最典型的是三國時期的劉備劉皇叔,...
    博雅大師兄閱讀 979評論 5 14
  • 沒有威士忌的夜晚 來杯開水吧 因為你不喝水比你不喝酒更難受 沒有親朋好友的相聚 看一本書吧 因為沒有靈魂比沒有軀體...
    亂語者閱讀 357評論 1 1