Pārlūkot izejas kodu

添加金山云上传逻辑

Pq 3 gadi atpakaļ
vecāks
revīzija
1e8d299a96

+ 9 - 1
BaseLibrary/build.gradle

@@ -47,6 +47,12 @@ android {
     buildFeatures {
         viewBinding = true
     }
+
+    sourceSets {
+        main {
+            jniLibs.srcDirs = ['libs']
+        }
+    }
 }
 
 kapt {
@@ -56,7 +62,7 @@ kapt {
 }
 
 dependencies {
-
+    api fileTree(dir: 'libs', include: ['*.jar','*.aar'])
     testImplementation 'junit:junit:4.13.2'
     androidTestImplementation 'androidx.test.ext:junit:1.1.3'
     androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
@@ -136,4 +142,6 @@ dependencies {
     api "com.github.tbruyelle:rxpermissions:0.12"
 
     api 'com.github.mcxtzhang:SuspensionIndexBar:V1.0.0'
+    //金山云上传所需
+    api 'joda-time:joda-time:2.9.9'
 }

BIN
BaseLibrary/libs/ks3-androidsdk-1.5.0.jar


+ 2 - 0
BaseLibrary/src/main/AndroidManifest.xml

@@ -4,6 +4,8 @@
 
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <application />
 
 </manifest>

+ 19 - 0
BaseLibrary/src/main/java/com/cooleshow/base/bean/UploadTokenInfoBean.java

@@ -0,0 +1,19 @@
+package com.cooleshow.base.bean;
+
+import java.io.Serializable;
+
+/**
+ * Author by pq, Date on 2022/5/11.
+ */
+public class UploadTokenInfoBean {
+
+    /**
+     * kssAccessKeyId :
+     * policy :
+     * signature :
+     */
+
+    public String kssAccessKeyId;
+    public String policy;
+    public String signature;
+}

+ 1 - 0
BaseLibrary/src/main/java/com/cooleshow/base/common/BaseConstant.java

@@ -8,6 +8,7 @@ import com.cooleshow.base.BuildConfig;
 public class BaseConstant {
     public final static String SERVER_ADDRESS= BuildConfig.BASE_SERVER_URL;
     public final static String TEACHER_GROUP = "api-teacher/";
+    public final static String STUDENT_GROUP = "api-student/";
     public final static String AUTH_GROUP = "api-auth/";
 
 

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

@@ -0,0 +1,37 @@
+package com.cooleshow.base.data.api;
+
+import com.cooleshow.base.bean.UploadTokenInfoBean;
+import com.cooleshow.base.data.net.BaseResponse;
+
+import java.util.List;
+
+import io.reactivex.rxjava3.core.Observable;
+import okhttp3.RequestBody;
+import retrofit2.http.Body;
+import retrofit2.http.POST;
+
+import static com.cooleshow.base.common.BaseConstant.TEACHER_GROUP;
+import static com.cooleshow.base.common.BaseConstant.STUDENT_GROUP;
+
+/**
+ * Author by pq, Date on 2022/5/11.
+ */
+public interface UploadApi {
+    /**
+     * 根据月份获取老师该月有课的日期
+     *
+     * @param
+     * @return
+     */
+    @POST(TEACHER_GROUP + "getUploadSign")
+    Observable<BaseResponse<UploadTokenInfoBean>> getUploadTokenForTeacher(@Body RequestBody body);
+
+    /**
+     * 根据月份获取老师该月有课的日期
+     *
+     * @param
+     * @return
+     */
+    @POST(STUDENT_GROUP + "getUploadSign")
+    Observable<BaseResponse<UploadTokenInfoBean>> getUploadTokenForStudent(@Body RequestBody body);
+}

+ 23 - 0
BaseLibrary/src/main/java/com/cooleshow/base/utils/helper/upload/UploadConfig.java

@@ -0,0 +1,23 @@
+package com.cooleshow.base.utils.helper.upload;
+
+/**
+ * Author by pq, Date on 2022/5/11.
+ */
+class UploadConfig {
+    // 测试用AK&SK
+    public static final String ACCESS_KEY__ID = "<yourAccessKeyId>";
+    public static final String ACCESS_KEY_SECRET = "<yourAccessSecretKey>";
+    // 访问的endpoint地址
+    public static final String END_POINT = "<yourEndPoint>";
+    // bucket名称
+    public static final String BUCKET_NAME = "ks3-cn-beijing.ksyuncs.com";
+    // 重试时长
+    public static final int  RETRY_TIMEOUT = 3000;
+    // 最大重连次数
+    public static final int MAX_RETRY_TIME = 10;
+
+    // 上传到bucket的object key
+    public static final String OBJECT_KEY = "test.jpg";
+    // 下载到本地的文件名称
+    public static final String DOWNLOAD_FILE_NAME = "formKs3.jpg";
+}

+ 179 - 0
BaseLibrary/src/main/java/com/cooleshow/base/utils/helper/upload/UploadHelper.java

@@ -0,0 +1,179 @@
+package com.cooleshow.base.utils.helper.upload;
+
+import android.app.Activity;
+
+import com.cooleshow.base.bean.UploadTokenInfoBean;
+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.FileUtils;
+import com.cooleshow.base.utils.LogUtils;
+import com.cooleshow.base.utils.RequestBodyUtil;
+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 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 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;
+import okhttp3.RequestBody;
+
+/**
+ * Author by pq, Date on 2022/5/11.
+ */
+public class UploadHelper {
+    public static final String SRC_BUCKETNAME = "daya";
+    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==";
+    public Activity mActivity;
+    private Ks3Client mClient;
+
+    private String uploadToken = "";
+
+    public UploadHelper(Activity activity) {
+        this.mActivity = activity;
+        initClient();
+    }
+
+    private void initClient() {
+        Ks3ClientConfiguration configuration = Ks3ClientConfiguration.getDefaultConfiguration();
+        configuration.setSSLSocketFactory(SSLSocketFactory.getSocketFactory());
+        configuration.setDomainMode(true);
+        configuration.setPathStyleAccess(true);
+        configuration.setProtocol(Ks3ClientConfiguration.PROTOCOL.https);
+        mClient = new Ks3Client(new AuthListener() {
+            @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;
+            }
+        }, configuration, mActivity.getApplicationContext());
+        mClient.setEndpoint("ks3-cn-beijing.ksyuncs.com");
+    }
+
+    public void uploadFile(File file) {
+        if (!file.exists()) {
+            return;
+        }
+        String name = FileUtils.getFileName(file) + System.currentTimeMillis();
+        String key = "androidtest/" + name;
+        getUploadToken(name, key, file);
+    }
+
+    private void doUpload(String key, File file) {
+        PutObjectRequest putObjectRequest = new PutObjectRequest("daya", key, file);
+        putObjectRequest.setCannedAcl(CannedAccessControlList.PublicRead);
+        mClient.putObject(putObjectRequest, new PutObjectResponseHandler() {
+            @Override
+            public void onTaskFailure(int i, Ks3Error ks3Error, Header[] headers, String s, Throwable throwable) {
+                LogUtils.i("pq", "onFailure postObject is " + s);
+            }
+
+            @Override
+            public void onTaskSuccess(int i, Header[] headers) {
+                LogUtils.i("pq", "onSuccess postObject is " + i);
+            }
+
+            @Override
+            public void onTaskStart() {
+
+            }
+
+            @Override
+            public void onTaskFinish() {
+
+            }
+
+            @Override
+            public void onTaskCancel() {
+
+            }
+
+            @Override
+            public void onTaskProgress(double v) {
+
+            }
+        });
+    }
+
+    private void getUploadToken(String fileName, String key, File file) {
+        JSONObject jsonObject = new JSONObject();
+        try {
+            JSONObject postDataJson = new JSONObject();
+            postDataJson.put("acl", CannedAccessControlList.PublicRead);
+            postDataJson.put("key", key);
+            jsonObject.putOpt("filename", fileName);
+            jsonObject.putOpt("postData", postDataJson);
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+        RequestBody body = RequestBodyUtil.convertToRequestBodyJson(jsonObject.toString());
+
+        UploadApi uploadApi = RetrofitFactory.Companion.getInstance().create(UploadApi.class);
+        uploadApi.getUploadTokenForTeacher(body).subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe(new Observer<BaseResponse<UploadTokenInfoBean>>() {
+                    @Override
+                    public void onSubscribe(@NonNull Disposable d) {
+
+                    }
+
+                    @Override
+                    public void onNext(@NonNull BaseResponse<UploadTokenInfoBean> response) {
+                        uploadToken = "KSS " + response.getData().kssAccessKeyId + ":" + response.getData().signature;
+                        doUpload(key, file);
+                    }
+
+                    @Override
+                    public void onError(@NonNull Throwable e) {
+                        uploadToken = "";
+                    }
+
+                    @Override
+                    public void onComplete() {
+
+                    }
+                });
+    }
+
+}

+ 0 - 0
live_teaching/src/main/res/drawable/checkbox_selector.xml → BaseLibrary/src/main/res/drawable/checkbox_selector.xml


+ 11 - 1
teacher/build.gradle

@@ -26,6 +26,8 @@ android {
 
     signingConfigs {
         release {
+            v1SigningEnabled true
+            v2SigningEnabled true
             storeFile file("../cooleshow.jks")
             //签名文件
             storePassword "cooleshow"
@@ -60,10 +62,18 @@ android {
     buildFeatures {
         viewBinding = true
     }
+
+
+    repositories {
+        flatDir {
+            dirs 'libs'
+        }
+
+    }
 }
 
 dependencies {
-
+    api fileTree(dir: 'libs', include: ['*.jar'])
     implementation 'androidx.core:core-ktx:1.7.0'
     implementation 'androidx.appcompat:appcompat:1.3.0'
     implementation 'com.google.android.material:material:1.4.0'

+ 40 - 43
teacher/src/main/java/com/cooleshow/teacher/ui/web/WebActivity.java

@@ -22,11 +22,14 @@ import com.cooleshow.base.BuildConfig;
 import com.cooleshow.base.common.WebConstants;
 import com.cooleshow.base.router.RouterPath;
 import com.cooleshow.base.ui.activity.BaseActivity;
+import com.cooleshow.base.utils.FileUtils;
 import com.cooleshow.base.utils.LogUtils;
 import com.cooleshow.base.utils.PermissionUtils;
 import com.cooleshow.base.utils.ToastUtil;
+import com.cooleshow.base.utils.UriUtils;
 import com.cooleshow.base.utils.Utils;
 import com.cooleshow.base.utils.helper.QMUIStatusBarHelper;
+import com.cooleshow.base.utils.helper.upload.UploadHelper;
 import com.cooleshow.teacher.widgets.helper.JsInterfaceHelper;
 import com.cooleshow.base.widgets.WebClient;
 import com.cooleshow.base.widgets.dialog.CommonDialog;
@@ -35,13 +38,13 @@ import com.cooleshow.teacher.databinding.ActivityHtmlBinding;
 import com.cooleshow.base.widgets.LollipopFixedWebView;
 import com.cooleshow.usercenter.helper.UserHelper;
 import com.daya.live_teaching.utils.GlideEngine;
+import com.ksyun.ks3.services.Ks3Client;
 import com.luck.picture.lib.PictureSelector;
 import com.luck.picture.lib.config.PictureConfig;
 import com.luck.picture.lib.config.PictureMimeType;
 import com.luck.picture.lib.entity.LocalMedia;
 import com.luck.picture.lib.tools.PictureFileUtils;
 import com.tbruyelle.rxpermissions3.RxPermissions;
-import com.yalantis.ucrop.util.FileUtils;
 
 import org.json.JSONObject;
 
@@ -204,6 +207,14 @@ public class WebActivity extends BaseActivity<ActivityHtmlBinding> implements Js
 
     }
 
+    @Override
+    public void chooseFile(JSONObject message) {
+        JSONObject content = (JSONObject) message.opt("content");
+        String type = (String) content.opt("image/*");
+        String[] types = new String[]{type};
+        showFileChooser();
+    }
+
     /**
      * 获取状态栏高度
      *
@@ -331,22 +342,13 @@ public class WebActivity extends BaseActivity<ActivityHtmlBinding> implements Js
         super.onConfigurationChanged(newConfig);
     }
 
-    private void showFileChooser(String[] contentTypes) {
-
-        Intent intent1 = new Intent(Intent.ACTION_GET_CONTENT);
-        intent1.addCategory(Intent.CATEGORY_OPENABLE);
-        if (contentTypes.length == 0) {
-            intent1.setType("*/*");
-        } else {
-            for (int i = 0; i < contentTypes.length; i++) {
-                intent1.setType(contentTypes[i]);
-            }
-        }
-        Intent chooser = new Intent(Intent.ACTION_CHOOSER);
-        chooser.putExtra(Intent.EXTRA_TITLE, "File Chooser");
-        chooser.putExtra(Intent.EXTRA_INTENT, intent1);
-//        chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]{intent2});
-        startActivityForResult(chooser, REQUEST_CODE_FILE_CHOOSER);
+    private void showFileChooser() {
+        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
+        intent.setType("*/*");
+        intent.addCategory(Intent.CATEGORY_OPENABLE);
+        intent.putExtra(Intent.EXTRA_TITLE, "File Chooser");
+        intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
+        startActivityForResult(intent, REQUEST_CODE_FILE_CHOOSER);
     }
 
     private void startFileSelect(WebChromeClient.FileChooserParams fileChooserParams) {
@@ -354,7 +356,7 @@ public class WebActivity extends BaseActivity<ActivityHtmlBinding> implements Js
                 .request(Manifest.permission.READ_EXTERNAL_STORAGE)
                 .subscribe(permission -> {
                     if (permission) {
-                        showFileChooser(fileChooserParams.getAcceptTypes());
+                        showFileChooser();
                     } else {
                         String tip = "上传文件需要储存卡读取权限,是否去设置?";
                         showCommonTipDialog(tip);
@@ -402,6 +404,8 @@ public class WebActivity extends BaseActivity<ActivityHtmlBinding> implements Js
     @Override
     protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
+        LogUtils.i("pq", "requestCode" + requestCode);
+        LogUtils.i("pq", "resultCode" + resultCode);
         if (requestCode == PictureConfig.CHOOSE_REQUEST && mUploadCallbackAboveL != null) {
             // 图片、视频、音频选择结果回调
             List<LocalMedia> selectList = PictureSelector.obtainMultipleResult(data);
@@ -417,32 +421,25 @@ public class WebActivity extends BaseActivity<ActivityHtmlBinding> implements Js
         }
         if (requestCode == REQUEST_CODE_FILE_CHOOSER) {
             Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
-//            if (result == null && !TextUtils.isEmpty(mCameraFilePath)) {
-//                // 看是否从相机返回
-//                File cameraFile = new File(mCameraFilePath);
-//                if (cameraFile.exists()) {
-//                    result = Uri.fromFile(cameraFile);
-//                    sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
-//                }
-//            }
             if (result != null) {
-                String path = FileUtils.getPath(this, result);
-                if (!TextUtils.isEmpty(path)) {
-                    File f = new File(path);
-                    if (f.exists() && f.isFile()) {
-                        Uri newUri = Uri.fromFile(f);
-                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
-                            if (mUploadCallbackAboveL != null) {
-                                if (newUri != null) {
-                                    mUploadCallbackAboveL.onReceiveValue(new Uri[]{newUri});
-                                    mUploadCallbackAboveL = null;
-                                    return;
-                                }
-                            }
-                        }
-                    } else {
-                        ToastUtil.getInstance().show(WebActivity.this, "文件损坏或不存在,请重新选择");
-                    }
+                File file = UriUtils.uri2File(result);
+                if (file != null && file.exists()) {
+                    UploadHelper uploadHelper = new UploadHelper(WebActivity.this);
+                    uploadHelper.uploadFile(file);
+//                    if (f.exists() && f.isFile()) {
+//                        Uri newUri = Uri.fromFile(f);
+//                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+//                            if (mUploadCallbackAboveL != null) {
+//                                if (newUri != null) {
+//                                    mUploadCallbackAboveL.onReceiveValue(new Uri[]{newUri});
+//                                    mUploadCallbackAboveL = null;
+//                                    return;
+//                                }
+//                            }
+//                        }
+//                    } else {
+//                        ToastUtil.getInstance().show(WebActivity.this, "文件损坏或不存在,请重新选择");
+//                    }
                 }
             }
             clearUploadMessage();

+ 15 - 0
teacher/src/main/java/com/cooleshow/teacher/widgets/helper/JsInterfaceHelper.java

@@ -28,6 +28,7 @@ public class JsInterfaceHelper extends Object {
     public static final String BACKICONCHANGE = "backIconChange";//顶部栏返回按钮颜色
     public static final String SETBARSTATUS = "setBarStatus";//顶部栏控制
     public static final String FINISH = "back";//结束本页面
+    public static final String CHOOSEFILE = "chooseFile";//选择文件
 
     private Activity activity;
     JSONObject resultJson;
@@ -93,6 +94,14 @@ public class JsInterfaceHelper extends Object {
             activity.finish();
             return;
         }
+
+        if(TextUtils.equals(CHOOSEFILE,api)){
+            //选择文件
+            if (onListener != null) {
+                onListener.chooseFile(jsonObject);
+            }
+            return;
+        }
     }
 
 
@@ -119,6 +128,12 @@ public class JsInterfaceHelper extends Object {
         void backIconChange(JSONObject message);
 
         /**
+         * 选择文件
+         * @param message
+         */
+        void chooseFile(JSONObject message);
+
+        /**
          * 返回顶部高度
          * 顶部栏高度
          * 以及dpi