日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

【Android Developers Training】 42. 從另一臺

系統 2429 0

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

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


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


一). 響應需求以顯示數據

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

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

用來匹配從通知發送的intent。

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

匹配隱式的 Intent 。

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

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

例如,下面的例子展示了如何添加一個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文件傳輸會發送含有 ACTION_VIEW 的intent。在接收設備上的其它應用也有可能會發送含有該行為的intent。我們馬上會進一步討論這一問題。


二). 需求文件權限

如果要讀取Android Beam文件傳輸所拷貝到設備上的文件,需要 READ_EXTERNAL_STORAGE 權限。例如:

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

如果你希望將文件拷貝指你自己應用的存儲區,那么需要的權限改為 WRITE_EXTERNAL_STORAGE ,另外 WRITE_EXTERNAL_STORAGE 權限包含了 READ_EXTERNAL_STORAGE 權限。

Note:

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

由于你的應用對于其 內部 存儲區域具有控制權,所以若要將文件拷貝至你應用的 內部 存儲區域,寫權限式不需要申明的。


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

Android Beam文件傳輸一次性將所有文件拷貝到目標設備的一個目錄內, Android Beam文件傳輸通知所發出的 Intent 中包含有URI,他指向了第一個傳輸的文件。然而,你的應用也有可能接收到除了 Android Beam文件傳輸之外的某個來源所發出的含有 ACTION_VIEW 行為的Intent。為了明確你應該如何處理接收的Intent,你需要檢查它的架構( scheme )和權威( authority )。

為了獲得URI的架構,調用 Uri.getScheme() ,下面的代碼展示了如何明確架構并處理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 包含一個內容URI,則該URI包含了一個文件的絕對文件名,包括了完整的路徑和文件名。對于 Android Beam文件傳輸來說,目錄路徑指向了其它傳輸文件的位置(如果有其它傳輸文件的話),要獲得這個目錄路徑,取得URI的路徑部分(URI中除去“ file: ”前綴的部分),根據路徑創建一個 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();

    }

    ...
      
    

從內容URI獲取目錄

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

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

Note:

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

確定內容提供程序

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

MediaStore.AUTHORITY

表明這個URI關聯了被 MediaStore 追蹤的 一個文件或者 多個文件??梢詮? MediaStore 中獲取文件的全名,目錄名就自然可以從文件全名中獲取。

其他任何權威值

來自其他內容提供程序的內容URI。可以顯示與該內容URI相關聯的數據,但是不要嘗試去獲取文件目錄。

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

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

      
         ...

    
      
      
        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
      
      
        ;

             }

        }

    }

    ...
      
    

要學習更多關于從內容提供程序獲取數據的知識,可以閱讀: Retrieving Data from the Provider

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


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 阳西县| 宜昌市| 盘锦市| 铜梁县| 海原县| 会昌县| 哈密市| 腾冲县| 新平| 平乐县| 阿拉尔市| 延津县| 嘉兴市| 泽库县| 探索| 凤台县| 南丰县| 莆田市| 大厂| 白河县| 广西| 修武县| 嵩明县| 阿拉善左旗| SHOW| 永兴县| 白水县| 保山市| 田东县| 遂宁市| 安龙县| 财经| 辰溪县| 根河市| 西林县| 陵水| 广德县| 桂东县| 廉江市| 周宁县| 沙坪坝区|