【基礎(chǔ)筆記】Android如何用第三方軟件打開文件

一披坏、為什么要用第三方軟件打開文件

假如在應(yīng)用中下載下來一個word文件,并把文件保存至指定位置后替劈。用戶想要打開文件蜒滩,不可能讓用戶對照著保存目錄去找滨达,這時候就需要通過指定的方法來調(diào)用對應(yīng)的第三方軟件來打開該文件。


二俯艰、主要方法

intent.setDataAndType(URI date,String Type):在Intent中傳入文件的Uri路徑和文件格式對應(yīng)的"Type"值捡遍。


三、實例

1竹握、代碼展示

  • FileOpen類
public class FileOpen {

    public static void openFile(Context context, File file){
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //intent.addCategory(Intent.CATEGORY_DEFAULT);
        Uri uriForFile;
        if (Build.VERSION.SDK_INT > 23){
            //Android 7.0之后
            uriForFile = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileprovider", file);
            intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);//給目標文件臨時授權(quán)
        }else {
            uriForFile = Uri.fromFile(file);
        }
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//系統(tǒng)會檢查當(dāng)前所有已創(chuàng)建的Task中是否有該要啟動的Activity的Task;
        // 若有画株,則在該Task上創(chuàng)建Activity;若沒有則新建具有該Activity屬性的Task啦辐,并在該新建的Task上創(chuàng)建Activity谓传。
        intent.setDataAndType(uriForFile,getMimeTypeFromFile(file));
        context.startActivity(intent);
    }

    /**
     * 使用自定義方法獲得文件的MIME類型
     */
    private static String getMimeTypeFromFile(File file) {
        String type = "*/*";
        String fName = file.getName();
        //獲取后綴名前的分隔符"."在fName中的位置。
        int dotIndex = fName.lastIndexOf(".");
        if (dotIndex > 0) {
            //獲取文件的后綴名
            String end = fName.substring(dotIndex, fName.length()).toLowerCase(Locale.getDefault());
            //在MIME和文件類型的匹配表中找到對應(yīng)的MIME類型芹关。
            HashMap<String, String> map = MyMimeMap.getMimeMap();
            if (!TextUtils.isEmpty(end) && map.keySet().contains(end)) {
                type = map.get(end);
            }
        }
        return type;
    }
}
  • MyMimeMap
