簡體   English   中英

將圖像從 Android 上傳到 Amazon S3?

[英]Upload an image from Android to Amazon S3?

我需要將位圖上傳到 Amazon S3。 我從未使用過 S3,而且文檔證明幫助不大,因為我看不到任何內容來滿足此特定要求。 不幸的是,我正在努力在這個項目上抽出一整天的時間來學習它是如何結合在一起的,所以希望你們中的一個人能給我一些指導。

您能否向我指出一個解釋如何將文件推送到 S3 並獲得 URL 引用作為回報的參考來源?

更具體地說: - 使用 S3 Android SDK 時憑據去哪里了? - 我需要在上傳文件之前創建一個存儲桶,還是它們可以存在於存儲桶之外? - 我使用哪種 SDK 方法將位圖推送到 S3? - 我是否正確地認為我需要 CORE 和 S3 庫來做我需要的,而不是其他的?

String      ACCESS_KEY="****************",
            SECRET_KEY="****************",
            MY_BUCKET="bucket_name",
            OBJECT_KEY="unique_id";              
  AWSCredentials credentials = new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY);
                AmazonS3 s3 = new AmazonS3Client(credentials);
                java.security.Security.setProperty("networkaddress.cache.ttl" , "60");
                s3.setRegion(Region.getRegion(Regions.AP_SOUTHEAST_1));
                s3.setEndpoint("https://s3-ap-southeast-1.amazonaws.com/");
                List<Bucket> buckets=s3.listBuckets();
                for(Bucket bucket:buckets){
                    Log.e("Bucket ","Name "+bucket.getName()+" Owner "+bucket.getOwner()+ " Date " + bucket.getCreationDate());
                }
                Log.e("Size ", "" + s3.listBuckets().size());
                TransferUtility transferUtility = new TransferUtility(s3, getApplicationContext());
                UPLOADING_IMAGE=new File(Environment.getExternalStorageDirectory().getPath()+"/Screenshot.png");
                TransferObserver observer = transferUtility.upload(MY_BUCKET,OBJECT_KEY,UPLOADING_IMAGE);
                observer.setTransferListener(new TransferListener() {
                    @Override
                    public void onStateChanged(int id, TransferState state) {
                        // do something
                        progress.hide();
                        path.setText("ID "+id+"\nState "+state.name()+"\nImage ID "+OBJECT_KEY);

                    }

                    @Override
                    public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
                        int percentage = (int) (bytesCurrent / bytesTotal * 100);
                        progress.setProgress(percentage);
                        //Display percentage transfered to user
                    }

                    @Override
                    public void onError(int id, Exception ex) {
                        // do something
                        Log.e("Error  ",""+ex );
                    }

                });

查看Amazon S3 API 文檔,了解使用 Amazon S3 可以做什么和不可以做什么。 請注意,有兩個 API,一個更簡單的 REST API 和一個更復雜的 SOAP API。

您可以編寫自己的代碼來發出 HTTP 請求以與 REST API 交互,或者使用 SOAP 庫來使用 SOAP API。 所有 Amazon 服務都有這些標准 API 端點(REST、SOAP),理論上您可以用任何編程語言編寫客戶端!

對於 Android 開發人員來說幸運的是,亞馬遜發布了一個(測試版)SDK ,可以為您完成所有這些工作。 還有入門指南和Javadocs 使用此 SDK,您應該能夠在幾個小時內將 S3 與您的應用程序集成。

入門指南附帶了一個完整的示例,並展示了如何提供所需的憑據。

從概念上講,Amazon S3 將數據存儲在Buckets 中,其中存儲桶包含Objects 通常,您會為每個應用程序使用一個存儲桶,並根據需要添加任意數量的對象。 S3 不支持或有任何文件夾概念,但您可以在對象名稱中放置斜杠 (/)。

我們可以直接使用“Amazone s3”存儲桶在服務器上存儲任何類型的文件,我們不需要將任何文件發送到 Api 服務器,這將減少請求時間。

搖籃文件:-

 compile 'com.amazonaws:aws-android-sdk-core:2.2.+'
    compile 'com.amazonaws:aws-android-sdk-s3:2.2.+'
    compile 'com.amazonaws:aws-android-sdk-ddb:2.2.+'

