Browse Source

增加H5页面流程,增加保存文件和分享功能api

Pq 1 year ago
parent
commit
1b5c4a22f9
25 changed files with 872 additions and 48 deletions
  1. 1 0
      BaseLibrary/build.gradle
  2. BIN
      BaseLibrary/libs/filedownload-1.0.0.aar
  3. 25 0
      BaseLibrary/src/main/java/com/cooleshow/base/bean/DownloadTaskBean.java
  4. 91 0
      BaseLibrary/src/main/java/com/cooleshow/base/utils/FileUtils.java
  5. 8 0
      BaseLibrary/src/main/java/com/cooleshow/base/utils/NetworkUtil.java
  6. 242 0
      BaseLibrary/src/main/java/com/cooleshow/base/utils/helper/DownloadHelper.java
  7. 0 44
      chatModule/src/main/java/com/cooleshow/chatmodule/utils/helper/IMShareHelper.java
  8. 1 1
      student/build.gradle
  9. BIN
      student/libs/filedownload-1.0.0.aar
  10. BIN
      student/libs/rong_player_5.2.4.aar
  11. 1 1
      student/src/main/AndroidManifest.xml
  12. 39 0
      student/src/main/java/com/cooleshow/student/App.java
  13. 60 0
      student/src/main/java/com/cooleshow/student/helper/ShareHelper.java
  14. 10 0
      student/src/main/java/com/cooleshow/student/ui/main/MallFragment.java
  15. 123 0
      student/src/main/java/com/cooleshow/student/ui/web/HtmlActivity.java
  16. 10 0
      student/src/main/java/com/cooleshow/student/ui/web/HtmlHorizontalScreenActivity.java
  17. 19 0
      student/src/main/java/com/cooleshow/student/widgets/helper/JsInterfaceUtils.java
  18. 2 1
      teacher/build.gradle
  19. BIN
      teacher/libs/filedownload-1.0.0.aar
  20. BIN
      teacher/libs/rong_player_5.2.4.aar
  21. 1 1
      teacher/src/main/AndroidManifest.xml
  22. 40 0
      teacher/src/main/java/com/cooleshow/teacher/App.java
  23. 59 0
      teacher/src/main/java/com/cooleshow/teacher/helper/ShareHelper.java
  24. 121 0
      teacher/src/main/java/com/cooleshow/teacher/ui/web/HtmlActivity.java
  25. 19 0
      teacher/src/main/java/com/cooleshow/teacher/widgets/helper/JsInterfaceUtils.java

+ 1 - 0
BaseLibrary/build.gradle

@@ -209,4 +209,5 @@ dependencies {
 
     compileOnly files('libs/emoji-ios-release.aar')
     compileOnly files('libs/emoji-release.aar')
+    compileOnly files('libs/filedownload-1.0.0.aar')
 }

BIN
BaseLibrary/libs/filedownload-1.0.0.aar


+ 25 - 0
BaseLibrary/src/main/java/com/cooleshow/base/bean/DownloadTaskBean.java

@@ -0,0 +1,25 @@
+package com.cooleshow.base.bean;
+
+/**
+ * Author by pq, Date on 2023/1/11.
+ */
+public class DownloadTaskBean {
+    private String url;
+    private String savePath;
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getSavePath() {
+        return savePath;
+    }
+
+    public void setSavePath(String savePath) {
+        this.savePath = savePath;
+    }
+}

+ 91 - 0
BaseLibrary/src/main/java/com/cooleshow/base/utils/FileUtils.java

@@ -1790,6 +1790,97 @@ public final class FileUtils {
         return true;
     }
 