public class MyMimeMap {
    private static final HashMap<String, String> mapSimple = new HashMap<>();
    /**
     *  常用"文件擴展名—MIME類型"匹配表续挟。
     *  注意,此表并不全侥衬,也并不是唯一的诗祸,就像有人喜歡用瀏覽器打開TXT一樣跑芳,你可以根據(jù)自己的愛好自定義。
     */
    public static HashMap<String, String> getMimeMap() {
        if (mapSimple.size() == 0) {
            mapSimple.put(".3gp", "video/3gpp");
            mapSimple.put(".apk", "application/vnd.android.package-archive");
            mapSimple.put(".asf", "video/x-ms-asf");
            mapSimple.put(".avi", "video/x-msvideo");
            mapSimple.put(".bin", "application/octet-stream");
            mapSimple.put(".bmp", "image/bmp");
            mapSimple.put(".c", "text/plain");
            mapSimple.put(".chm", "application/x-chm");
            mapSimple.put(".class", "application/octet-stream");
            mapSimple.put(".conf", "text/plain");
            mapSimple.put(".cpp", "text/plain");
            mapSimple.put(".doc", "application/msword");
            mapSimple.put(".docx", "application/msword");
            mapSimple.put(".exe", "application/octet-stream");
            mapSimple.put(".gif", "image/gif");
            mapSimple.put(".gtar", "application/x-gtar");
            mapSimple.put(".gz", "application/x-gzip");
            mapSimple.put(".h", "text/plain");
            mapSimple.put(".htm", "text/html");
            mapSimple.put(".html", "text/html");
            mapSimple.put(".jar", "application/java-archive");
            mapSimple.put(".java", "text/plain");
            mapSimple.put(".jpeg", "image/jpeg");
            mapSimple.put(".jpg", "image/jpeg");
            mapSimple.put(".js", "application/x-javascript");
            mapSimple.put(".log", "text/plain");
            mapSimple.put(".m3u", "audio/x-mpegurl");
            mapSimple.put(".m4a", "audio/mp4a-latm");
            mapSimple.put(".m4b", "audio/mp4a-latm");
            mapSimple.put(".m4p", "audio/mp4a-latm");
            mapSimple.put(".m4u", "video/vnd.mpegurl");
            mapSimple.put(".m4v", "video/x-m4v");
            mapSimple.put(".mov", "video/quicktime");
            mapSimple.put(".mp2", "audio/x-mpeg");
            mapSimple.put(".mp3", "audio/x-mpeg");
            mapSimple.put(".mp4", "video/mp4");
            mapSimple.put(".mpc", "application/vnd.mpohun.certificate");
            mapSimple.put(".mpe", "video/mpeg");
            mapSimple.put(".mpeg", "video/mpeg");
            mapSimple.put(".mpg", "video/mpeg");
            mapSimple.put(".mpg4", "video/mp4");
            mapSimple.put(".mpga", "audio/mpeg");
            mapSimple.put(".msg", "application/vnd.ms-outlook");
            mapSimple.put(".ogg", "audio/ogg");
            mapSimple.put(".pdf", "application/pdf");
            mapSimple.put(".png", "image/png");
            mapSimple.put(".pps", "application/vnd.ms-powerpoint");
            mapSimple.put(".ppt", "application/vnd.ms-powerpoint");
            mapSimple.put(".pptx", "application/vnd.ms-powerpoint");
            mapSimple.put(".prop", "text/plain");
            mapSimple.put(".rar", "application/x-rar-compressed");
            mapSimple.put(".rc", "text/plain");
            mapSimple.put(".rmvb", "audio/x-pn-realaudio");
            mapSimple.put(".rtf", "application/rtf");
            mapSimple.put(".sh", "text/plain");
            mapSimple.put(".tar", "application/x-tar");
            mapSimple.put(".tgz", "application/x-compressed");
            mapSimple.put(".txt", "text/plain");
            mapSimple.put(".wav", "audio/x-wav");
            mapSimple.put(".wma", "audio/x-ms-wma");
            mapSimple.put(".wmv", "audio/x-ms-wmv");
            mapSimple.put(".wps", "application/vnd.ms-works");
            mapSimple.put(".xml", "text/plain");
            mapSimple.put(".xls", "application/vnd.ms-excel");
            mapSimple.put(".xlsx", "application/vnd.ms-excel");
            mapSimple.put(".z", "application/x-compress");
            mapSimple.put(".zip", "application/zip");
            mapSimple.put("", "*/*");
        }
        return mapSimple;
    }
}

2直颅、實現(xiàn)思路

主要思路:通過第三方軟件打開文件時博个,要使用Intent的隱式方式將文件傳送到第三方應(yīng)用。

2.1:FileProvider
  • android 7.0 新增私有目錄訪問權(quán)限功偿,Google 官方說明:為了提高私有文件的安全性盆佣,面向 Android 7.0 或更高版本的應(yīng)用私有目錄被限制訪問 (0700)。此設(shè)置可防止私有文件的元數(shù)據(jù)泄漏脖含。所以這里在訪問下載的文件存儲路徑時罪塔,也需要動態(tài)判斷系統(tǒng)版本添加文件讀取權(quán)限,使用FileProvider獲取路徑养葵,否則會觸發(fā) FileUriExposedException異常
  • 添加FileProvider:
    在AndroidManifest的<application>中添加
   <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.example.administrator.timer.fileprovider"
            tools:replace="android:authorities"
            android:exported="false"
            android:grantUriPermissions="true">
            <!--指定Uri的共享路徑-->
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

在res中新建一個名為xml的Directory。在xml中新建一個file_pahts的xml文件瘩缆。

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_files" path="" />
</paths>
  • 通過File來獲取Uri:Android7.0前 Uri.fromfile(File file) 关拒;Android7.0后FileProvider.getUriForFile(Context context , String authority,File file);