清單文件:-

<service android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService"
            android:enabled="true" />

任何類中的 FileUploader 函數:-

 private void setUPAmazon() {
 //we Need Identity Pool ID  like :- "us-east-1:f224****************8"
        CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(getActivity(),
                "us-east-1:f224****************8", Regions.US_EAST_1);
        AmazonS3 s3 = new AmazonS3Client(credentialsProvider);
        final TransferUtility transferUtility = new TransferUtility(s3, getActivity());
        final File file = new File(mCameraUri.getPath());
        final TransferObserver observer = transferUtility.upload(GeneralValues.AMAZON_BUCKET, file.getName(), file, CannedAccessControlList.PublicRead);
        observer.setTransferListener(new TransferListener() {
            @Override
            public void onStateChanged(int id, TransferState state) {
                Log.e("onStateChanged", id + state.name());
                if (state == TransferState.COMPLETED) {
                    String url = "https://"+GeneralValues.AMAZON_BUCKET+".s3.amazonaws.com/" + observer.getKey();
                    Log.e("URL :,", url);
//we just need to share this File url with Api service request.  
                }
            }

            @Override
            public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
            }

            @Override
            public void onError(int id, Exception ex) {
                Toast.makeText(getActivity(), "Unable to Upload", Toast.LENGTH_SHORT).show();
                ex.printStackTrace();
            }
        });
    }

您可以使用下面提到的類將數據上傳到亞馬遜 s3 存儲桶。

public class UploadAmazonS3{

private CognitoCachingCredentialsProvider credentialsProvider = null;
private AmazonS3Client s3Client = null;
private TransferUtility transferUtility = null;
private static UploadAmazonS3 uploadAmazonS3;

/**
 * Creating single tone object by defining private.
 * <P>
 *     At the time of creating
 * </P>*/
private UploadAmazonS3(Context context, String canito_pool_id)
{
    /**
     * Creating the object of the getCredentialProvider object. */
    credentialsProvider=getCredentialProvider(context,canito_pool_id);
    /**
     * Creating the object  of the s3Client */
    s3Client=getS3Client(context,credentialsProvider);

    /**
     * Creating the object of the TransferUtility of the Amazone.*/
    transferUtility=getTransferUtility(context,s3Client);

}

public static UploadAmazonS3 getInstance(Context context, String canito_pool_id)
{
    if(uploadAmazonS3 ==null)
    {
        uploadAmazonS3 =new UploadAmazonS3(context,canito_pool_id);
        return uploadAmazonS3;
    }else
    {
        return uploadAmazonS3;
    }

}

/**
 * <h3>Upload_data</h3>
 * <P>
 *     Method is use to upload data in the amazone server.
 *
 * </P>*/

public void uploadData(final String bukkate_name, final File file, final Upload_CallBack callBack)
{
    Utility.printLog("in amazon upload class uploadData "+file.getName());

    if(transferUtility!=null&&file!=null)
    {
        TransferObserver observer=transferUtility.upload(bukkate_name,file.getName(),file);
        observer.setTransferListener(new TransferListener()
        {
            @Override
            public void onStateChanged(int id, TransferState state)
            {
                if(state.equals(TransferState.COMPLETED))
                {
                    callBack.sucess(com.tarha_taxi.R.string.AMAZON_END_POINT_LINK+bukkate_name+"/"+file.getName());
                }
            }

            @Override
            public void onProgressChanged(int id, long bytesCurrent, long bytesTotal)
            {

            }
            @Override
            public void onError(int id, Exception ex)
            {
                callBack.error(id+":"+ex.toString());

            }
        });
    }else
    {
        callBack.error("Amamzones3 is not intialize or File is empty !");
    }
}

/**
 * This method is used to get the CredentialProvider and we provide only context as a parameter.
 * @param context Here, we are getting the context from calling Activity.*/
private CognitoCachingCredentialsProvider getCredentialProvider(Context context,String pool_id)
{
    if (credentialsProvider == null)
    {
        credentialsProvider = new CognitoCachingCredentialsProvider(
                context.getApplicationContext(),
                pool_id, // Identity Pool ID
                AMAZON_REGION // Region
        );
    }
    return credentialsProvider;
}

/**
 * This method is used to get the AmazonS3 Client
 * and we provide only context as a parameter.
 * and from here we are calling getCredentialProvider() function.
 * @param context Here, we are getting the context from calling Activity.*/
private AmazonS3Client getS3Client(Context context,CognitoCachingCredentialsProvider cognitoCachingCredentialsProvider)
{
    if (s3Client == null)
    {
        s3Client = new AmazonS3Client(cognitoCachingCredentialsProvider);
        s3Client.setRegion(Region.getRegion(AMAZON_REGION));
        s3Client.setEndpoint(context.getString(com.tarha_taxi.R.string.AMAZON_END_POINT_LINK));
    }
    return s3Client;
}

/**
 * This method is used to get the Transfer Utility
 * and we provide only context as a parameter.
 * and from here we are, calling getS3Client() function.
 * @param context Here, we are getting the context from calling Activity.*/
private TransferUtility getTransferUtility(Context context,AmazonS3Client amazonS3Client)
{
    if (transferUtility == null)
    {
        transferUtility = new TransferUtility(amazonS3Client,context.getApplicationContext());
    }
    return transferUtility;
}

/**
 * Interface for the sucess callback fro the Amazon uploading .
 * */
public interface Upload_CallBack
{
    /**
     *Method for sucess .
     * @param sucess it is true on sucess and false for falure.*/
    void sucess(String sucess);
    /**
     * Method for falure.
     * @param errormsg contains the error message.*/
    void error(String errormsg);

}

}

