本文介绍在安卓系统中,如何上传文件到OSS。

简单上传

简单上传就是调用OSS API中的 PutObject接口,一次性将选择的文件上传到OSS上。
  • 调用逻辑
    1. 选择上传后,可以选择需要上传的本地文件。
    2. OssDemo在获取sts_server的地址后发送请求。
    3. sts_server返回AccessKeyId、AccessKeySecret、SecurityToken、Expiration。
    4. OssDemo获取这些信息后,调用SDK,构建OssClient,进行简单上传。
  • 具体代码
    1. 生成一个Button控件。
      位置:
       res/layout/content_main.xml
       内容:
       <Button
           style="?android:attr/buttonStyleSmall"
           android:layout_height="wrap_content"
           android:layout_width="wrap_content"
           android:text="@string/upload"
           android:id="@+id/upload" />
    2. 点击上传,选择要上传的文件。

      函数实现片段:

      Button upload = (Button) findViewById(R.id.upload);
       upload.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               Intent i = new Intent(
                       Intent.ACTION_PICK,
                       android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
               startActivityForResult(i, RESULT_UPLOAD_IMAGE);
           }
       }
    3. 调用SDK的上传接口。

      函数实现片段:

      @Override
       protected void onActivityResult(int requestCode, int resultCode, Intent data) {
           super.onActivityResult(requestCode, resultCode, data);
           if ((requestCode == RESULT_UPLOAD_IMAGE || requestCode == RESULT_PAUSEABLEUPLOAD_IMAGE) && resultCode == RESULT_OK && null != data) {
               Uri selectedImage = data.getData();
               String[] filePathColumn = { MediaStore.Images.Media.DATA };
               Cursor cursor = getContentResolver().query(selectedImage,
                       filePathColumn, null, null, null);
               cursor.moveToFirst();
               int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
               String picturePath = cursor.getString(columnIndex);
               Log.d("PickPicture", picturePath);
               cursor.close();
               try {
                   Bitmap bm = ImageDisplayer.autoResizeFromLocalFile(picturePath);
                   displayImage(bm);
                   File file = new File(picturePath);
                   displayInfo("文件: " + picturePath + "\n大小: " + String.valueOf(file.length()));
               }
               catch (IOException e) {
                   e.printStackTrace();
                   displayInfo(e.toString());
               }
               //根据操作不同完成普通上传或者断点上传
               if (requestCode == RESULT_UPLOAD_IMAGE) {
                   final EditText editText = (EditText) findViewById(R.id.edit_text);
                   String objectName = editText.getText().toString();
                   //调用简单上传接口上传
                   ossService.asyncPutImage(objectName, picturePath, getPutCallback(), new ProgressCallbackFactory<PutObjectRequest>().get());
               }
           }
       }

      这里省略了对上传结果的处理,可以参考源码中的onSuccess和onFailure的处理。

基于分片上传实现的断点续传上传

调用OSS API中的MultipartUpload(分片上传)接口实现断点续传的效果。
  • 调用逻辑
    1. 选择上传后,可以选择需要上传的本地文件。
    2. OssDemo在获取sts_server的地址后,发送请求。
    3. sts_server返回AccessKeyId、AccessKeySecret、SecurityToken、Expiration。
    4. OssDemo获取这些信息后,调用SDK,构建OssClient,进行分片上传。
    5. 点击暂停时,如果分片上传没有结束,再点击继续时,可以接着未完成的地方继续上传,以达到断点续传的效果。
  • 具体代码
    1. 生成一个Button控件。
      位置:
       res/layout/content_main.xml
       内容:
       <Button
           style="?android:attr/buttonStyleSmall"
           android:layout_height="wrap_content"
           android:layout_width="wrap_content"
           android:text="@string/multipart_upload"
           android:id="@+id/multipart_upload" />
    2. 点击上传,选择要上传的文件。

      函数实现片段:

      Button multipart_upload = (Button) findViewById(R.id.multipart_upload);
       multipart_upload.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               //为了简单化,这里只会同时运行一个断点上传的任务
               Intent i = new Intent(
                       Intent.ACTION_PICK,
                       android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
               startActivityForResult(i, RESULT_PAUSEABLEUPLOAD_IMAGE);
           }
       }
       );
    3. 点击继续,完成断点续传。

      函数实现片段:

      //点击上传: 
      //这里调用SDK的分片上传接口来上传
      task = ossService.asyncMultiPartUpload(objectName, picturePath,getMultiPartCallback().addCallback(new Runnable() {
          @Override
          public void run() {
              pauseTaskStatus = TASK_NONE;       
              multipart_resume.setEnabled(false);       
              multipart_pause.setEnabled(false);
              task = null;
          }
      }), new ProgressCallbackFactory<PauseableUploadRequest>().get()); 
      
      //底层对SDK的封装逻辑,可以看到是在multiPartUploadManager中的asyncUpload实现的断点续传上传 
      //断点上传,返回的task可以用来暂停任务
      public PauseableUploadTask asyncMultiPartUpload(String object,
                                    String localFile,                                                    
                                    final OSSCompletedCallback<PauseableUploadRequest,PauseableUploadResult> userCallback,                                                   
                                    final OSSProgressCallback<PauseableUploadRequest>userProgressCallback) {
              if(object.equals("")) {           
                Log.w("AsyncMultiPartUpload", "ObjectNull");
                return null;
              }
              File file = new File(localFile);
              if (!file.exists()) {           
              Log.w("AsyncMultiPartUpload", "FileNotExist");          
              Log.w("LocalFile", localFile);
              return null;
              }        
              Log.d("MultiPartUpload", localFile);
              PauseableUploadTask task =
              multiPartUploadManager.asyncUpload(object, localFile, userCallback,userProgressCallback);
              return task;
          }