+    public static boolean saveAudioToMusic(Context context, String filePath) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
+            return saveAudioToMusicBeforeQ(context, filePath);
+        } else {
+            return saveAudioToMusicAfterQ(context, filePath);
+        }
+    }
+
+    /**
+     * 获取视频的contentValue
+     */
+    public static ContentValues getAudioContentValues(Context context, File paramFile, long timestamp) {
+        ContentValues localContentValues = new ContentValues();
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+            localContentValues.put(MediaStore.Video.Media.RELATIVE_PATH, Environment.DIRECTORY_DCIM
+                    + File.separator + context.getPackageName());
+        }
+        localContentValues.put(MediaStore.Audio.Media.TITLE, paramFile.getName());
+        localContentValues.put(MediaStore.Audio.Media.DISPLAY_NAME, paramFile.getName());
+        localContentValues.put(MediaStore.Audio.Media.MIME_TYPE, "audio/mp3");
+        localContentValues.put(MediaStore.Audio.Media.RELATIVE_PATH, "Music/yyszkt");
+        localContentValues.put(MediaStore.Audio.Media.DATE_TAKEN, timestamp);
+        localContentValues.put(MediaStore.Audio.Media.DATE_MODIFIED, timestamp);
+        localContentValues.put(MediaStore.Audio.Media.DATE_ADDED, timestamp);
+        localContentValues.put(MediaStore.Audio.Media.SIZE, paramFile.length());
+        localContentValues.put(MediaStore.Audio.Media.IS_RINGTONE, true);
+        localContentValues.put(MediaStore.Audio.Media.IS_NOTIFICATION, false);
+        localContentValues.put(MediaStore.Audio.Media.IS_ALARM, false);
+        localContentValues.put(MediaStore.Audio.Media.IS_MUSIC, false);
+        return localContentValues;
+    }
+
+    private static boolean saveAudioToMusicAfterQ(Context context, String audioFilePath) {
+        try {
+            ContentResolver contentResolver = context.getContentResolver();
+            File tempFile = new File(audioFilePath);
+            ContentValues contentValues = getAudioContentValues(context, tempFile, System.currentTimeMillis());
+            Uri uri = contentResolver.insert(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, contentValues);
+            copyFileAfterQ(context, contentResolver, tempFile, uri);
+            contentValues.clear();
+            contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0);
+            context.getContentResolver().update(uri, contentValues, null, null);
+            context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri));
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    private static boolean saveAudioToMusicBeforeQ(Context context, String audioFile) {
+        File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC);
+        File tempFile = new File(audioFile);
+        File destFile = new File(picDir, "yyszkt" + File.separator + tempFile.getName());
+        FileInputStream ins = null;
+        BufferedOutputStream ous = null;
+        try {
+            ins = new FileInputStream(tempFile);
+            ous = new BufferedOutputStream(new FileOutputStream(destFile));
+            long nread = 0L;
+            byte[] buf = new byte[1024];
+            int n;
+            while ((n = ins.read(buf)) > 0) {
+                ous.write(buf, 0, n);
+                nread += n;
+            }
+            MediaScannerConnection.scanFile(
+                    context,
+                    new String[]{destFile.getAbsolutePath()},
+                    new String[]{"audio/*"},
+                    (path, uri) -> {
+                        // Scan Completed
+                    });
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        } finally {
+            try {
+                if (ins != null) {
+                    ins.close();
+                }
+                if (ous != null) {
+                    ous.close();
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
     public static boolean saveVideoToGallery(Context context, String filePath) {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
             return saveVideoToAlbumBeforeQ(context, filePath);

+ 8 - 0
BaseLibrary/src/main/java/com/cooleshow/base/utils/NetworkUtil.java

@@ -169,4 +169,12 @@ public class NetworkUtil {
         }
     }
 
+    public static boolean isWifiNetwork(Context context) {
+        int netWorkType = NetworkUtil.getNetWorkType(context);
+        if (netWorkType == NetworkUtil.NETWORKTYPE_WIFI) {
+            return true;
+        }
+        return false;
+    }
+
 }

+ 242 - 0
BaseLibrary/src/main/java/com/cooleshow/base/utils/helper/DownloadHelper.java

@@ -0,0 +1,242 @@
+package com.cooleshow.base.utils.helper;
+
+import android.util.Log;
+
+import com.cooleshow.base.bean.DownloadTaskBean;
+import com.liulishuo.filedownloader.BaseDownloadTask;
+import com.liulishuo.filedownloader.FileDownloadListener;
+import com.liulishuo.filedownloader.FileDownloadQueueSet;
+import com.liulishuo.filedownloader.FileDownloadSampleListener;
+import com.liulishuo.filedownloader.FileDownloader;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Author by pq, Date on 2023/1/11.
+ */
+public class DownloadHelper {
+    public static final int DOWNLOAD_STATUS_CALLBACK_ING = 1;//下载中
+    public static final int DOWNLOAD_STATUS_CALLBACK_COMPLETE = 2;//下载完成
+    public static final int DOWNLOAD_STATUS_CALLBACK_ERROR = 3;//下载错误
+    public static final String TAG = "DownloadHelper";
+    private volatile static DownloadHelper instance;
+    private HashMap<String, ArrayList<Integer>> downloadIds;
+    private OnEventListener mEventListener;
+
+    private DownloadHelper() {
+        downloadIds = new HashMap<>();
+    }
+
+    public static DownloadHelper getInstance() {
+        if (instance == null) {
+            synchronized (DownloadHelper.class) {
+                if (instance == null) {
+                    instance = new DownloadHelper();
+                }
+            }
+        }
+        return instance;
+    }
+
+    public void stop() {
+        FileDownloader.getImpl().pauseAll();
+    }
+
+    public void startDownload(String idKey, ArrayList<DownloadTaskBean> downloadUrls, OnEventListener onEventListener) {
+        if (downloadUrls == null || downloadUrls.size() == 0) {
+            return;
+        }
+        this.mEventListener = onEventListener;
+        final List<BaseDownloadTask> tasks = new ArrayList<>();
+        final ArrayList<Integer> taskIds = new ArrayList<>();
+        Log.i("qwa","downloadUrls:"+downloadUrls.size());
+        for (int i = 0; i < downloadUrls.size(); i++) {
+            DownloadTaskBean downloadTaskBean = downloadUrls.get(i);
+            BaseDownloadTask task1 = FileDownloader.getImpl().create(downloadTaskBean.getUrl()).setPath(downloadTaskBean.getSavePath(), false);
+            tasks.add(task1);
+            taskIds.add(task1.getId());
+        }
+        getDownloadTaskInfos().put(idKey, taskIds);
+        start_multi(tasks);
+    }
+
+    public void start_multi(List<BaseDownloadTask> tasks) {
+        downloadListener = createLis();
+        //(1) 创建 FileDownloadQueueSet
+        final FileDownloadQueueSet queueSet = new FileDownloadQueueSet(downloadListener);
+        //(3) 设置参数
+
+        // 每个任务的进度 无回调
+        //queueSet.disableCallbackProgressTimes();
+        // do not want each task's download progress's callback,we just consider which task will completed.
+
+        queueSet.setCallbackProgressTimes(1000);
+        queueSet.setCallbackProgressMinInterval(100);
+        //失败 重试次数
+        queueSet.setAutoRetryTimes(3);
+
+        //避免掉帧
+        FileDownloader.enableAvoidDropFrame();
+
+        //(4)串行下载
+        queueSet.downloadSequentially(tasks);
+
+        //(5)任务启动
+        queueSet.start();
+    }
+
+    // 多任务下载
+    private FileDownloadListener downloadListener;
+
+    public FileDownloadListener createLis() {
+        return new FileDownloadSampleListener() {
+            @Override
+            protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
+                if (task.getListener() != downloadListener) {
+                    return;
+                }
+                Log.d(TAG, "pending taskId:" + task.getId() + ",fileName:" + task.getFilename() + ",soFarBytes:" + soFarBytes + ",totalBytes:" + totalBytes + ",percent:" + soFarBytes * 1.0 / totalBytes);
+
+            }
+
+            @Override
+            protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
+                if (task.getListener() != downloadListener) {
+                    return;
+                }
+                Log.d(TAG, "progress taskId:" + task.getId() + ",fileName:" + task.getFilename() + ",soFarBytes:" + soFarBytes + ",totalBytes:" + totalBytes + ",percent:" + soFarBytes * 1.0 / totalBytes + ",speed:" + task.getSpeed());
+
+                HashMap<String, ArrayList<Integer>> downloadTaskInfos = getDownloadTaskInfos();
+                Iterator<String> iterator = downloadTaskInfos.keySet().iterator();
+                Log.i("progress", "downloadTaskInfos:" + downloadTaskInfos.size());
+                while (iterator.hasNext()) {
+                    String key = iterator.next();
+                    ArrayList<Integer> integers = downloadTaskInfos.get(key);
+                    Log.i("progress", "integers size:" + integers.size());
+                    float maxProgress = 100f / integers.size();
+                    Log.i("maxProgress", "maxProgress:" + maxProgress);
+                    int id = task.getId();
+                    Log.i("progress", "taskId:" + id);
+                    int i = integers.indexOf(id);
+                    Log.i("progress", "integers indexof:" + i);
+                    if (i != -1) {
+                        float value = maxProgress * (soFarBytes * 1.0f / totalBytes);
+                        int progress = (int) (maxProgress * (i) + value);
+                        if (mEventListener != null) {
+                            Log.i("progress", "progress:" + progress);
+                            mEventListener.onProgress(key, progress);
+                        }
+                    }
+                }
+            }
+
+            @Override
+            protected void blockComplete(BaseDownloadTask task) {
+                if (task.getListener() != downloadListener) {
+                    return;
+                }
+                Log.d(TAG, "blockComplete taskId:" + task.getId() + ",filePath:" + task.getPath() + ",fileName:" + task.getFilename() + ",speed:" + task.getSpeed() + ",isReuse:" + task.reuse());
+                HashMap<String, ArrayList<Integer>> downloadTaskInfos = getDownloadTaskInfos();
+                Iterator<String> iterator = downloadTaskInfos.keySet().iterator();
+                Log.i("blockComplete", "downloadTaskInfos:" + downloadTaskInfos.size());
+                while (iterator.hasNext()) {
+                    String key = iterator.next();
+                    ArrayList<Integer> integers = downloadTaskInfos.get(key);
+                    Log.i("blockComplete", "integers size:" + integers.size());
+                    StringBuilder stringBuilder = new StringBuilder();
+                    for (int i = 0; i < integers.size(); i++) {
+                        stringBuilder.append(integers.get(i)).append(",");
+                    }
+                    Log.i("blockComplete", "integers:" + stringBuilder);
+                    float totalProgress = 100f;
+                    int id = task.getId();
+                    Log.i("blockComplete", "taskId:" + id);
+                    int i = integers.indexOf(id);
+                    Log.i("blockComplete", "integers indexof:" + i);
+                    if (i != -1) {
+                        float progress;
+                        if (i != integers.size() - 1) {
+                            progress = (i + 1) * (totalProgress / integers.size());
+                        } else {
+                            progress = 100;
+                            getDownloadTaskInfos().clear();
+                            if (mEventListener != null) {
+                                mEventListener.onComplete(task.getPath());
+                            }
+                        }
+                        if (mEventListener != null) {
+                            Log.i("blockComplete", "progress:" + progress);
+                            mEventListener.onProgress(key, (int) progress);
+                        }
+                    }
+                }
+            }
+
+            @Override
+            protected void completed(BaseDownloadTask task) {
+                if (task.getListener() != downloadListener) {
+                    return;
+                }
+                if (mEventListener != null) {
+                    mEventListener.onComplete(task.getPath());
+                }
+                Log.d(TAG, "completed taskId:" + task.getId() + ",isReuse:" + task.reuse());
+            }
+
+            @Override
+            protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
+                if (task.getListener() != downloadListener) {
+                    return;
+                }
+                Log.d(TAG, "paused taskId:" + task.getId() + ",soFarBytes:" + soFarBytes + ",totalBytes:" + totalBytes + ",percent:" + soFarBytes * 1.0 / totalBytes);
+            }
+
+            @Override
+            protected void error(BaseDownloadTask task, Throwable e) {
+                if (task.getListener() != downloadListener) {
+                    return;
+                }
+                if (mEventListener != null) {
+                    HashMap<String, ArrayList<Integer>> downloadTaskInfos = getDownloadTaskInfos();
+                    Iterator<String> iterator = downloadTaskInfos.keySet().iterator();
+                    while (iterator.hasNext()) {
+                        mEventListener.downloadError(iterator.next());
+                    }
+                }
+                FileDownloader.getImpl().clearAllTaskData();
+                getDownloadTaskInfos().clear();
+                Log.d(TAG, "error taskId:" + task.getId() + ",e:" + e.getLocalizedMessage());
+            }
+
+            @Override
+            protected void warn(BaseDownloadTask task) {
+                if (task.getListener() != downloadListener) {
+                    return;
+                }
+                Log.d(TAG, "warn taskId:" + task.getId());
+            }
+        };
+    }
+
+    public void replaceCallBack(OnEventListener onEventListener) {
+        this.mEventListener = onEventListener;
+    }
+
+    public HashMap<String, ArrayList<Integer>> getDownloadTaskInfos() {
+        if (downloadIds == null) {
+            downloadIds = new HashMap<>();
+        }
+        return downloadIds;
+    }
+
+    public interface OnEventListener {
+        void onProgress(String id, int progress);
+
+        void downloadError(String id);
+
+        void onComplete(String filePath);
+    }
+}