使用下面的方法訪問上面的類:

 private void uploadToAmazon() {
    dialogL.show();
    UploadAmazonS3 amazonS3 = UploadAmazonS3.getInstance(getActivity(), getString(R.string.AMAZON_POOL_ID));
    amazonS3.uploadData(getString(R.string.BUCKET_NAME), Utility.renameFile(VariableConstants.TEMP_PHOTO_FILE_NAME, phone.getText().toString().substring(1) + ".jpg"), new UploadAmazonS3.Upload_CallBack() {
        @Override
        public void sucess(String sucess) {
            if (Utility.isNetworkAvailable(getActivity())) {
                dialogL.dismiss();
                /**
                 * to set the image into image view and
                 * add the write the image in the file
                 */
                activity.user_image.setTag(setTarget(progress_bar));
                Picasso.with(getActivity()).load(getString(R.string.AMAZON_IMAGE_LINK) + phone.getText().toString().substring(1) + ".jpg").
                        networkPolicy(NetworkPolicy.NO_CACHE).memoryPolicy(MemoryPolicy.NO_CACHE).into((Target) activity.user_image.getTag());

                Utility.printLog("amazon upload success ");
                new BackgroundForUpdateProfile().execute();
            } else {
                dialogL.dismiss();
                Utility.showToast(getActivity(), getResources().getString(R.string.network_connection_fail));
            }
        }

        @Override
        public void error(String errormsg) {
            dialogL.dismiss();
            Utility.showToast(getActivity(), getResources().getString(R.string.network_connection_fail));
        }
    });
}

您可以在 s3 amazon 中上傳圖像和下載圖像。 你使用這個 WebserviceAmazon 創建一個簡單的類

public class WebserviceAmazon extends AsyncTask<Void, Void, Void> {
private String mParams;
private String mResult = "x";
WebServiceInterface<String, String> mInterface;
private int mRequestType;
private  String UserId;
private Context mContext;


public WebserviceAmazon(Context context,String imagePath,String AppId,int type) {
    this.mContext = context;
    this.mParams = imagePath;
    this.mRequestType = type;
    this.UserId = AppId;
}

public void result(WebServiceInterface<String, String> myInterface) {
    this.mInterface = myInterface;
}

@Override
protected Void doInBackground(Void... params) {
    String ACCESS_KEY ="abc..";
    String SECRET_KEY = "klm...";

    try {
        if (mRequestType == 1) { // POST
            AmazonS3Client s3Client = new AmazonS3Client(new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY));
            PutObjectRequest request = new PutObjectRequest("bucketName", "imageName", new File(mParams));
            s3Client.putObject(request);

            mResult = "success";
        } if (mRequestType == 2) { // For get image data
            AmazonS3Client s3Client = new AmazonS3Client(new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY));
            S3Object object = s3Client.getObject(new GetObjectRequest("bucketName", mParams));
            S3ObjectInputStream objectContent = object.getObjectContent();
            byte[] byteArray = IOUtils.toByteArray(objectContent);

           Bitmap bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);



