亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

【Android Developers Training】 42. 從另一臺

系統(tǒng) 2020 0

注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術(shù)一般,由于喜愛安卓而產(chǎn)生了翻譯的念頭,純屬個人興趣愛好。

原文鏈接: http://developer.android.com/training/beam-files/receive-files.html


Android Beam文件傳輸將文件拷貝至接收設(shè)備上的一個特殊目錄。同時使用Android媒體掃描器 Android Media Scanner )掃描拷貝的文件,并為媒體文件添加對應(yīng)的字段至媒體庫( MediaStore ?provide)中。這節(jié)課將向你展示當(dāng)文件拷貝完成時要如何響應(yīng),并且在接收設(shè)備上應(yīng)該如何放置拷貝的文件。


一). 響應(yīng)需求以顯示數(shù)據(jù)

當(dāng)Android Beam文件傳輸將文件拷貝至接收設(shè)備后,它會發(fā)布一個通知,包含了一個 Intent ,它有有一個 ACTION_VIEW 的行為,第一個傳輸文件的 MIME 類型,和一個指向第一個文件的 URI。當(dāng)用戶點擊了這個通知后,intent會被發(fā)送至系統(tǒng)。為了讓你的應(yīng)用能夠響應(yīng)這個intent,為要響應(yīng)的 Activity 所對應(yīng)的 <activity> 標(biāo)簽添加 <intent-filter> 標(biāo)簽,在 <intent-filter> 標(biāo)簽中,添加下面的子標(biāo)簽:

<action android:name="android.intent.action.VIEW" />

用來匹配從通知發(fā)送的intent。

<category android:name="android.intent.category.CATEGORY_DEFAULT" />

匹配隱式的 Intent

<data android:mimeType=" mime-type " />

匹配一個MIME類型。要指定那些你的應(yīng)用能夠處理的類型。

例如,下面的例子展示了如何添加一個intent過濾器來激活你的activity:

com.example.android.nfctransfer.ViewActivity

      
        <
      
      
        activity

        
      
      
        android:name
      
      
        ="com.example.android.nfctransfer.ViewActivity"
      
      
        

        android:label
      
      
        ="Android Beam Viewer"
      
      
        >
      
      
        

        ...

        
      
      
        <
      
      
        intent-filter
      
      
        >
      
      
        <
      
      
        action 
      
      
        android:name
      
      
        ="android.intent.action.VIEW"
      
      
        />
      
      
        <
      
      
        category 
      
      
        android:name
      
      
        ="android.intent.category.DEFAULT"
      
      
        />
      
      
        

            ...

        
      
      
        </
      
      
        intent-filter
      
      
        >
      
      
        </
      
      
        activity
      
      
        >
      
    

Note:

不僅僅只有Android Beam文件傳輸會發(fā)送含有 ACTION_VIEW 的intent。在接收設(shè)備上的其它應(yīng)用也有可能會發(fā)送含有該行為的intent。我們馬上會進一步討論這一問題。


二). 需求文件權(quán)限

如果要讀取Android Beam文件傳輸所拷貝到設(shè)備上的文件,需要 READ_EXTERNAL_STORAGE 權(quán)限。例如:

      
        <
      
      
        uses-permission 
      
      
        android:name
      
      
        ="android.permission.READ_EXTERNAL_STORAGE"
      
      
        />
      
    

如果你希望將文件拷貝指你自己應(yīng)用的存儲區(qū),那么需要的權(quán)限改為 WRITE_EXTERNAL_STORAGE ,另外 WRITE_EXTERNAL_STORAGE 權(quán)限包含了 READ_EXTERNAL_STORAGE 權(quán)限。

Note:

對于Android 4.2.2 (API Level 17), READ_EXTERNAL_STORAGE 權(quán)限僅在用戶選擇要讀文件時才是強制需要的。而在今后的版本中會在所有情況下都需要該權(quán)限。為了保證應(yīng)用在未來的兼容性,建議在清單文件中申明該權(quán)限。

由于你的應(yīng)用對于其 內(nèi)部 存儲區(qū)域具有控制權(quán),所以若要將文件拷貝至你應(yīng)用的 內(nèi)部 存儲區(qū)域,寫權(quán)限式不需要申明的。


三). 獲取拷貝文件的目錄

Android Beam文件傳輸一次性將所有文件拷貝到目標(biāo)設(shè)備的一個目錄內(nèi), Android Beam文件傳輸通知所發(fā)出的 Intent 中包含有URI,他指向了第一個傳輸?shù)奈募H欢愕膽?yīng)用也有可能接收到除了 Android Beam文件傳輸之外的某個來源所發(fā)出的含有 ACTION_VIEW 行為的Intent。為了明確你應(yīng)該如何處理接收的Intent,你需要檢查它的架構(gòu)( scheme )和權(quán)威( authority )。