2.2使用Intent將文件傳遞給第三方應(yīng)用
  • 打開文件時,需要給方法傳入當(dāng)前的Context和需要打開的File庸娱。
  • 新建一個Intent着绊,傳入Intent.ACTION_VIEW
  • 判斷當(dāng)前的系統(tǒng)是Android 7.0之前還是之后熟尉,選擇對應(yīng)的方法讀取讀取File的Uri值归露。
  • intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK):檢查當(dāng)前所有已創(chuàng)建的Task中是否有該要啟動的Activity的Task.
    當(dāng)系統(tǒng)是Android 7.0之后,別忘記了通過intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION)給目標文件臨時授權(quán)斤儿。
  • intent.setDataAndType(uri,getMimeTypeFromFile(file)):傳文件Uri地址和文件類型對應(yīng)的Type剧包。文件的Type可以通過getMimeTypeFromFile的方法來獲取。最后通過startActivity(intent)就可以實現(xiàn)效果了往果。
2.3 getMimeTypeFromFile:通過File獲取對應(yīng)的類型的Mime值
  • MIME(Multipurpose Internet Mail Extensions)多用途互聯(lián)網(wǎng)郵件擴展類型疆液。是設(shè)定某種擴展名的文件用一種應(yīng)用程序來打開的方式類型,當(dāng)該擴展名文件被訪問的時候陕贮,瀏覽器會自動使用指定應(yīng)用程序來打開堕油。
  • 獲取文件的數(shù)據(jù)類型,通過getMimeMap()的方法找到對應(yīng)的MimeMap值并將這個值返回肮之。

四掉缺、方法總結(jié)

  1. 通過 intent.setDataAndType(uri,getMimeTypeFromFile(file))傳入重要的兩個參數(shù),
  2. 其中通過File獲取Uri值時戈擒,需要判斷是Android的版本眶明,選擇對應(yīng)的方法獲取;
    獲取文件的Mime值時,需要獲取到文件類型名后峦甩,在getMimeMap()找到對應(yīng)Mime值并返回赘来。
  3. 往Intent中傳入相應(yīng)的Flags现喳,Action,最后調(diào)用startActivity(intent)就可以通過相關(guān)的第三方軟件打開文件了犬辰。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嗦篱,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子幌缝,更是在濱河造成了極大的恐慌灸促,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件涵卵,死亡現(xiàn)場離奇詭異浴栽,居然都是意外死亡,警方通過查閱死者的電腦和手機轿偎,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門典鸡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人坏晦,你說我怎么就攤上這事萝玷。” “怎么了昆婿?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵球碉,是天一觀的道長。 經(jīng)常有香客問我仓蛆,道長睁冬,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任看疙,我火速辦了婚禮豆拨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘狼荞。我一直安慰自己辽装,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布相味。 她就那樣靜靜地躺著拾积,像睡著了一般。 火紅的嫁衣襯著肌膚如雪丰涉。 梳的紋絲不亂的頭發(fā)上拓巧,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音一死,去河邊找鬼肛度。 笑死,一個胖子當(dāng)著我的面吹牛投慈,可吹牛的內(nèi)容都是我干的承耿。 我是一名探鬼主播冠骄,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼加袋!你這毒婦竟也來了凛辣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤职烧,失蹤者是張志新(化名)和其女友劉穎扁誓,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚀之,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡蝗敢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了足删。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寿谴。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖失受,靈堂內(nèi)的尸體忽然破棺而出木羹,到底是詐尸還是另有隱情奶甘,我是刑警寧澤裂七,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布运嗜,位于F島的核電站欣喧,受9級特大地震影響轰驳,放射性物質(zhì)發(fā)生泄漏蹲坷。R本人自食惡果不足惜坷剧,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一浦夷、第九天 我趴在偏房一處隱蔽的房頂上張望辖试。 院中可真熱鬧,春花似錦劈狐、人聲如沸罐孝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽莲兢。三九已至,卻和暖如春续膳,著一層夾襖步出監(jiān)牢的瞬間改艇,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工坟岔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留谒兄,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓社付,卻偏偏與公主長得像承疲,于是被迫代替她去往敵國和親邻耕。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容