            mResult = "success";
        }

    } catch (Exception e) {
        mResult = e.toString();
        e.printStackTrace();
    }
    return null;
}

@Override
protected void onPreExecute() {
    // TODO Auto-generated method stub
    super.onPreExecute();
}

@Override
protected void onPostExecute(Void result) {
    // TODO Auto-generated method stub
  super.onPostExecute(result);
    mInterface.success(this.mResult);

}

public interface WebServiceInterface<E, R> {
    public void success(E reslut);

    public void error(R Error);
}

}

在項目中的任何位置調用此網絡服務

    WebserviceAmazon amazon = new WebserviceAmazon(getActivity(), imageName, "", 2);
    amazon.result(new WebserviceAmazon.WebServiceInterface<String, String>() {
        @Override
        public void success(String reslut) {

        }

        @Override
        public void error(String Error) {

        }
    });

    return totalPoints;
}

您可以使用名為 S3UploadService 的庫。 首先,您需要將位圖轉換為文件。 為此,請查看這篇文章:

將位圖轉換為文件

S3UploadService 是一個處理上傳到 Amazon S3 的庫。 它提供了一個名為 S3UploadService 的服務,其中包含一個靜態方法,您可以在其中提供一個 Context(因此該靜態方法可以啟動該服務)、一個 File、一個指示在上傳完成后是否應刪除所述文件的布爾值,您還可以選擇設置回調(不是就像一個普通的回調。它的工作方式在自述文件中解釋)。

它是一個 IntentService,因此即使用戶在上傳時終止了應用程序,上傳也會運行(因為它的生命周期沒有附加到應用程序的生命周期)。

要使用這個庫,你只需要在你的清單中聲明服務:

<application
    ...>

    ...

    <service
        android:name="com.onecode.s3.service.S3UploadService"
        android:exported="false" />
</application>

然后構建一個 S3BucketData 實例並調用 S3UploadService.upload():

    S3Credentials s3Credentials = new S3Credentials(accessKey, secretKey, sessionToken);
    S3BucketData s3BucketData = new S3BucketData.Builder()
            .setCredentials(s3Credentials)
            .setBucket(bucket)
            .setKey(key)
            .setRegion(region)
            .build();

    S3UploadService.upload(getActivity(), s3BucketData, file, null);

要添加此庫,您需要將 JitPack 存儲庫添加到您的根 build.gradle:

allprojects {
    repositories {
        ...
        maven { url "https://jitpack.io" }
    }
}

然后添加依賴項:

dependencies {
    compile 'com.github.OneCodeLabs:S3UploadService:1.0.0@aar'
}

這是存儲庫的鏈接: https : //github.com/OneCodeLabs/S3UploadService

這個答案有點晚了,但我希望它可以幫助某人

這是我將圖像上傳到Amazon AWS S3 存儲桶的代碼希望這對您有所幫助首先讓我清除一些關鍵點,您可以從相機拍攝圖像或從圖庫中選擇圖像,AWS 將圖像存儲為文件,因此您首先需要將圖像存儲到本地目錄並獲取圖像的路徑,然后從該路徑創建一個文件,之后您就可以將該圖像文件上傳到 AWS。

首先你需要在Oncreate上添加配置

BasicAWSCredentials credentials = new BasicAWSCredentials(KEY,SECRET);
         s3 = new AmazonS3Client(credentials);
        s3.setRegion(Region.getRegion(Regions.US_EAST_1));