+ 0 - 44
chatModule/src/main/java/com/cooleshow/chatmodule/utils/helper/IMShareHelper.java

@@ -245,50 +245,6 @@ public class IMShareHelper {
         }
     }
 
-    public static void parseShareActivity(Activity activity, JSONObject jsonObject, UMShareListener shareListener) {
-        JSONObject content = null;
-        try {
-            content = jsonObject.getJSONObject("content");
-            String shareTitle = content.getString("title");
-            String shareDesc = content.getString("desc");
-            String type = content.getString("type");
-            String shareType = content.getString("shareType");
-            SHARE_MEDIA share_media = SHARE_MEDIA.WEIXIN;
-            if (TextUtils.equals(shareType, WECHAT_TAG)) {
-                //分享微信
-                share_media = SHARE_MEDIA.WEIXIN;
-            }
-            if (TextUtils.equals(shareType, WECHAT_CIRCLE_TAG)) {
-                //分享朋友圈
-                share_media = SHARE_MEDIA.WEIXIN_CIRCLE;
-            }
-            if (TextUtils.equals(shareType, SINA_TAG)) {
-                //分享新浪微博
-                share_media = SHARE_MEDIA.SINA;
-            }
-            if (!UMShareAPI.get(Utils.getApp()).isInstall(activity, share_media)) {
-                ToastUtil.getInstance().show(Utils.getApp(), "应用未安装,分享失败");
-                return;
-            }
-            if (TextUtils.equals(type, IMAGE_TAG)) {
-                //分享图片
-                String imageData = content.getString("image");
-                UMImage image = new UMImage(activity, MyFileUtils.base64ToBitmap(imageData.split(",")[1]));//bitmap文件
-                image.setThumb(image);
-                image.compressFormat = Bitmap.CompressFormat.PNG;
-                image.compressStyle = UMImage.CompressStyle.SCALE;
-                image.setTitle(shareTitle);
-                image.setDescription(shareDesc);
-                new ShareAction(activity).withMedia(image)
-                        .setPlatform(share_media)
-                        .setCallback(shareListener)
-                        .share();
-            }
-        } catch (JSONException e) {
-            e.printStackTrace();
-        }
-    }
-
     public interface ResultCallBack {
         void onResult(boolean isSuccess);
     }

+ 1 - 1
student/build.gradle

@@ -152,5 +152,5 @@ dependencies {
 
     implementation(name: 'emoji-ios-release', ext: 'aar')
     implementation(name: 'emoji-release', ext: 'aar')
-    implementation(name: 'rong_player_5.2.4', ext: 'aar')
+    implementation(name: 'filedownload-1.0.0', ext: 'aar')
 }

BIN
student/libs/filedownload-1.0.0.aar


BIN
student/libs/rong_player_5.2.4.aar


+ 1 - 1
student/src/main/AndroidManifest.xml

