فهرست منبع

修改上传版本

Pq 1 سال پیش
والد
کامیت
f9fc50e6c3

+ 19 - 8
BaseLibrary/src/main/java/com/cooleshow/base/constanst/UploadConstants.java

@@ -4,11 +4,15 @@ package com.cooleshow.base.constanst;
  * Author by pq, Date on 2022/7/7.
  */
 public class UploadConstants {
-    //学上传作业(视频)
+    //学上传作业(视频)
     public static final String BUCKET_NAME_HOMEWORK = "homework";
-    //聊天上传视频 图片 文件(老师端和学端)
+    //聊天上传视频 图片 文件(老师端和学端)
     public static final String BUCKET_NAME_IM = "i-m";
 
+
+    //默认path
+    public static final String DEFAULT_PATH = "user";
+
     //1.用户上传头像
     //3.广告管理上传广告封面 广告视频
     //4.APP按钮管理 上传APP按钮图片
@@ -16,10 +20,13 @@ public class UploadConstants {
     //6.闪页管理 上传闪页图片
     //10.专业管理 上传声部图片
     //11.乐理章节管理  上传章节封面
-    //1.用户头像上传(老师端和学端)
+    //1.用户头像上传(老师端和学端)
     //3.老师端上传老师风采(视频)
     //达人认证
-    public static final String BUCKET_NAME_DAYA = "daya";
+    public static final String BUCKET_NAME_DEFAULT = "daya";
+    public static final String CLIENT_KEY= "klx/";
+    public static final String BUCKET_NAME_DEFAULT2 = "daya-online-1303457149";
+    public static final String PLUGIN_NAME = "tencent";
 
     public static final int UPLOAD_TYPE_HOMEWORK = 0;//对应BUCKET_NAME_HOMEWORK桶
     public static final int UPLOAD_TYPE_IM = 1;//对应BUCKET_NAME_IM桶
@@ -32,12 +39,16 @@ public class UploadConstants {
      * @return
      */
     public static String getBucketNameByType(int type) {
-        if (type == UPLOAD_TYPE_HOMEWORK) {
-            return BUCKET_NAME_HOMEWORK;
-        }
         if (type == UPLOAD_TYPE_IM) {
             return BUCKET_NAME_IM;
         }
-        return BUCKET_NAME_DAYA;
+        return BUCKET_NAME_DEFAULT;
+    }
+
+    public static String getPathByType(int type) {
+        if (type == UPLOAD_TYPE_IM) {
+            return "";
+        }
+        return DEFAULT_PATH;
     }
 }

+ 2 - 2
BaseLibrary/src/main/java/com/cooleshow/base/data/api/UploadApi.java

@@ -33,8 +33,8 @@ public interface UploadApi {
      * @param
      * @return
      */
-    @POST(TEACHER_GROUP + "getUploadSign")
-    Observable<BaseResponse<UploadTokenInfoBean>> getUploadTokenForTeacher(@Body RequestBody body);
+    @POST("{group_name}" + "/open/getUploadSign?pluginName=tencent")
+    Observable<BaseResponse<UploadTokenInfoBean>> getUploadTokenForTeacher(@Body RequestBody body, @Path("group_name") String group_name);
 
     /**
      * 根据月份获取老师该月有课的日期

+ 205 - 143
BaseLibrary/src/main/java/com/cooleshow/base/utils/helper/upload/UploadHelper.java

@@ -2,57 +2,49 @@ package com.cooleshow.base.utils.helper.upload;
 
 import android.app.Activity;
 import android.text.TextUtils;
-import android.util.Log;
 
 import com.cooleshow.base.bean.UploadTokenInfoBean;
+import com.cooleshow.base.common.BaseConstant;
 import com.cooleshow.base.constanst.UploadConstants;
 import com.cooleshow.base.data.api.UploadApi;
 import com.cooleshow.base.data.net.BaseResponse;
 import com.cooleshow.base.data.net.RetrofitFactory;
-import com.cooleshow.base.utils.ConversionUtil;
-import com.cooleshow.base.utils.DateUtil;
-import com.cooleshow.base.utils.EncodeUtils;
 import com.cooleshow.base.utils.FileUtils;
+import com.cooleshow.base.utils.LOG;
 import com.cooleshow.base.utils.LogUtils;
 import com.cooleshow.base.utils.RequestBodyUtil;
-import com.cooleshow.base.utils.SPUtils;
+import com.cooleshow.base.utils.ThreadUtils;
 import com.cooleshow.base.utils.TimeUtils;
 import com.cooleshow.base.utils.Utils;
-import com.cooleshow.base.widgets.ProgressLoading;
 import com.cooleshow.base.widgets.UploadProgressLoading;
-import com.ksyun.ks3.auth.AuthUtils;
-import com.ksyun.ks3.exception.Ks3Error;
-import com.ksyun.ks3.model.PostObjectFormFields;
-import com.ksyun.ks3.model.acl.Authorization;
-import com.ksyun.ks3.model.acl.CannedAccessControlList;
-import com.ksyun.ks3.services.AuthListener;
-import com.ksyun.ks3.services.Ks3Client;
-import com.ksyun.ks3.services.Ks3ClientConfiguration;
-import com.ksyun.ks3.services.handler.CreateBucketResponceHandler;
-import com.ksyun.ks3.services.handler.Ks3HttpResponceHandler;
-import com.ksyun.ks3.services.handler.PutObjectResponseHandler;
-import com.ksyun.ks3.services.request.PutObjectRequest;
-import com.ksyun.ks3.services.request.object.PostObjectRequest;
-import com.ksyun.ks3.util.Constants;
-
-import org.json.JSONArray;
+import com.tencent.cos.xml.CosXmlServiceConfig;
+import com.tencent.cos.xml.CosXmlSimpleService;
+import com.tencent.cos.xml.exception.CosXmlClientException;
+import com.tencent.cos.xml.exception.CosXmlServiceException;
+import com.tencent.cos.xml.listener.CosXmlProgressListener;
+import com.tencent.cos.xml.listener.CosXmlResultListener;
+import com.tencent.cos.xml.model.CosXmlRequest;
+import com.tencent.cos.xml.model.CosXmlResult;
+import com.tencent.cos.xml.model.tag.InitiateMultipartUpload;
+import com.tencent.cos.xml.transfer.COSXMLUploadTask;
+import com.tencent.cos.xml.transfer.InitMultipleUploadListener;
+import com.tencent.cos.xml.transfer.TransferConfig;
+import com.tencent.cos.xml.transfer.TransferManager;
+import com.tencent.cos.xml.transfer.TransferState;
+import com.tencent.cos.xml.transfer.TransferStateListener;
+import com.tencent.qcloud.core.auth.QCloudSelfSigner;
+import com.tencent.qcloud.core.common.QCloudClientException;
+import com.tencent.qcloud.core.http.HttpConstants;
+import com.tencent.qcloud.core.http.QCloudHttpRequest;
+
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import java.io.File;
-import java.security.SignatureException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import cz.msebera.android.httpclient.Header;
-import cz.msebera.android.httpclient.conn.ssl.SSLSocketFactory;
+
+import androidx.annotation.Nullable;
 import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
 import io.reactivex.rxjava3.annotations.NonNull;
-import io.reactivex.rxjava3.core.Observable;
-import io.reactivex.rxjava3.core.ObservableEmitter;
-import io.reactivex.rxjava3.core.ObservableOnSubscribe;
 import io.reactivex.rxjava3.core.Observer;
 import io.reactivex.rxjava3.disposables.Disposable;
 import io.reactivex.rxjava3.schedulers.Schedulers;
@@ -62,37 +54,43 @@ import okhttp3.RequestBody;
  * Author by pq, Date on 2022/5/11.
  */
 public class UploadHelper {
-    public static final String USER_ID = "user_id";
-    public String SRC_BUCKETNAME = UploadConstants.BUCKET_NAME_DAYA;
+    private static final String TAG = "UploadHelper";
+    public String SRC_BUCKETNAME = UploadConstants.BUCKET_NAME_DEFAULT;
     public static final String END_POINT = "ks3-cn-beijing.ksyuncs.com";
     public static final String PROTOCOL = "https://";
     public static final String SRC_OBJECTKEY = "";
     public static final String DST_BUCKETNAME = "";
     public static final String ak = "AKLTtTeIbadpRG-pil4S0Q4m-Q";
     public static final String sk = "OB1HmNOfDNW95wHoxMkP6IPFZXormk2ngA800TkvKAw7ozhiJGRqrMnnV8ZrAU3WRQ==";
-    private Ks3Client mClient;
 
     private String uploadToken = "";
+    private String uploadSignature = "";
     private Activity mActivity;
     private UploadProgressLoading mProgressLoading;
     private String loadingTip = "";
-    private String mUserId;
+    private String path = "";
+    private CosXmlSimpleService mCosXmlService;
 
     public UploadHelper(Activity activity, int type) {
-        this(activity, UploadConstants.getBucketNameByType(type));
+        this(activity, UploadConstants.getBucketNameByType(type), UploadConstants.getPathByType(type));
     }
 
-    public UploadHelper(Activity activity, String bukName) {
+    public UploadHelper(Activity activity, String path) {
+        this(activity, UploadConstants.BUCKET_NAME_DEFAULT, !TextUtils.isEmpty(path) ? path : UploadConstants.DEFAULT_PATH);
+    }
+
+    public UploadHelper(Activity activity, String bukName, String path) {
         this.mActivity = activity;
         //获取桶名称
         SRC_BUCKETNAME = bukName;
-        mUserId = SPUtils.getInstance().getString(USER_ID);
         if (TextUtils.isEmpty(bukName)) {
-            SRC_BUCKETNAME = UploadConstants.BUCKET_NAME_DAYA;
+            SRC_BUCKETNAME = UploadConstants.BUCKET_NAME_DEFAULT;
         }
+        this.path = UploadConstants.CLIENT_KEY + path;
         LogUtils.i("UploadHelper", "SRC_BUCKETNAME:" + SRC_BUCKETNAME);
+        LogUtils.i("UploadHelper", "PATH:" + path);
         initUploadProgressDialog();
-        initClient();
+        initTencent();
     }
 
     private void initUploadProgressDialog() {
@@ -101,138 +99,199 @@ public class UploadHelper {
                 return;
             }
             mProgressLoading = UploadProgressLoading.Companion.create(mActivity);
+            setLoadingTip("上传中");
         }
     }
 
-    private void initClient() {
-        Ks3ClientConfiguration configuration = Ks3ClientConfiguration.getDefaultConfiguration();
-        configuration.setSSLSocketFactory(SSLSocketFactory.getSocketFactory());
-        configuration.setDomainMode(true);
-        configuration.setPathStyleAccess(false);
-        configuration.setProtocol(Ks3ClientConfiguration.PROTOCOL.https);
-        mClient = new Ks3Client(new AuthListener() {
+    private void initTencent() {
+        QCloudSelfSigner qCloudSelfSigner = new QCloudSelfSigner() {
             @Override
-            public String onCalculateAuth(final String httpMethod,
-                                          final String ContentType, final String Date,
-                                          final String ContentMD5, final String Resource,
-                                          final String Headers) {
-                String token = "";
-                try {
-                    token = AuthUtils.calcAuthToken(httpMethod, ContentType, Date, ContentMD5, Resource, Headers, ak, sk);
-                    LogUtils.i("pq", "token:" + token);
-                } catch (SignatureException e) {
-                    e.printStackTrace();
-                }
-                return token;
+            public void sign(QCloudHttpRequest request) throws QCloudClientException {
+                String auth = uploadSignature;
+                // 2. 给请求添加签名
+                request.addHeader(HttpConstants.Header.AUTHORIZATION, auth);
             }
-        }, configuration, Utils.getApp());
-        mClient.setEndpoint(END_POINT);
+        };
+        // 存储桶所在地域简称,例如广州地区是 ap-guangzhou
+        String region = "ap-nanjing";
+
+
+        // 创建 CosXmlServiceConfig 对象,根据需要修改默认的配置参数
+        CosXmlServiceConfig serviceConfig = new CosXmlServiceConfig.Builder()
+                .setRegion(region)
+                .isHttps(true) // 使用 HTTPS 请求, 默认为 HTTP 请求
+                .builder();
+
+
+        // 通过服务端签名授权初始化 COS Service,获取实例
+        mCosXmlService = new CosXmlSimpleService(Utils.getApp(),
+                serviceConfig, qCloudSelfSigner);
+
     }
 
-    public void uploadFile(File file) {
-        if (!file.exists()) {
-            return;
-        }
-        String name = FileUtils.getFileName(file);
-        long nowTime = TimeUtils.getNowMills();
-        String timeStr = nowTime + "_" + mUserId;
-        if (name.contains(".")) {
-            String[] split = name.split("\\.");
-            name = timeStr + "." + split[split.length - 1];
-        } else {
-            name = "" + timeStr;
+    private void doUpload2(String key, File file) {
+        // 初始化 TransferConfig,这里使用默认配置,如果需要定制,请参考 SDK 接口文档
+        TransferConfig transferConfig = new TransferConfig.Builder()
+                .setForceSimpleUpload(true).build();
+        // 初始化 TransferManager
+        TransferManager transferManager = new TransferManager(mCosXmlService,
+                transferConfig);
+
+        // 存储桶名称,由 bucketname-appid 组成,appid 必须填入,可以在 COS 控制台查看存储桶名称。 https://console.cloud.tencent.com/cos5/bucket
+        String bucket = UploadConstants.BUCKET_NAME_DEFAULT2;
+        String cosPath = key; //对象在存储桶中的位置标识符,即称对象键
+        String srcPath = file.getAbsolutePath().toString(); //本地文件的绝对路径
+        // 若存在初始化分块上传的 UploadId,则赋值对应的 uploadId 值用于续传;否则,赋值 null
+        String uploadId = null;
+        // 上传文件
+        COSXMLUploadTask cosxmlUploadTask = transferManager.upload(bucket, cosPath,
+                srcPath, uploadId);
+        showUploadLoading();
+
+        if (upLoadCallBack != null) {
+            upLoadCallBack.onUploadStart();
         }
-        String lastName = name;
-        String month = TimeUtils.date2String(TimeUtils.getNowDate(), TimeUtils.getSafeDateFormat("yyyy-MM"));
-        String day = String.valueOf(DateUtil.dayOfMonth());
-        String key = "android/" + month + "/" + day + "/" + lastName;
-        getUploadToken(name, key, file);
-    }
 
-    private String getBaseResult(long timeStr) {
-//        Log.i("UploadHelper", "timeStr:" + timeStr);
-//        byte[] bytes = String.valueOf(timeStr).getBytes();
-//        String timeStrLast = EncodeUtils.base64Encode2String(bytes);
-//        Log.i("UploadHelper", "timeStrLast:" + timeStrLast);
-//        byte[] bytes1 = EncodeUtils.base64Decode(timeStrLast);
-//        String result = new String(bytes1);
-//        Log.i("UploadHelper", "result:" + result);
-        String encode = ConversionUtil.encode(timeStr);
-        return encode;
-    }
 
-    private void doUpload(String key, File file) {
-        PutObjectRequest putObjectRequest = new PutObjectRequest(SRC_BUCKETNAME, key, file);
-        putObjectRequest.setCannedAcl(CannedAccessControlList.PublicRead);
-        mClient.putObject(putObjectRequest, new PutObjectResponseHandler() {
+        //设置初始化分块上传回调(5.9.7版本以及后续版本支持)
+        cosxmlUploadTask.setInitMultipleUploadListener(new InitMultipleUploadListener() {
             @Override
-            public void onTaskFailure(int i, Ks3Error ks3Error, Header[] headers, String s, Throwable throwable) {
-                if (throwable != null) {
-                    throwable.printStackTrace();
-                }
-                hideUploadLoading();
-                if (upLoadCallBack != null) {
-                    upLoadCallBack.onFailure();
-                }
-                LogUtils.i("pq", "onFailure postObject is " + ks3Error.getErrorMessage());
+            public void onSuccess(InitiateMultipartUpload initiateMultipartUpload) {
+                //用于下次续传上传的 uploadId
+                String uploadId = initiateMultipartUpload.uploadId;
             }
-
+        });
+        //设置上传进度回调
+        cosxmlUploadTask.setCosXmlProgressListener(new CosXmlProgressListener() {
             @Override
-            public void onTaskSuccess(int i, Header[] headers) {
-                hideUploadLoading();
-                if (null != upLoadCallBack) {
-                    upLoadCallBack.onSuccess(buildUploadUrl(key));
-                }
-                LogUtils.i("pq", "onSuccess postObject is " + i);
+            public void onProgress(long complete, long target) {
+                // todo Do something to update progress...
+                LOG.i(TAG, "tencent upload:onProgress-" + complete + "--target:" + target + "----Thread:" + Thread.currentThread().getName());
+                ThreadUtils.runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        double v = (complete * 1.0d / target) * 100;
+                        LOG.i(TAG, "tencent upload:v=" + v + "----Thread:" + Thread.currentThread().getName());
+                        if (mProgressLoading != null) {
+                            if (!TextUtils.isEmpty(loadingTip)) {
+                                mProgressLoading.setProgress(v, loadingTip);
+                            } else {
+                                mProgressLoading.setProgress(v);
+                            }
+                        }
+                        if (upLoadCallBack != null) {
+                            upLoadCallBack.onUploadProgress(v);
+                        }
+                    }
+                });
             }
-
+        });
+        //设置返回结果回调
+        cosxmlUploadTask.setCosXmlResultListener(new CosXmlResultListener() {
             @Override
-            public void onTaskStart() {
-                showUploadLoading();
-                if (upLoadCallBack != null) {
-                    upLoadCallBack.onUploadStart();
-                }
+            public void onSuccess(CosXmlRequest request, CosXmlResult result) {
+                COSXMLUploadTask.COSXMLUploadTaskResult uploadResult =
+                        (COSXMLUploadTask.COSXMLUploadTaskResult) result;
+                LOG.i(TAG, "tencent upload:onSuccess-" + "----Thread:" + Thread.currentThread().getName());
+                ThreadUtils.runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        hideUploadLoading();
+                        if (null != upLoadCallBack && uploadResult != null) {
+                            upLoadCallBack.onSuccess(uploadResult.accessUrl);
+                        }
+                    }
+                });
             }
 
-            @Override
-            public void onTaskFinish() {
-                hideUploadLoading();
-                if (upLoadCallBack != null) {
-                    upLoadCallBack.onUploadFinish();
-                }
-            }
 
+            // 如果您使用 kotlin 语言来调用,请注意回调方法中的异常是可空的,否则不会回调 onFail 方法,即:
+            // clientException 的类型为 CosXmlClientException?,serviceException 的类型为 CosXmlServiceException?
             @Override
-            public void onTaskCancel() {
-                hideUploadLoading();
-                if (upLoadCallBack != null) {
-                    upLoadCallBack.onUploadCancel();
+            public void onFail(CosXmlRequest request,
+                               @Nullable CosXmlClientException clientException,
+                               @Nullable CosXmlServiceException serviceException) {
+                if (clientException != null) {
+                    clientException.printStackTrace();
+                } else {
+                    serviceException.printStackTrace();
                 }
+                ThreadUtils.runOnUiThread(new Runnable() {
+                    @Override
+                    public void run() {
+                        hideUploadLoading();
+                        if (upLoadCallBack != null) {
+                            upLoadCallBack.onFailure();
+                        }
+                        LogUtils.i("pq", "onFailure upload");
+                    }
+                });
             }
-
+        });
+        //设置任务状态回调, 可以查看任务过程
+        cosxmlUploadTask.setTransferStateListener(new TransferStateListener() {
             @Override
-            public void onTaskProgress(double v) {
-                if (mProgressLoading != null) {
-                    if (!TextUtils.isEmpty(loadingTip)) {
-                        mProgressLoading.setProgress(v, loadingTip);
-                    } else {
-                        mProgressLoading.setProgress(v);
-                    }
-                }
-                if (upLoadCallBack != null) {
-                    upLoadCallBack.onUploadProgress(v);
+            public void onStateChanged(TransferState state) {
+                // todo notify transfer state
+                if (state != null) {
+                    ThreadUtils.runOnUiThread(new Runnable() {
+                        @Override
+                        public void run() {
+                            LOG.i(TAG, "onStateChanged" + "----Thread:" + Thread.currentThread().getName());
+                            if (state == TransferState.CANCELED) {
+                                hideUploadLoading();
+                                if (upLoadCallBack != null) {
+                                    upLoadCallBack.onUploadCancel();
+                                }
+                            }
+                        }
+                    });
                 }
             }
         });
+
+    }
+
+    public void uploadFile(File file) {
+        if (!file.exists()) {
+            return;
+        }
+        String name = FileUtils.getFileName(file);
+        long timeStr = TimeUtils.getNowMills();
+        if (name.contains(".")) {
+            String[] split = name.split("\\.");
+            name = timeStr + "." + split[split.length - 1];
+        } else {
+            name = "" + timeStr;
+        }
+        String lastName = name;
+        String month = TimeUtils.date2String(TimeUtils.getNowDate(), TimeUtils.getSafeDateFormat("yyyy-MM"));
+        String key = formatPath(path) + "android/" + month + "/" + lastName;
+        getUploadToken(name, key, file);
+    }
+
+    private String formatPath(String path) {
+        if (TextUtils.isEmpty(path)) {
+            return "";
+        }
+        if (path.startsWith("/")) {
+            path = path.replaceFirst("/+", "");
+        }
+        if (!path.endsWith("/")) {
+            path = path + "/";
+        }
+        return path;
     }
 
     private void getUploadToken(String fileName, String key, File file) {
+        LogUtils.i(TAG, "fileName:" + fileName);
+        LogUtils.i(TAG, "key:" + key);
         JSONObject jsonObject = new JSONObject();
         try {
             JSONObject postDataJson = new JSONObject();
-            postDataJson.put("acl", CannedAccessControlList.PublicRead);
             postDataJson.put("key", key);
             jsonObject.putOpt("filename", fileName);
+            jsonObject.putOpt("bucketName", UploadConstants.BUCKET_NAME_DEFAULT2);
             jsonObject.putOpt("postData", postDataJson);
         } catch (JSONException e) {
             e.printStackTrace();
@@ -240,7 +299,7 @@ public class UploadHelper {
         RequestBody body = RequestBodyUtil.convertToRequestBodyJson(jsonObject.toString());
 
         UploadApi uploadApi = RetrofitFactory.Companion.getInstance().create(UploadApi.class);
-        uploadApi.getUploadTokenForTeacher(body).subscribeOn(Schedulers.io())
+        uploadApi.getUploadTokenForTeacher(body, BaseConstant.CLIENT_API_GROUP_NAME).subscribeOn(Schedulers.io())
                 .observeOn(AndroidSchedulers.mainThread())
                 .subscribe(new Observer<BaseResponse<UploadTokenInfoBean>>() {
                     @Override
@@ -252,7 +311,9 @@ public class UploadHelper {
                     public void onNext(@NonNull BaseResponse<UploadTokenInfoBean> response) {
                         if (response != null && response.getData() != null) {
                             uploadToken = "KSS " + response.getData().kssAccessKeyId + ":" + response.getData().signature;
-                            doUpload(key, file);
+                            uploadSignature = response.getData().signature;
+//                            doUpload(key, file);
+                            doUpload2(key, file);
                         }
                     }
 
@@ -293,6 +354,7 @@ public class UploadHelper {
         }
         if (mProgressLoading != null && !mProgressLoading.isShowing()) {
             mProgressLoading.showLoading();
+            mProgressLoading.setProgress(0, loadingTip);
         }
     }