private void uploadFile() {

        verifyStoragePermissions(CustomCameraActivity.this);

        TransferUtility transferUtility =
                TransferUtility.builder()
                        .context(getApplicationContext())
                        .awsConfiguration(AWSMobileClient.getInstance().getConfiguration())
                        .s3Client(s3)
                        .build();

        TransferObserver uploadObserver= null;
        
        File file2 = FileUtils.getFile(CustomCameraActivity.this, storageImagePath);//here i am converting path to file ,,FileUtils.getFile is custom class
        
            uploadObserver = transferUtility.upload("your bucket name", imageNameWithoutExtension + ".jpg", file2);// imagenamewithoutExtension is actually the name that you want to store 

        uploadObserver.setTransferListener(new TransferListener() {

            @Override
            public void onStateChanged(int id, TransferState state) {
                if (TransferState.COMPLETED == state) {
                    Toast.makeText(getApplicationContext(), "Upload Completed!", Toast.LENGTH_SHORT).show();
                    uploadResourcesApi(uploadResoucesURL);
                    //imageFile.delete();
                    //file2.delete();
                } else if (TransferState.FAILED == state) {
                    //imageFile.delete();
                    //file2.delete();
                }
            }

            @Override
            public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
                float percentDonef = ((float) bytesCurrent / (float) bytesTotal) * 100;
                int percentDone = (int) percentDonef;

                //tvFileName.setText("ID:" + id + "|bytesCurrent: " + bytesCurrent + "|bytesTotal: " + bytesTotal + "|" + percentDone + "%");
            }

            @Override
            public void onError(int id, Exception ex) {
                ex.printStackTrace();
            }

        });
    } 

這是 fileUtils 類

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.webkit.MimeTypeMap;



import java.io.File;
import java.io.FileFilter;
import java.text.DecimalFormat;
import java.util.Comparator;

/**
 * @version 2009-07-03
 * @author Peli
 * @version 2013-12-11
 * @author paulburke (ipaulpro)
 */
public class FileUtils {
    private FileUtils() {} //private constructor to enforce Singleton pattern

    /** TAG for log messages. */
    static final String TAG = "FileUtils";
    private static final boolean DEBUG = false; // Set to true to enable logging

    public static final String MIME_TYPE_AUDIO = "audio/*";
    public static final String MIME_TYPE_TEXT = "text/*";
    public static final String MIME_TYPE_IMAGE = "image/*";
    public static final String MIME_TYPE_VIDEO = "video/*";
    public static final String MIME_TYPE_APP = "application/*";

    public static final String HIDDEN_PREFIX = ".";

    /**
     * Gets the extension of a file name, like ".png" or ".jpg".
     *
     * @param uri
     * @return Extension including the dot("."); "" if there is no extension;
     *         null if uri was null.
     */
    public static String getExtension(String uri) {
        if (uri == null) {
            return null;
        }

        int dot = uri.lastIndexOf(".");
        if (dot >= 0) {
            return uri.substring(dot);
        } else {
            // No extension.
            return "";
        }
    }

    /**
     * @return Whether the URI is a local one.
     */
    public static boolean isLocal(String url) {
        if (url != null && !url.startsWith("http://") && !url.startsWith("https://")) {
            return true;
        }
        return false;
    }

    /**
     * @return True if Uri is a MediaStore Uri.
     * @author paulburke
     */
    public static boolean isMediaUri(Uri uri) {
        return "media".equalsIgnoreCase(uri.getAuthority());
    }

    /**
     * Convert File into Uri.
     *
     * @param file
     * @return uri
     */
    public static Uri getUri(File file) {
        if (file != null) {
            return Uri.fromFile(file);
        }
        return null;
    }

    /**
     * Returns the path only (without file name).
     *
     * @param file
     * @return
     */
    public static File getPathWithoutFilename(File file) {
        if (file != null) {
            if (file.isDirectory()) {
                // no file to be split off. Return everything
                return file;
            } else {
                String filename = file.getName();
                String filepath = file.getAbsolutePath();

                // Construct path without file name.
                String pathwithoutname = filepath.substring(0,
                        filepath.length() - filename.length());
                if (pathwithoutname.endsWith("/")) {
                    pathwithoutname = pathwithoutname.substring(0, pathwithoutname.length() - 1);
                }
                return new File(pathwithoutname);
            }
        }
        return null;
    }