為了獲得URI的架構(gòu),調(diào)用 Uri.getScheme() ,下面的代碼展示了如何明確架構(gòu)并處理URI:

      
        public
      
      
        class
      
       MainActivity 
      
        extends
      
      
         Activity {

    ...

    
      
      
        //
      
      
         A File object containing the path to the transferred files
      
      
        private
      
      
         File mParentPath;

    
      
      
        //
      
      
         Incoming Intent
      
      
        private
      
      
         Intent mIntent;

    ...

    
      
      
        /*
      
      
        

     * Called from onNewIntent() for a SINGLE_TOP Activity

     * or onCreate() for a new Activity. For onNewIntent(),

     * remember to call setIntent() to store the most

     * current Intent

     *

     
      
      
        */
      
      
        private
      
      
        void
      
      
         handleViewIntent() {

        ...

        
      
      
        //
      
      
         Get the Intent action
      
      

        mIntent =
      
         getIntent();

        String action 
      
      =
      
         mIntent.getAction();

        
      
      
        /*
      
      
        

         * For ACTION_VIEW, the Activity is being asked to display data.

         * Get the URI.

         
      
      
        */
      
      
        if
      
      
         (TextUtils.equals(action, Intent.ACTION_VIEW)) {

            
      
      
        //
      
      
         Get the URI from the Intent
      
      

            Uri beamUri =
      
         mIntent.getData();

            
      
      
        /*
      
      
        

             * Test for the type of URI, by getting its scheme value

             
      
      
        */
      
      
        if
      
       (TextUtils.equals(beamUri.getScheme(), "file"
      
        )) {

                mParentPath 
      
      =
      
         handleFileUri(beamUri);

            } 
      
      
        else
      
      
        if
      
      
         (TextUtils.equals(

                    beamUri.getScheme(), 
      
      "content"
      
        )) {

                mParentPath 
      
      =
      
         handleContentUri(beamUri);

            }

        }

        ...

    }

    ...

}
      
    

從文件URI中獲取目錄

如果接收的 Intent 包含一個內(nèi)容URI,則該URI包含了一個文件的絕對文件名,包括了完整的路徑和文件名。對于 Android Beam文件傳輸來說,目錄路徑指向了其它傳輸文件的位置(如果有其它傳輸文件的話),要獲得這個目錄路徑,取得URI的路徑部分(URI中除去“ file: ”前綴的部分),根據(jù)路徑創(chuàng)建一個 File 對象,然后獲取這個 File 的父目錄:

      
        ...

    
      
      
        public
      
      
         String handleFileUri(Uri beamUri) {

        
      
      
        //
      
      
         Get the path part of the URI
      
      

        String fileName =
      
         beamUri.getPath();

        
      
      
        //
      
      
         Create a File object for this filename
      
      

        File copiedFile = 
      
        new
      
      
         File(fileName);

        
      
      
        //
      
      
         Get a string containing the file's parent directory
      
      
        return
      
      
         copiedFile.getParent();

    }

    ...
      
    

從內(nèi)容URI獲取目錄

如果接收的 Intent 包含一個內(nèi)容URI,這個URI可能指向的是一個存儲于 MediaStore 內(nèi)容提供程序的目錄和文件名。你可以通過檢測URI的權(quán)威值來判斷是否是 MediaStore 的內(nèi)容URI。一個 MediaStore 的內(nèi)容URI可能來自 Android Beam文件傳輸也可能來自其它應(yīng)用,但不管怎么樣,你都能根據(jù)該內(nèi)容URI獲得一個目錄和文件名。

你也能接收一個 ACTION_VIEW 的Intent,它包含有一個內(nèi)容提供程序的URI而不是 MediaStore ,在這個例子中,這個內(nèi)容URI不包含 MediaStore 的權(quán)威值,且這個URI一般不指向一個目錄

Note:

對于 Android Beam文件傳輸,如果第一個接收的文件,其MIME類型為“ audio/* ”,“ image/* ”或者“ video/* ”,那么你接收這個處于 ACTION_VIEW 的Intent的內(nèi)容URI。 Android Beam文件傳輸會通過在它存儲傳輸文件的目錄內(nèi)運行媒體掃描器,以此為媒體文件添加索引。同時媒體掃描器將結(jié)果寫入 MediaStore 內(nèi)容提供程序,之后它將第一個文件的內(nèi)容URI回遞給 Android Beam文件傳輸。這個內(nèi)容URI就是你在通知 Intent 中所接收到的。要獲得第一個文件的目錄,你需要使用該內(nèi)容URI從 MediaStore 中獲取它。

確定內(nèi)容提供程序

為了明確你能從內(nèi)容URI中獲取文件目錄,你可以通過調(diào)用 Uri.getAuthority() 獲取URI的權(quán)威,以此確定與該URI相關(guān)聯(lián)的內(nèi)容提供程序。其結(jié)果有兩個可能的值:

MediaStore.AUTHORITY

表明這個URI關(guān)聯(lián)了被 MediaStore 追蹤的 一個文件或者 多個文件。可以從 MediaStore 中獲取文件的全名,目錄名就自然可以從文件全名中獲取。

其他任何權(quán)威值

來自其他內(nèi)容提供程序的內(nèi)容URI。可以顯示與該內(nèi)容URI相關(guān)聯(lián)的數(shù)據(jù),但是不要嘗試去獲取文件目錄。

為了從 MediaStore 的內(nèi)容URI中獲取目錄,執(zhí)行一個查詢操作,它將 Uri 參數(shù)指定為收到的內(nèi)容URI,列名為 MediaColumns.DATA 。返回的 Cursor 包含了完整路徑和URI所代表的文件名。該目錄路徑下還包含了由 Android Beam文件傳輸傳送到該設(shè)備上的其它文件。

下面的代碼展示了你要如何測試內(nèi)容URI的權(quán)威值,并獲取傳輸文件的路徑和文件名:

      
         ...

    
      
      
        public
      
      
         String handleContentUri(Uri beamUri) {

        
      
      
        //
      
      
         Position of the filename in the query Cursor
      
      
        int
      
      
         filenameIndex;

        
      
      
        //
      
      
         File object for the filename
      
      
                File copiedFile;

        
      
      
        //
      
      
         The filename stored in MediaStore
      
      
                String fileName;

        
      
      
        //
      
      
         Test the authority of the URI
      
      
        if
      
       (!
      
        TextUtils.equals(beamUri.getAuthority(), MediaStore.AUTHORITY)) {

            
      
      
        /*
      
      
        

             * Handle content URIs for other content providers

             
      
      
        */
      
      
        //
      
      
         For a MediaStore content URI
      
      

        } 
      
        else
      
      
         {

            
      
      
        //
      
      
         Get the column that contains the file name
      
      

            String[] projection =
      
         { MediaStore.MediaColumns.DATA };

            Cursor pathCursor 
      
      =
      
        

                    getContentResolver().query(beamUri, projection,

                    
      
      
        null
      
      , 
      
        null
      
      , 
      
        null
      
      
        );

            
      
      
        //
      
      
         Check for a valid cursor
      
      
        if
      
       (pathCursor != 
      
        null
      
       &&
      
        

                    pathCursor.moveToFirst()) {

                
      
      
        //
      
      
         Get the column index in the Cursor
      
      

                filenameIndex =
      
         pathCursor.getColumnIndex(

                        MediaStore.MediaColumns.DATA);

                
      
      
        //
      
      
         Get the full file name including path
      
      

                fileName =
      
         pathCursor.getString(filenameIndex);

                
      
      
        //
      
      
         Create a File object for the filename
      
      

                copiedFile = 
      
        new
      
      
         File(fileName);

                
      
      
        //
      
      
         Return the parent directory of the file
      
      
        return
      
      
        new
      
      
         File(copiedFile.getParent());

             } 
      
      
        else
      
      
         {

                
      
      
        //
      
      
         The query didn't work; return null
      
      
        return
      
      
        null
      
      
        ;

             }

        }

    }

    ...
      
    

要學(xué)習(xí)更多關(guān)于從內(nèi)容提供程序獲取數(shù)據(jù)的知識,可以閱讀: Retrieving Data from the Provider

【Android Developers Training】 42. 從另一臺設(shè)備接收文件


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 国产性做久久久久久 | 欧美国产亚洲18 | 性做久久久久久蜜桃花 | 日本α级毛片视频免费观看 | 四虎永久在线观看 | 福利午夜国产网站在线不卡 | 亚洲国产片 | 国产日韩在线 | 俺来也欧美亚洲a∨在线 | 日夜操在线视频 | 亚洲第一综合色 | 美女被羞羞视频网站在线 | 日本一级α一片免费视频 | 亚洲天天干 | 热久久这里只有精品 | 亚洲国产成人99精品激情在线 | 四虎国产视频 | 国产成人一区二区 | 亚洲日韩中文字幕一区 | 久久天天躁狠狠躁夜夜中文字幕 | 亚洲国产精品乱码在线观看97 | 7799国产精品久久久久99 | 日本一级毛片aaaaa | 中文字幕在线视频精品 | 日本一级特黄大一片免 | 日韩三级久久 | 色婷婷六月桃花综合影院 | 看一级毛片 | 久久一区二区精品综合 | 97免费观看视频 | 免费观看成人碰视频公开 | 九九视频免费看 | 全免费毛片在线播放 | 四虎网站在线 | 四虎永久免费观看 | 97国产在线公开免费观看 | 国产二级毛片 | 欧美爱爱视频网站 | julia在线视频 | 中文字幕一区二区视频 | 国产精品毛片va一区二区三区 |