@@ -2,7 +2,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     package="com.cooleshow.student">
-
+    <uses-sdk tools:overrideLibrary="com.liulishuo.filedownloader"/>
     <uses-permission android:name="android.permission.REORDER_TASKS" />
     <permission
         android:name="${applicationId}.permission.JPUSH_MESSAGE"

+ 39 - 0
student/src/main/java/com/cooleshow/student/App.java

@@ -1,6 +1,7 @@
 package com.cooleshow.student;
 
 import android.app.ActivityManager;
+import android.app.Notification;
 import android.content.Context;
 import android.os.Build;
 import android.text.TextUtils;
@@ -12,12 +13,17 @@ import androidx.annotation.RequiresApi;
 import com.alibaba.android.arouter.launcher.ARouter;
 import com.cooleshow.base.common.BaseApplication;
 import com.cooleshow.base.data.net.CommonParamsHelper;
+import com.cooleshow.base.utils.AppUtils;
 import com.cooleshow.base.utils.FileUtils;
 import com.cooleshow.base.utils.ProcessUtils;
 import com.cooleshow.base.utils.Utils;
 import com.cooleshow.base.widgets.CustomRefreshHeader;
 import com.cooleshow.student.helper.InitHelper;
 import com.cooleshow.usercenter.helper.UserHelper;
+import com.liulishuo.filedownloader.FileDownloader;
+import com.liulishuo.filedownloader.connection.FileDownloadUrlConnection;
+import com.liulishuo.filedownloader.services.ForegroundServiceConfig;
+import com.liulishuo.filedownloader.util.FileDownloadLog;
 import com.scwang.smart.refresh.footer.ClassicsFooter;
 import com.scwang.smart.refresh.layout.SmartRefreshLayout;
 import com.scwang.smart.refresh.layout.api.RefreshFooter;
@@ -33,6 +39,7 @@ import com.uuzuche.lib_zxing.activity.ZXingLibrary;
 import com.vanniktech.emoji.EmojiManager;
 import com.vanniktech.emoji.ios.IosEmojiProvider;
 
+import androidx.core.app.NotificationCompat;
 import cn.jiguang.api.utils.JCollectionAuth;
 import cn.jpush.android.api.JPushInterface;
 import io.reactivex.rxjava3.annotations.NonNull;
@@ -75,6 +82,7 @@ public class App extends BaseApplication {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
             webviewSetPath(this);
         }
+        initFileDownload();
         //极光推送
         //用户同意之后才初始化极光推送
         JPushInterface.setDebugMode(true);
@@ -159,6 +167,37 @@ public class App extends BaseApplication {
         return null;
     }
 
+    private void initFileDownload() {
+        // just for open the log in this demo project.
+        FileDownloadLog.NEED_LOG = true;
+
+        /**
+         * just for cache Application's Context, and ':filedownloader' progress will NOT be launched
+         * by below code, so please do not worry about performance.
+         * @see FileDownloader#init(Context)
+         */
+        final String channelId = "student";
+        Notification notification = new NotificationCompat.Builder(this, channelId)
+                .setSmallIcon(R.mipmap.ic_launcher)
+                .setContentText("Downloading")
+                .setContentTitle("" + AppUtils.getAppName())
+                .build();
+        ForegroundServiceConfig config = new ForegroundServiceConfig.Builder()
+                .notification(notification)
+                .notificationChannelId(channelId)
+                .notificationChannelName("name")
+                .needRecreateChannelId(true) // if your channel id is created before, you can ignore this configuration and you don't need to provide channel id and channel name
+                .notificationId(R.mipmap.ic_launcher)
+                .build();
+        FileDownloader.setupOnApplicationOnCreate(this)
+                .connectionCreator(new FileDownloadUrlConnection
+                        .Creator(new FileDownloadUrlConnection.Configuration()
+                        .connectTimeout(15_000) // set connection timeout.
+                        .readTimeout(15_000) // set read timeout.
+                )).foregroundServiceConfig(config)
+                .commit();
+    }
+
     @Override
     public boolean isTeacherClient() {
         return false;

+ 60 - 0
student/src/main/java/com/cooleshow/student/helper/ShareHelper.java

@@ -1,5 +1,6 @@
 package com.cooleshow.student.helper;
 
+import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
@@ -12,10 +13,19 @@ import android.util.Log;
 import android.view.View;
 
 import com.cooleshow.base.utils.FileUtils;
+import com.cooleshow.base.utils.MyFileUtils;
 import com.cooleshow.base.utils.ToastUtil;
 import com.cooleshow.base.utils.Utils;
 import com.cooleshow.chatmodule.utils.helper.ChatGroupHelper;
 import com.cooleshow.chatmodule.utils.helper.IMShareHelper;
+import com.umeng.socialize.ShareAction;
+import com.umeng.socialize.UMShareAPI;
+import com.umeng.socialize.UMShareListener;
+import com.umeng.socialize.bean.SHARE_MEDIA;
+import com.umeng.socialize.media.UMImage;
+
+import org.json.JSONException;
+import org.json.JSONObject;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -36,6 +46,12 @@ import io.reactivex.rxjava3.schedulers.Schedulers;
  */
 public class ShareHelper {
 
+    public static final String WECHAT_TAG = "wechat";
+    public static final String WECHAT_CIRCLE_TAG = "wechat_circle";
+    public static final String SINA_TAG = "sina";
+    public static final String IMAGE_TAG = "image";
+    public static final String VIDEO_TAG = "video";
+
     public static void saveImg(Context context, String base64, ResultCallBack resultCallBack) {
         Observable.create(new ObservableOnSubscribe<File>() {
                     @Override
@@ -211,4 +227,48 @@ public class ShareHelper {
         FileUtils.saveImageToLocal(bitmap, file.getAbsolutePath());
         return file;
     }
+
+    public static void parseShareActivity(Activity activity, JSONObject jsonObject, UMShareListener shareListener) {
+        JSONObject content = null;
+        try {
+            content = jsonObject.getJSONObject("content");
+            String shareTitle = content.getString("title");
+            String shareDesc = content.getString("desc");
+            String type = content.getString("type");
+            String shareType = content.getString("shareType");
+            SHARE_MEDIA share_media = SHARE_MEDIA.WEIXIN;
+            if (TextUtils.equals(shareType, WECHAT_TAG)) {
+                //分享微信
+                share_media = SHARE_MEDIA.WEIXIN;
+            }
+            if (TextUtils.equals(shareType, WECHAT_CIRCLE_TAG)) {
+                //分享朋友圈
+                share_media = SHARE_MEDIA.WEIXIN_CIRCLE;
+            }
+            if (TextUtils.equals(shareType, SINA_TAG)) {
+                //分享新浪微博
+                share_media = SHARE_MEDIA.SINA;
+            }
+            if (!UMShareAPI.get(Utils.getApp()).isInstall(activity, share_media)) {
+                ToastUtil.getInstance().show(Utils.getApp(), "应用未安装,分享失败");
+                return;
+            }
+            if (TextUtils.equals(type, IMAGE_TAG)) {
+                //分享图片
+                String imageData = content.getString("image");
+                UMImage image = new UMImage(activity, MyFileUtils.base64ToBitmap(imageData.split(",")[1]));//bitmap文件
+                image.setThumb(image);
+                image.compressFormat =Bitmap.CompressFormat.PNG;
+                image.compressStyle = UMImage.CompressStyle.SCALE;
+                image.setTitle(shareTitle);
+                image.setDescription(shareDesc);
+                new ShareAction(activity).withMedia(image)
+                        .setPlatform(share_media)
+                        .setCallback(shareListener)
+                        .share();
+            }
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+    }
 }

+ 10 - 0
student/src/main/java/com/cooleshow/student/ui/main/MallFragment.java

@@ -543,6 +543,16 @@ public class MallFragment extends BaseMVPFragment<FragmentMallBinding, ShopMallP
 
     }
 
+    @Override
+    public void saveFile(JSONObject jsonObject) {
+
+    }
+
+    @Override
+    public void shareTripartite(JSONObject jsonObject) {
+
+    }
+
     private boolean goPay = false;
 
     @Subscribe(threadMode = ThreadMode.MAIN)

+ 123 - 0
student/src/main/java/com/cooleshow/student/ui/web/HtmlActivity.java

@@ -45,6 +45,7 @@ import com.alibaba.android.arouter.facade.annotation.Route;
 import com.alibaba.android.arouter.launcher.ARouter;
 import com.alipay.sdk.app.PayTask;
 import com.cooleshow.base.BuildConfig;
+import com.cooleshow.base.bean.DownloadTaskBean;
 import com.cooleshow.base.bean.WxPayResult;
 import com.cooleshow.base.common.WebConstants;
 import com.cooleshow.base.constanst.Constants;
@@ -55,18 +56,23 @@ import com.cooleshow.base.ui.activity.BaseActivity;
 import com.cooleshow.base.utils.AndroidBug5497Workaround;
 import com.cooleshow.base.utils.AppUtils;
 import com.cooleshow.base.utils.ClipboardUtils;
+import com.cooleshow.base.utils.EncryptUtils;
+import com.cooleshow.base.utils.FileUtils;
 import com.cooleshow.base.utils.LOG;
 import com.cooleshow.base.utils.LogUtils;
 import com.cooleshow.base.utils.MyFileUtils;
+import com.cooleshow.base.utils.NetworkUtil;
 import com.cooleshow.base.utils.PermissionUtils;
 import com.cooleshow.base.utils.ToastUtil;
 import com.cooleshow.base.utils.UriUtils;
 import com.cooleshow.base.utils.WebParamsUtils;
 import com.cooleshow.base.utils.helper.DialogHelper;
+import com.cooleshow.base.utils.helper.DownloadHelper;
 import com.cooleshow.base.utils.helper.GlideEngine;
 import com.cooleshow.base.utils.helper.QMUIStatusBarHelper;
 import com.cooleshow.base.utils.helper.upload.UploadHelper;
 import com.cooleshow.base.widgets.DialogUtil;
+import com.cooleshow.base.widgets.dialog.CommonConfirmDialog2;
 import com.cooleshow.chatmodule.constants.TCChatRouterPath;
 import com.cooleshow.chatmodule.utils.helper.ChatHelper;
 import com.cooleshow.student.App;
@@ -114,6 +120,7 @@ import java.io.UnsupportedEncodingException;
 import java.lang.ref.WeakReference;
 import java.net.URLEncoder;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
@@ -149,6 +156,8 @@ public class HtmlActivity extends BaseActivity<ActivityHtml1Binding> implements
     private String mImageBase64;
     private boolean isNeedResetScreenOrientation = true;
 
+    private DownloadHelper.OnEventListener mEventListener;
+
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         //限制截屏和录屏
@@ -432,6 +441,14 @@ public class HtmlActivity extends BaseActivity<ActivityHtml1Binding> implements
     }
 
     @Override
+    public void shareTripartite(JSONObject jsonObject) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        ShareHelper.parseShareActivity(HtmlActivity.this, jsonObject, mShareListener);
+    }
+
+    @Override
     public void shareAchievements(JSONObject jsonObject) {
 
         JSONObject content = null;
@@ -912,6 +929,112 @@ public class HtmlActivity extends BaseActivity<ActivityHtml1Binding> implements
                 });
     }
 
+
+    @Override
+    public void saveFile(JSONObject jsonObject) {
+        if (!checkActivityExist()) {
+            return;
+        }
+
+        new RxPermissions(this)
+                .request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
+                .subscribe(permission -> {
+                    boolean isWifi = NetworkUtil.isWifiNetwork(HtmlActivity.this);
+                    JSONObject contentJson = jsonObject.optJSONObject("content");
+                    String downloadFileUrl = contentJson.optString("url", "");
+                    if (!TextUtils.isEmpty(downloadFileUrl)) {
+                        if (isWifi) {
+                            toDownLoad(downloadFileUrl);
+                        } else {
+                            showWifiTipDialog2(downloadFileUrl);
+                        }
+                    }
+                });
+    }
+
+    private void showWifiTipDialog2(String url) {
+        CommonConfirmDialog2 commonDialog2 = new CommonConfirmDialog2(this);
+        commonDialog2.show();
+        commonDialog2.setTitle("提示");
+        commonDialog2.setContent("当前非Wifi网络,确认下载?");
+        commonDialog2.setOnConfirmClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                commonDialog2.dismiss();
+                toDownLoad(url);
+            }
+        });
+    }
+
+    private void toDownLoad(String downloadFileUrl) {
+        String downloadSavePath = MyFileUtils.getDownloadSavePath(downloadFileUrl);
+        if (!TextUtils.isEmpty(downloadSavePath)) {
+            DownloadTaskBean downloadTaskBean = new DownloadTaskBean();
+            downloadTaskBean.setUrl(downloadFileUrl);
+            downloadTaskBean.setSavePath(downloadSavePath);
+            String key = EncryptUtils.encryptMD5ToString(downloadFileUrl);
+            ArrayList<DownloadTaskBean> downloadTaskBeans = new ArrayList<>();
+            downloadTaskBeans.add(downloadTaskBean);
+            showLoading("保存中:0%");
+            DownloadHelper.getInstance().startDownload(key, downloadTaskBeans, getDownloadEventListener());
+        }
+    }
+
+    private DownloadHelper.OnEventListener getDownloadEventListener() {
+        if (mEventListener == null) {
+            mEventListener = new DownloadHelper.OnEventListener() {
+                @Override
+                public void onProgress(String id, int progress) {
+                    Log.i("pq", "html Download:" + progress);
+                    if (webView != null) {
+                        webView.post(new Runnable() {
+                            @Override
+                            public void run() {
+                                updateLoadingText("保存中:" + progress + "%");
+                            }
+                        });
+                    }
+                }
+
+                @Override
+                public void downloadError(String id) {
+                    if (webView != null) {
+                        webView.post(new Runnable() {
+                            @Override
+                            public void run() {
+                                hideLoading();
+                                ToastUtil.getInstance().showShort("文件保存失败");
+                            }
+                        });
+                    }
+                }
+
+                @Override
+                public void onComplete(String filePath) {
+                    Log.i("pq", "download onComplete:" + filePath);
+                    if (webView != null) {
+                        webView.post(new Runnable() {
+                            @Override
+                            public void run() {
+                                hideLoading();
+                                boolean isVideo = MyFileUtils.isVideo(filePath);
+                                if (isVideo) {
+                                    ToastUtil.getInstance().showShort("视频已保存到相册");
+                                    FileUtils.saveVideoToGallery(HtmlActivity.this, filePath);
+                                }else{
+                                    FileUtils.saveAudioToMusic(HtmlActivity.this,filePath);
+                                    String fileName = FileUtils.getFileName(filePath);
+                                    ToastUtil.getInstance().showShort("保存成功,文件存储路径: 手机存储/Music/yyszkt/"+fileName);
+                                }
+                            }
+                        });
+                    }
+                }
+            };
+        }
+        return mEventListener;
+    }
+
     //android获取一个用于打开PDF文件的intent
     public static Intent getPdfFileIntent(String Path) {
         File file = new File(Path);

+ 10 - 0
student/src/main/java/com/cooleshow/student/ui/web/HtmlHorizontalScreenActivity.java

@@ -673,6 +673,16 @@ public class HtmlHorizontalScreenActivity extends BaseActivity<ActivityHtml1Bind
         onBackPressed();
     }
 
+    @Override
+    public void saveFile(JSONObject jsonObject) {
+
+    }
+
+    @Override
+    public void shareTripartite(JSONObject jsonObject) {
+
+    }
+
     private boolean goPay = false;
 
     @Subscribe(threadMode = ThreadMode.MAIN)

+ 19 - 0
student/src/main/java/com/cooleshow/student/widgets/helper/JsInterfaceUtils.java

@@ -199,6 +199,13 @@ public class JsInterfaceUtils extends Object {
                     }
                 }
 
+                if ("shareTripartite".equals(api)) {
+                    if (onListener != null) {
+                        onListener.shareTripartite(jsonObject);
+                    }
+                    return;
+                }
+
                 if ("backIconChange".equals(api)) {
                     if (onListener != null) {
                         onListener.backIconChange(jsonObject);
@@ -292,6 +299,13 @@ public class JsInterfaceUtils extends Object {
                     }
                     return;
                 }
+
+                if(TextUtils.equals(WebApi.API_SAVE_FILE,api)){
+                    if (onListener != null) {
+                        onListener.saveFile(jsonObject);
+                    }
+                    return;
+                }
             } catch (Exception e) {
             }
         });
@@ -395,6 +409,11 @@ public class JsInterfaceUtils extends Object {
         void savePicture(String base64, String uuid);
 
         void onBackPress();
+
+        void saveFile(JSONObject jsonObject);
+
+        void shareTripartite(JSONObject jsonObject);
+
     }
 
 }

+ 2 - 1
teacher/build.gradle

@@ -158,5 +158,6 @@ dependencies {
 
     implementation(name: 'emoji-ios-release', ext: 'aar')
     implementation(name: 'emoji-release', ext: 'aar')
-    implementation(name: 'rong_player_5.2.4', ext: 'aar')
+    implementation(name: 'filedownload-1.0.0', ext: 'aar')
+
 }

BIN
teacher/libs/filedownload-1.0.0.aar


BIN
teacher/libs/rong_player_5.2.4.aar


+ 1 - 1
teacher/src/main/AndroidManifest.xml

@@ -2,7 +2,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
     package="com.cooleshow.teacher">
-
+    <uses-sdk tools:overrideLibrary="com.liulishuo.filedownloader"/>
 
     <permission
         android:name="${applicationId}.permission.JPUSH_MESSAGE"

+ 40 - 0
teacher/src/main/java/com/cooleshow/teacher/App.java

@@ -1,6 +1,7 @@
 package com.cooleshow.teacher;
 
 import android.app.ActivityManager;
+import android.app.Notification;
 import android.content.Context;
 import android.os.Build;
 import android.text.TextUtils;
@@ -9,12 +10,17 @@ import android.webkit.WebView;
 import com.alibaba.android.arouter.launcher.ARouter;
 import com.cooleshow.base.common.BaseApplication;
 import com.cooleshow.base.data.net.CommonParamsHelper;
+import com.cooleshow.base.utils.AppUtils;
 import com.cooleshow.base.utils.FileUtils;
 import com.cooleshow.base.utils.ProcessUtils;
 import com.cooleshow.base.utils.Utils;
 import com.cooleshow.base.widgets.CustomRefreshHeader;
 import com.cooleshow.teacher.helper.InitHelper;
 import com.cooleshow.usercenter.helper.UserHelper;
+import com.liulishuo.filedownloader.FileDownloader;
+import com.liulishuo.filedownloader.connection.FileDownloadUrlConnection;
+import com.liulishuo.filedownloader.services.ForegroundServiceConfig;
+import com.liulishuo.filedownloader.util.FileDownloadLog;
 import com.scwang.smart.refresh.footer.ClassicsFooter;
 import com.scwang.smart.refresh.layout.SmartRefreshLayout;
 import com.scwang.smart.refresh.layout.api.RefreshFooter;
@@ -32,6 +38,7 @@ import com.vanniktech.emoji.ios.IosEmojiProvider;
 
 import androidx.annotation.RequiresApi;
 
+import androidx.core.app.NotificationCompat;
 import cn.jiguang.api.utils.JCollectionAuth;
 import cn.jpush.android.api.JPushInterface;
 import io.reactivex.rxjava3.annotations.NonNull;
@@ -74,6 +81,7 @@ public class App extends BaseApplication {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
             webviewSetPath(this);
         }
+        initFileDownload();
         initBugly();
         //极光推送
         JPushInterface.setDebugMode(true);
@@ -158,6 +166,38 @@ public class App extends BaseApplication {
         return null;
     }
 
+    private void initFileDownload() {
+        // just for open the log in this demo project.
+        FileDownloadLog.NEED_LOG = true;
+
+        /**
+         * just for cache Application's Context, and ':filedownloader' progress will NOT be launched
+         * by below code, so please do not worry about performance.
+         * @see FileDownloader#init(Context)
+         */
+        final String channelId = "student";
+        Notification notification = new NotificationCompat.Builder(this, channelId)
+                .setSmallIcon(R.mipmap.ic_launcher)
+                .setContentText("Downloading")
+                .setContentTitle("" + AppUtils.getAppName())
+                .build();
+        ForegroundServiceConfig config = new ForegroundServiceConfig.Builder()
+                .notification(notification)
+                .notificationChannelId(channelId)
+                .notificationChannelName("name")
+                .needRecreateChannelId(true) // if your channel id is created before, you can ignore this configuration and you don't need to provide channel id and channel name
+                .notificationId(R.mipmap.ic_launcher)
+                .build();
+        FileDownloader.setupOnApplicationOnCreate(this)
+                .connectionCreator(new FileDownloadUrlConnection
+                        .Creator(new FileDownloadUrlConnection.Configuration()
+                        .connectTimeout(15_000) // set connection timeout.
+                        .readTimeout(15_000) // set read timeout.
+                )).foregroundServiceConfig(config)
+                .commit();
+    }
+
+
     @Override
     public boolean isTeacherClient() {
         return true;

+ 59 - 0
teacher/src/main/java/com/cooleshow/teacher/helper/ShareHelper.java

@@ -1,5 +1,6 @@
 package com.cooleshow.teacher.helper;
 
+import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
@@ -11,10 +12,19 @@ import android.util.Base64;
 import android.util.Log;
 
 import com.cooleshow.base.utils.FileUtils;
+import com.cooleshow.base.utils.MyFileUtils;
 import com.cooleshow.base.utils.ToastUtil;
 import com.cooleshow.base.utils.Utils;
 import com.cooleshow.chatmodule.utils.helper.ChatGroupHelper;
 import com.cooleshow.chatmodule.utils.helper.IMShareHelper;
+import com.umeng.socialize.ShareAction;
+import com.umeng.socialize.UMShareAPI;
+import com.umeng.socialize.UMShareListener;
+import com.umeng.socialize.bean.SHARE_MEDIA;
+import com.umeng.socialize.media.UMImage;
+
+import org.json.JSONException;
+import org.json.JSONObject;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -34,6 +44,11 @@ import io.reactivex.rxjava3.schedulers.Schedulers;
  * Author by pq, Date on 2022/5/31.
  */
 public class ShareHelper {
+    public static final String WECHAT_TAG = "wechat";
+    public static final String WECHAT_CIRCLE_TAG = "wechat_circle";
+    public static final String SINA_TAG = "sina";
+    public static final String IMAGE_TAG = "image";
+    public static final String VIDEO_TAG = "video";
 
     public static void saveImg(Context context, String base64, ResultCallBack resultCallBack) {
         Observable.create(new ObservableOnSubscribe<File>() {
@@ -135,6 +150,50 @@ public class ShareHelper {
         IMShareHelper.shareImgToChatGroup(targetBitmap,targetId,isGroup,resultCallBack);
     }
 
+    public static void parseShareActivity(Activity activity, JSONObject jsonObject, UMShareListener shareListener) {
+        JSONObject content = null;
+        try {
+            content = jsonObject.getJSONObject("content");
+            String shareTitle = content.getString("title");
+            String shareDesc = content.getString("desc");
+            String type = content.getString("type");
+            String shareType = content.getString("shareType");
+            SHARE_MEDIA share_media = SHARE_MEDIA.WEIXIN;
+            if (TextUtils.equals(shareType, WECHAT_TAG)) {
+                //分享微信
+                share_media = SHARE_MEDIA.WEIXIN;
+            }
+            if (TextUtils.equals(shareType, WECHAT_CIRCLE_TAG)) {
+                //分享朋友圈
+                share_media = SHARE_MEDIA.WEIXIN_CIRCLE;
+            }
+            if (TextUtils.equals(shareType, SINA_TAG)) {
+                //分享新浪微博
+                share_media = SHARE_MEDIA.SINA;
+            }
+            if (!UMShareAPI.get(Utils.getApp()).isInstall(activity, share_media)) {
+                ToastUtil.getInstance().show(Utils.getApp(), "应用未安装,分享失败");
+                return;
+            }
+            if (TextUtils.equals(type, IMAGE_TAG)) {
+                //分享图片
+                String imageData = content.getString("image");
+                UMImage image = new UMImage(activity, MyFileUtils.base64ToBitmap(imageData.split(",")[1]));//bitmap文件
+                image.setThumb(image);
+                image.compressFormat =Bitmap.CompressFormat.PNG;
+                image.compressStyle = UMImage.CompressStyle.SCALE;
+                image.setTitle(shareTitle);
+                image.setDescription(shareDesc);
+                new ShareAction(activity).withMedia(image)
+                        .setPlatform(share_media)
+                        .setCallback(shareListener)
+                        .share();
+            }
+        } catch (JSONException e) {
+            e.printStackTrace();
+        }
+    }
+
     public interface ResultCallBack {
         void onResult(boolean isSuccess);
     }

+ 121 - 0
teacher/src/main/java/com/cooleshow/teacher/ui/web/HtmlActivity.java

@@ -45,6 +45,7 @@ import com.alibaba.android.arouter.facade.annotation.Route;
 import com.alibaba.android.arouter.launcher.ARouter;
 import com.alipay.sdk.app.PayTask;
 import com.cooleshow.base.BuildConfig;
+import com.cooleshow.base.bean.DownloadTaskBean;
 import com.cooleshow.base.bean.WxPayResult;
 import com.cooleshow.base.common.WebConstants;
 import com.cooleshow.base.constanst.Constants;
@@ -53,18 +54,22 @@ import com.cooleshow.base.router.RouterPath;
 import com.cooleshow.base.ui.activity.BaseActivity;
 import com.cooleshow.base.utils.AppUtils;
 import com.cooleshow.base.utils.ClipboardUtils;
+import com.cooleshow.base.utils.EncryptUtils;
 import com.cooleshow.base.utils.FileUtils;
 import com.cooleshow.base.utils.LOG;
 import com.cooleshow.base.utils.LogUtils;
+import com.cooleshow.base.utils.NetworkUtil;
 import com.cooleshow.base.utils.PermissionUtils;
 import com.cooleshow.base.utils.ToastUtil;
 import com.cooleshow.base.utils.UriUtils;
 import com.cooleshow.base.utils.WebParamsUtils;
 import com.cooleshow.base.utils.helper.DialogHelper;
+import com.cooleshow.base.utils.helper.DownloadHelper;
 import com.cooleshow.base.utils.helper.GlideEngine;
 import com.cooleshow.base.utils.helper.QMUIStatusBarHelper;
 import com.cooleshow.base.utils.helper.upload.UploadHelper;
 import com.cooleshow.base.widgets.DialogUtil;
+import com.cooleshow.base.widgets.dialog.CommonConfirmDialog2;
 import com.cooleshow.chatmodule.constants.TCChatRouterPath;
 import com.cooleshow.chatmodule.utils.helper.ChatHelper;
 import com.cooleshow.teacher.App;
@@ -113,6 +118,7 @@ import java.io.UnsupportedEncodingException;
 import java.lang.ref.WeakReference;
 import java.net.URLEncoder;
 import java.text.SimpleDateFormat;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Locale;
@@ -149,6 +155,8 @@ public class HtmlActivity extends BaseActivity<ActivityHtml1Binding> implements
     private String mImageBase64;
     private boolean isNeedResetScreenOrientation =true;
 
+    private DownloadHelper.OnEventListener mEventListener;
+
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         //限制截屏和录屏
@@ -373,6 +381,111 @@ public class HtmlActivity extends BaseActivity<ActivityHtml1Binding> implements
     }
 
     @Override
+    public void saveFile(JSONObject jsonObject) {
+        if (!checkActivityExist()) {
+            return;
+        }
+
+        new RxPermissions(this)
+                .request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
+                .subscribe(permission -> {
+                    boolean isWifi = NetworkUtil.isWifiNetwork(HtmlActivity.this);
+                    JSONObject contentJson = jsonObject.optJSONObject("content");
+                    String downloadFileUrl = contentJson.optString("url", "");
+                    if (!TextUtils.isEmpty(downloadFileUrl)) {
+                        if (isWifi) {
+                            toDownLoad(downloadFileUrl);
+                        } else {
+                            showWifiTipDialog2(downloadFileUrl);
+                        }
+                    }
+                });
+    }
+
+    private void showWifiTipDialog2(String url) {
+        CommonConfirmDialog2 commonDialog2 = new CommonConfirmDialog2(this);
+        commonDialog2.show();
+        commonDialog2.setTitle("提示");
+        commonDialog2.setContent("当前非Wifi网络,确认下载?");
+        commonDialog2.setOnConfirmClickListener(new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                commonDialog2.dismiss();
+                toDownLoad(url);
+            }
+        });
+    }
+
+    private void toDownLoad(String downloadFileUrl) {
+        String downloadSavePath = MyFileUtils.getDownloadSavePath(downloadFileUrl);
+        if (!TextUtils.isEmpty(downloadSavePath)) {
+            DownloadTaskBean downloadTaskBean = new DownloadTaskBean();
+            downloadTaskBean.setUrl(downloadFileUrl);
+            downloadTaskBean.setSavePath(downloadSavePath);
+            String key = EncryptUtils.encryptMD5ToString(downloadFileUrl);
+            ArrayList<DownloadTaskBean> downloadTaskBeans = new ArrayList<>();
+            downloadTaskBeans.add(downloadTaskBean);
+            showLoading("保存中:0%");
+            DownloadHelper.getInstance().startDownload(key, downloadTaskBeans, getDownloadEventListener());
+        }
+    }
+
+    private DownloadHelper.OnEventListener getDownloadEventListener() {
+        if (mEventListener == null) {
+            mEventListener = new DownloadHelper.OnEventListener() {
+                @Override
+                public void onProgress(String id, int progress) {
+                    Log.i("pq", "html Download:" + progress);
+                    if (webView != null) {
+                        webView.post(new Runnable() {
+                            @Override
+                            public void run() {
+                                updateLoadingText("保存中:" + progress + "%");
+                            }
+                        });
+                    }
+                }
+
+                @Override
+                public void downloadError(String id) {
+                    if (webView != null) {
+                        webView.post(new Runnable() {
+                            @Override
+                            public void run() {
+                                hideLoading();
+                                ToastUtil.getInstance().showShort("文件保存失败");
+                            }
+                        });
+                    }
+                }
+
+                @Override
+                public void onComplete(String filePath) {
+                    Log.i("pq", "download onComplete:" + filePath);
+                    if (webView != null) {
+                        webView.post(new Runnable() {
+                            @Override
+                            public void run() {
+                                hideLoading();
+                                boolean isVideo = MyFileUtils.isVideo(filePath);
+                                if (isVideo) {
+                                    ToastUtil.getInstance().showShort("视频已保存到相册");
+                                    FileUtils.saveVideoToGallery(HtmlActivity.this, filePath);
+                                }else{
+                                    FileUtils.saveAudioToMusic(HtmlActivity.this,filePath);
+                                    String fileName = FileUtils.getFileName(filePath);
+                                    ToastUtil.getInstance().showShort("保存成功,文件存储路径: 手机存储/Music/yyszkt/"+fileName);
+                                }
+                            }
+                        });
+                    }
+                }
+            };
+        }
+        return mEventListener;
+    }
+
+    @Override
     public void downloadFile(String url) {
         if (TextUtils.isEmpty(url)) {
             ToastUtil.getInstance().showShort("文件异常");
@@ -431,6 +544,14 @@ public class HtmlActivity extends BaseActivity<ActivityHtml1Binding> implements
     }
 
     @Override
+    public void shareTripartite(JSONObject jsonObject) {
+        if (!checkActivityExist()) {
+            return;
+        }
+        ShareHelper.parseShareActivity(HtmlActivity.this, jsonObject, mShareListener);
+    }
+
+    @Override
     public void shareAchievements(JSONObject jsonObject) {
 
         JSONObject content = null;

+ 19 - 0
teacher/src/main/java/com/cooleshow/teacher/widgets/helper/JsInterfaceUtils.java

@@ -216,6 +216,13 @@ public class JsInterfaceUtils extends Object {
                     return;
                 }
 
+                if ("shareTripartite".equals(api)) {
+                    if (onListener != null) {
+                        onListener.shareTripartite(jsonObject);
+                    }
+                    return;
+                }
+
                 if ("backIconChange".equals(api)) {
                     if (onListener != null) {
                         onListener.backIconChange(jsonObject);
@@ -339,6 +346,13 @@ public class JsInterfaceUtils extends Object {
                     }
                     return;
                 }
+
+                if(TextUtils.equals(WebApi.API_SAVE_FILE,api)){
+                    if (onListener != null) {
+                        onListener.saveFile(jsonObject);
+                    }
+                    return;
+                }
             } catch (Exception e) {
             }
         });
@@ -442,6 +456,11 @@ public class JsInterfaceUtils extends Object {
         void savePicture(String base64, String uuid);
 
         void onBackPress();
+
+        void saveFile(JSONObject jsonObject);
+
+        void shareTripartite(JSONObject jsonObject);
+
     }
 
 }