    /**
     * @return The MIME type for the given file.
     */
    public static String getMimeType(File file) {

        String extension = getExtension(file.getName());

        if (extension.length() > 0)
            return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1));

        return "application/octet-stream";
    }

    /**
     * @return The MIME type for the give Uri.
     */
    public static String getMimeType(Context context, Uri uri) {
        File file = new File(getPath(context, uri));
        return getMimeType(file);
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is {@link LocalStorageProvider}.
     * @author paulburke
     */
    public static boolean isLocalStorageDocument(Uri uri) {
        return LocalStorageProvider.AUTHORITY.equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     * @author paulburke
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     * @author paulburke
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     * @author paulburke
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context The context.
     * @param uri The Uri to query.
     * @param selection (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     * @author paulburke
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                if (DEBUG)
                    DatabaseUtils.dumpCursor(cursor);

                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        } finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    
    public static String getPath(final Context context, final Uri uri) {

        if (DEBUG)
            Log.d(TAG + " File -",
                    "Authority: " + uri.getAuthority() +
                            ", Fragment: " + uri.getFragment() +
                            ", Port: " + uri.getPort() +
                            ", Query: " + uri.getQuery() +
                            ", Scheme: " + uri.getScheme() +
                            ", Host: " + uri.getHost() +
                            ", Segments: " + uri.getPathSegments().toString()
            );

        final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

        // DocumentProvider
        if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
            // LocalStorageProvider
            if (isLocalStorageDocument(uri)) {
                // The path is the id
                return DocumentsContract.getDocumentId(uri);
            }
            // ExternalStorageProvider
            else if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                if ("primary".equalsIgnoreCase(type)) {
                    return Environment.getExternalStorageDirectory() + "/" + split[1];
                }

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {

                final String id = DocumentsContract.getDocumentId(uri);
                final Uri contentUri = ContentUris.withAppendedId(
                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

                return getDataColumn(context, contentUri, null, null);
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[] {
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    
    public static File getFile(Context context, Uri uri) {
        if (uri != null) {
            String path = getPath(context, uri);
            if (path != null && isLocal(path)) {
                return new File(path);
            }
        }
        return null;
    }

    
    public static String getReadableFileSize(int size) {
        final int BYTES_IN_KILOBYTES = 1024;
        final DecimalFormat dec = new DecimalFormat("###.#");
        final String KILOBYTES = " KB";
        final String MEGABYTES = " MB";
        final String GIGABYTES = " GB";
        float fileSize = 0;
        String suffix = KILOBYTES;

        if (size > BYTES_IN_KILOBYTES) {
            fileSize = size / BYTES_IN_KILOBYTES;
            if (fileSize > BYTES_IN_KILOBYTES) {
                fileSize = fileSize / BYTES_IN_KILOBYTES;
                if (fileSize > BYTES_IN_KILOBYTES) {
                    fileSize = fileSize / BYTES_IN_KILOBYTES;
                    suffix = GIGABYTES;
                } else {
                    suffix = MEGABYTES;
                }
            }
        }
        return String.valueOf(dec.format(fileSize) + suffix);
    }

    
    public static Bitmap getThumbnail(Context context, File file) {
        return getThumbnail(context, getUri(file), getMimeType(file));
    }

    
    public static Bitmap getThumbnail(Context context, Uri uri) {
        return getThumbnail(context, uri, getMimeType(context, uri));
    }

    
    public static Bitmap getThumbnail(Context context, Uri uri, String mimeType) {
        if (DEBUG)
            Log.d(TAG, "Attempting to get thumbnail");

        if (!isMediaUri(uri)) {
            Log.e(TAG, "You can only retrieve thumbnails for images and videos.");
            return null;
        }

        Bitmap bm = null;
        if (uri != null) {
            final ContentResolver resolver = context.getContentResolver();
            Cursor cursor = null;
            try {
                cursor = resolver.query(uri, null, null, null, null);
                if (cursor.moveToFirst()) {
                    final int id = cursor.getInt(0);
                    if (DEBUG)
                        Log.d(TAG, "Got thumb ID: " + id);

                    if (mimeType.contains("video")) {
                        bm = MediaStore.Video.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Video.Thumbnails.MINI_KIND,
                                null);
                    }
                    else if (mimeType.contains(FileUtils.MIME_TYPE_IMAGE)) {
                        bm = MediaStore.Images.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Images.Thumbnails.MINI_KIND,
                                null);
                    }
                }
            } catch (Exception e) {
                if (DEBUG)
                    Log.e(TAG, "getThumbnail", e);
            } finally {
                if (cursor != null)
                    cursor.close();
            }
        }
        return bm;
    }

    
    public static Comparator<File> sComparator = new Comparator<File>() {
        @Override
        public int compare(File f1, File f2) {
            // Sort alphabetically by lower case, which is much cleaner
            return f1.getName().toLowerCase().compareTo(
                    f2.getName().toLowerCase());
        }
    };

   
    public static FileFilter sFileFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return files only (not directories) and skip hidden files
            return file.isFile() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    
    public static FileFilter sDirFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return directories only and skip hidden directories
            return file.isDirectory() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    
    public static Intent createGetContentIntent() {
        // Implicitly allow the user to select a particular kind of data
        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        // The MIME data type filter
        intent.setType("*/*");
        // Only return URIs that can be opened with ContentResolver
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        return intent;
    }
}

那么你也需要這個類

public class LocalStorageProvider extends DocumentsProvider {

    public static final String AUTHORITY = "com.ianhanniballake.localstorage.documents";

    private final static String[] DEFAULT_ROOT_PROJECTION = new String[] {
            Root.COLUMN_ROOT_ID,
            Root.COLUMN_FLAGS, Root.COLUMN_TITLE, Root.COLUMN_DOCUMENT_ID, Root.COLUMN_ICON,
            Root.COLUMN_AVAILABLE_BYTES
    };
    
    private final static String[] DEFAULT_DOCUMENT_PROJECTION = new String[] {
            Document.COLUMN_DOCUMENT_ID,
            Document.COLUMN_DISPLAY_NAME, Document.COLUMN_FLAGS, Document.COLUMN_MIME_TYPE,
            Document.COLUMN_SIZE,
            Document.COLUMN_LAST_MODIFIED
    };

    @Override
    public Cursor queryRoots(final String[] projection) throws FileNotFoundException {
        
        final MatrixCursor result = new MatrixCursor(projection != null ? projection
                : DEFAULT_ROOT_PROJECTION);
        
        File homeDir = Environment.getExternalStorageDirectory();
        final MatrixCursor.RowBuilder row = result.newRow();
        // These columns are required
        row.add(Root.COLUMN_ROOT_ID, homeDir.getAbsolutePath());
        row.add(Root.COLUMN_DOCUMENT_ID, homeDir.getAbsolutePath());
        row.add(Root.COLUMN_TITLE, "Internal storage");
        row.add(Root.COLUMN_FLAGS, Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_CREATE);
        row.add(Root.COLUMN_ICON, R.drawable.ic_launcher_foreground);
        // These columns are optional
        row.add(Root.COLUMN_AVAILABLE_BYTES, homeDir.getFreeSpace());
        // Root.COLUMN_MIME_TYPE is another optional column and useful if you
        
        return result;
    }

    @Override
    public String createDocument(final String parentDocumentId, final String mimeType,
                                 final String displayName) throws FileNotFoundException {
        File newFile = new File(parentDocumentId, displayName);
        try {
            newFile.createNewFile();
            return newFile.getAbsolutePath();
        } catch (IOException e) {
            Log.e(LocalStorageProvider.class.getSimpleName(), "Error creating new file " + newFile);
        }
        return null;
    }

    @Override
    public AssetFileDescriptor openDocumentThumbnail(final String documentId, final Point sizeHint,
                                                     final CancellationSignal signal) throws FileNotFoundException {
        
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(documentId, options);
        final int targetHeight = 2 * sizeHint.y;
        final int targetWidth = 2 * sizeHint.x;
        final int height = options.outHeight;
        final int width = options.outWidth;
        options.inSampleSize = 1;
        if (height > targetHeight || width > targetWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
           
            while ((halfHeight / options.inSampleSize) > targetHeight
                    || (halfWidth / options.inSampleSize) > targetWidth) {
                options.inSampleSize *= 2;
            }
        }
        options.inJustDecodeBounds = false;
        Bitmap bitmap = BitmapFactory.decodeFile(documentId, options);
        // Write out the thumbnail to a temporary file
        File tempFile = null;
        FileOutputStream out = null;
        try {
            tempFile = File.createTempFile("thumbnail", null, getContext().getCacheDir());
            out = new FileOutputStream(tempFile);
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
        } catch (IOException e) {
            Log.e(LocalStorageProvider.class.getSimpleName(), "Error writing thumbnail", e);
            return null;
        } finally {
            if (out != null)
                try {
                    out.close();
                } catch (IOException e) {
                    Log.e(LocalStorageProvider.class.getSimpleName(), "Error closing thumbnail", e);
                }
        }
        // It appears the Storage Framework UI caches these results quite
        // aggressively so there is little reason to
        // write your own caching layer beyond what you need to return a single
        // AssetFileDescriptor
        return new AssetFileDescriptor(ParcelFileDescriptor.open(tempFile,
                ParcelFileDescriptor.MODE_READ_ONLY), 0,
                AssetFileDescriptor.UNKNOWN_LENGTH);
    }

    @Override
    public Cursor queryChildDocuments(final String parentDocumentId, final String[] projection,
                                      final String sortOrder) throws FileNotFoundException {
        // Create a cursor with either the requested fields, or the default
        // projection if "projection" is null.
        final MatrixCursor result = new MatrixCursor(projection != null ? projection
                : DEFAULT_DOCUMENT_PROJECTION);
        final File parent = new File(parentDocumentId);
        for (File file : parent.listFiles()) {
            // Don't show hidden files/folders
            if (!file.getName().startsWith(".")) {
                // Adds the file's display name, MIME type, size, and so on.
                includeFile(result, file);
            }
        }
        return result;
    }

    @Override
    public Cursor queryDocument(final String documentId, final String[] projection)
            throws FileNotFoundException {
        // Create a cursor with either the requested fields, or the default
        // projection if "projection" is null.
        final MatrixCursor result = new MatrixCursor(projection != null ? projection
                : DEFAULT_DOCUMENT_PROJECTION);
        includeFile(result, new File(documentId));
        return result;
    }

    private void includeFile(final MatrixCursor result, final File file)
            throws FileNotFoundException {
        final MatrixCursor.RowBuilder row = result.newRow();
        // These columns are required
        row.add(Document.COLUMN_DOCUMENT_ID, file.getAbsolutePath());
        row.add(Document.COLUMN_DISPLAY_NAME, file.getName());
        String mimeType = getDocumentType(file.getAbsolutePath());
        row.add(Document.COLUMN_MIME_TYPE, mimeType);
        int flags = file.canWrite() ? Document.FLAG_SUPPORTS_DELETE | Document.FLAG_SUPPORTS_WRITE
                : 0;
        // We only show thumbnails for image files - expect a call to
        // openDocumentThumbnail for each file that has
        // this flag set
        if (mimeType.startsWith("image/"))
            flags |= Document.FLAG_SUPPORTS_THUMBNAIL;
        row.add(Document.COLUMN_FLAGS, flags);
        // COLUMN_SIZE is required, but can be null
        row.add(Document.COLUMN_SIZE, file.length());
        // These columns are optional
        row.add(Document.COLUMN_LAST_MODIFIED, file.lastModified());
        // Document.COLUMN_ICON can be a resource id identifying a custom icon.
        // The system provides default icons
        // based on mime type
        // Document.COLUMN_SUMMARY is optional additional information about the
        // file
    }

    @Override
    public String getDocumentType(final String documentId) throws FileNotFoundException {
        File file = new File(documentId);
        if (file.isDirectory())
            return Document.MIME_TYPE_DIR;
        // From FileProvider.getType(Uri)
        final int lastDot = file.getName().lastIndexOf('.');
        if (lastDot >= 0) {
            final String extension = file.getName().substring(lastDot + 1);
            final String mime = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
            if (mime != null) {
                return mime;
            }
        }
        return "application/octet-stream";
    }

    @Override
    public void deleteDocument(final String documentId) throws FileNotFoundException {
        new File(documentId).delete();
    }

    @Override
    public ParcelFileDescriptor openDocument(final String documentId, final String mode,
                                             final CancellationSignal signal) throws FileNotFoundException {
        File file = new File(documentId);
        final boolean isWrite = (mode.indexOf('w') != -1);
        if (isWrite) {
            return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
        } else {
            return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
        }
    }

    @Override
    public boolean onCreate() {
        return true;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM