Browse Source

视频类基础框架,基本开发完成,基础功能都单元测试通过

lyn 5 years ago
parent
commit
fe4988590b

+ 2 - 0
app/build.gradle

@@ -72,4 +72,6 @@ dependencies {
     // classpath.
     androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.1.0'
     implementation 'com.shuyu:GSYVideoPlayer:7.0.2'
+    implementation 'com.yanzhenjie.nohttp:nohttp:1.1.11'
+    implementation 'com.liulishuo.filedownloader:library:1.7.6'
 }

+ 25 - 0
app/src/androidTest/java/com/haochuan/hciptvbasic/MainActivityTest.java

@@ -7,7 +7,10 @@ import androidx.test.platform.app.InstrumentationRegistry;
 
 import androidx.test.rule.ActivityTestRule;
 
+import com.haochuan.hciptvbasic.Util.Logger;
 import com.haochuan.hciptvbasic.Util.ScreenSnap;
+import com.haochuan.hciptvbasic.webview.PayToJS;
+import com.haochuan.hciptvbasic.webview.ToolToJS;
 
 import org.junit.Rule;
 import org.junit.Test;
@@ -36,9 +39,31 @@ public class MainActivityTest{
            int y = 0;
            int width = ScreenSnap.getScreenWidth(getContext());
            int height = ScreenSnap.getScreenHeight(getContext());
+
        }catch (Throwable throwable) {
            throwable.printStackTrace();
        }
 
     }
+
+    @Test
+    public void testPayToJs(){
+        MainActivity activity = mActivityRule.getActivity();
+        PayToJS payToJS = new PayToJS(getContext(),activity.getWebView());
+        payToJS.getUserId();
+    }
+
+    @Test
+    public void testToolToJs(){
+        MainActivity activity = mActivityRule.getActivity();
+        ToolToJS toolToJS = new ToolToJS(activity,activity.getWebView());
+        String filePath = "/storage/emulated/0/Android/data/com.haochuan.hciptvbasic/cache/temp/com.haochuan.hciptvbasic1.apk";
+        String url = "http://117.169.11.222:8018/tv/index.php?m=Home&c=Activity&a=getActStatus";
+        String paramJson = "{\"m\":\"Home\",\"c\":\"Activity\",\"a\":\"getActStatus\"}";
+        String headJson = "{\"cookie\":\"head=123123123131fdfsfsdfs\"}";
+        toolToJS.clientWebRequest(url,paramJson,headJson,2,false,"test");
+        //Logger.d("md5:" + md5);
+        //toolToJS.download("http://202.99.114.74:56251/dudu_youxi/h5/gameList/apk/jiSuKuangBiao.apk");
+
+    }
 }

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

@@ -3,6 +3,7 @@
     package="com.haochuan.hciptvbasic">
 
     <application
+        android:name=".BaseApp"
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
@@ -16,7 +17,6 @@
             </intent-filter>
         </activity>
         <activity android:name=".MainActivity">
-
         </activity>
 
         <uses-library

+ 44 - 0
app/src/main/java/com/haochuan/hciptvbasic/BaseApp.java

@@ -0,0 +1,44 @@
+package com.haochuan.hciptvbasic;
+
+import android.app.Application;
+
+import com.liulishuo.filedownloader.FileDownloader;
+import com.yanzhenjie.nohttp.InitializationConfig;
+import com.yanzhenjie.nohttp.Logger;
+import com.yanzhenjie.nohttp.NoHttp;
+import com.yanzhenjie.nohttp.URLConnectionNetworkExecutor;
+import com.yanzhenjie.nohttp.cache.DBCacheStore;
+import com.yanzhenjie.nohttp.cookie.DBCookieStore;
+
+public class BaseApp extends Application {
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        initHttp();
+        FileDownloader.setupOnApplicationOnCreate(this);
+    }
+
+    private void initHttp() {
+        InitializationConfig config = InitializationConfig.newBuilder(this)
+                // 全局连接服务器超时时间,单位毫秒,默认10s。
+                .connectionTimeout(10 * 1000)
+                // 全局等待服务器响应超时时间,单位毫秒,默认10s。
+                .readTimeout(10 * 1000)
+                // 配置缓存,默认保存数据库DBCacheStore,保存到SD卡使用DiskCacheStore。
+                .cacheStore(
+                        // 如果不使用缓存,setEnable(false)禁用。
+                        new DBCacheStore(this).setEnable(false)
+                )
+                // 配置Cookie,默认保存数据库DBCookieStore,开发者可以自己实现CookieStore接口。
+                .cookieStore(
+                        // 如果不维护cookie,setEnable(false)禁用。
+                        new DBCookieStore(this).setEnable(false)
+                )
+                // 配置网络层,默认URLConnectionNetworkExecutor,如果想用OkHttp:OkHttpNetworkExecutor。
+                .networkExecutor(new URLConnectionNetworkExecutor())
+                // 全局重试次数,配置后每个请求失败都会重试x次。
+                .retry(2)
+                .build();
+        NoHttp.initialize(config);
+    }
+}

+ 31 - 9
app/src/main/java/com/haochuan/hciptvbasic/BaseWebActivity.java

@@ -20,6 +20,7 @@ import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
 import androidx.core.content.ContextCompat;
 
+import com.haochuan.hciptvbasic.Util.Logger;
 import com.haochuan.hciptvbasic.video.BaseMediaPlayer;
 import com.haochuan.hciptvbasic.video.HCPlayer;
 import com.haochuan.hciptvbasic.video.IVideoPlayer;
@@ -43,22 +44,19 @@ public abstract class BaseWebActivity extends AppCompatActivity {
 
     //获取启动页web地址
     protected abstract String getIndexURL();
-    //处理intent中的参数
-    protected abstract void handleIntent(Intent intent);
 
     /*--------------------生命周期---------------------*/
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        if (getIntent() != null) {
-            handleIntent(getIntent());
-        }
+
+        //初始化日志
+        Logger.init(this);
 
         initPlayer();
 
         webView = new WebView(this);
         webView.setBackgroundColor(ContextCompat.getColor(this, android.R.color.transparent));
-//        webView.setBackgroundResource(R.drawable.img_start_bg);
         setContentView(webView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
 
         initWebSetting(webView);
@@ -213,6 +211,17 @@ public abstract class BaseWebActivity extends AppCompatActivity {
     private void setPayToJS(){ payToJS = new PayToJS(this,webView); }
     private void setToolToJS(){ toolToJS = new ToolToJS(this,webView); }
 
+    /*-----------------------------------功能函数 start----------------------------------*/
+
+    /*
+     *  将日志发给前端
+     *  @param log    日志内容
+     * */
+
+    public void loggerToJs(String log){
+        getToolToJS().logToJs(log);
+    }
+
     /*------------------------子类获取实例接口------------------------------*/
 
     /**
@@ -220,6 +229,12 @@ public abstract class BaseWebActivity extends AppCompatActivity {
      */
     protected WebView getWebView(){return this.webView;}
 
+    /*
+     * 获取播放器实例
+     * */
+    protected BaseMediaPlayer getMediaPlayer(){return this.mHCPlayer;}
+
+
 
     /*
     * 获取PlayerToJs实例
@@ -227,8 +242,15 @@ public abstract class BaseWebActivity extends AppCompatActivity {
     protected PlayerToJS getPlayerToJS(){return playerToJS;}
 
     /*
-    * 获取播放器实例
-    * */
-    protected BaseMediaPlayer getMediaPlayer(){return this.mHCPlayer;}
+     * 获取PayToJS实例
+     * */
+    protected PayToJS getPayToJS(){return payToJS;}
+
+
+    /*
+     * 获取ToolToJS实例
+     * */
+    protected ToolToJS getToolToJS(){return toolToJS;}
+
 
 }

+ 0 - 82
app/src/main/java/com/haochuan/hciptvbasic/MainActivity.java

@@ -1,38 +1,16 @@
 package com.haochuan.hciptvbasic;
 
-import android.content.Intent;
 import android.os.Bundle;
 
-import com.haochuan.hciptvbasic.Util.Juge;
-import com.haochuan.hciptvbasic.Util.Logger;
-import com.haochuan.hciptvbasic.webview.PlayerToJS;
-
-import org.json.JSONObject;
-
-import java.util.Set;
-
 
 public class MainActivity extends BaseWebActivity {
     private String mBasicUrl = "http://10.255.25.176:8091/sxrj/loading.html";    //入口地址
-    private String mIntentParamsUrl = "";                                               //启动参数拼接地址
-    private String mIntentParamsJson = "";                                              //启动参数集合json
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-    /*    //test
-        String url = "https://gzhc-sxrj.oss-cn-shenzhen.aliyuncs.com/gzhc-djbl/djbl01.mp4";
-        int x = 0;
-        int y = 0;
-        int width = ScreenSnap.getScreenWidth(this);
-        int height = ScreenSnap.getScreenHeight(this);
-        playVideo(url,x,y,width,height);*/
     }
 
-
-
-
-
     /**-------------------BaseWebActivity重载函数 start--------------------------*/
 
     /*
@@ -40,70 +18,10 @@ public class MainActivity extends BaseWebActivity {
     * */
     @Override
     protected String getIndexURL() {
-        //mIntentParams不能为空,而且不能是纯IP地址(深圳天威VV玩具就是纯IP地址),才能加到入口地址中
-        if(!mIntentParamsUrl.isEmpty() && !Juge.isPureIp(mBasicUrl)){
-            mBasicUrl += mIntentParamsUrl;
-        }
         return mBasicUrl;
     }
 
-    //处理启动参数,1,将参数添加到启动链接的参数中;2将其转化为json,传给前端
-    @Override
-    protected void handleIntent(Intent intent) {
-        try{
-            if(intent != null){
-                Bundle bundle = intent.getExtras();
-                if(bundle != null){
-                    Set<String> keySet = bundle.keySet();
-                    JSONObject intentJson = new JSONObject();
-                    int i = 0;
-                    StringBuilder sb = new StringBuilder(mIntentParamsUrl);
-                    for(String key : keySet){
-                        String bundleValue = String.valueOf(bundle.get(key));
-                        intentJson.put(key,bundleValue);
-                        if(i==0 && !mBasicUrl.contains("?")){
-                            sb.append("?");
-                            sb.append(key);
-                            sb.append("=");
-                            sb.append(bundleValue);
-                        }else{
-                            sb.append("&");
-                            sb.append(key);
-                            sb.append("=");
-                            sb.append(bundleValue);
-                        }
-                        i++;
-                    }
-                    mIntentParamsJson = sb.toString();
-                    mIntentParamsJson = intentJson.toString();
-                    Logger.show(this,"mIntentParamsJson:" + mIntentParamsJson);
-
-                }
-            }else{
-                Logger.show(this,"get intent is null");
-            }
-        }catch (Exception e){
-            Logger.show(this,"get intent exception");
-            e.printStackTrace();
-        }
-    }
-
-
     /**-------------------BaseWebActivity重载函数 end--------------------------*/
 
 
-    /*-----------------------------------功能函数 start----------------------------------*/
-
-    /*
-    *  将日志发给前端
-    *  @param log    日志内容
-    * */
-
-    public void loggerToJs(String log){
-        getPlayerToJS().logToJs(log);
-    }
-
-
-
-
 }

+ 86 - 0
app/src/main/java/com/haochuan/hciptvbasic/Util/DownloadUtils.java

@@ -0,0 +1,86 @@
+package com.haochuan.hciptvbasic.Util;
+
+
+import com.liulishuo.filedownloader.BaseDownloadTask;
+import com.liulishuo.filedownloader.FileDownloadLargeFileListener;
+import com.liulishuo.filedownloader.FileDownloader;
+import com.liulishuo.filedownloader.util.FileDownloadUtils;
+
+import java.io.File;
+
+/**
+ * 下载文件工具类
+ */
+public class DownloadUtils {
+
+    /**
+     * 下载文件
+     *
+     * @param url           下载地址
+     * @param fileName      文件名
+     * @param fileExtension 文件扩展名,例如exe,apk,xml等等
+     * @param listener      下载进度监听
+     */
+    public static void download(String url, final String fileName, String fileExtension, final DownloadProgressListener listener) {
+        Logger.d("准备下载文件:%s");
+        final String filePath = FileDownloadUtils.getDefaultSaveRootPath() + File.separator + "temp" + File.separator + fileName + "." + fileExtension;
+        if (listener != null) {
+            listener.onDownloadStart(filePath);
+        }
+        FileDownloader.getImpl().create(url)
+                .setPath(filePath, false)
+                .setCallbackProgressTimes(500)
+                .setMinIntervalUpdateSpeed(400)
+                .setListener(new FileDownloadLargeFileListener() {
+                    @Override
+                    protected void pending(BaseDownloadTask task, long soFarBytes, long totalBytes) {
+
+                    }
+
+                    @Override
+                    protected void progress(BaseDownloadTask task, long soFarBytes, long totalBytes) {
+                        int progress = (int) ((soFarBytes * 100) / totalBytes);
+                        Logger.d(String.format("文件下载中,进度【%s, %s, %s】", soFarBytes, progress, totalBytes));
+                        if (listener != null) {
+                            listener.onDownloadProgress(progress);
+                        }
+                    }
+
+                    @Override
+                    protected void paused(BaseDownloadTask task, long soFarBytes, long totalBytes) {
+
+                    }
+
+                    @Override
+                    protected void completed(BaseDownloadTask task) {
+                        Logger.d(String.format("文件下载成功,路径:%s", filePath));
+                        if (listener != null) {
+                            listener.onDownloadSuccessful(filePath);
+                        }
+                    }
+
+                    @Override
+                    protected void error(BaseDownloadTask task, Throwable e) {
+                        Logger.e(String.format("文件下载异常:%s", e));
+                        if (listener != null) {
+                            listener.onDownloadFail(e.getMessage());
+                        }
+                    }
+
+                    @Override
+                    protected void warn(BaseDownloadTask task) {
+
+                    }
+                }).start();
+    }
+
+    public interface DownloadProgressListener {
+        void onDownloadStart(String fileName);
+
+        void onDownloadProgress(int progress);
+
+        void onDownloadSuccessful(String filePath);
+
+        void onDownloadFail(String message);
+    }
+}

+ 26 - 0
app/src/main/java/com/haochuan/hciptvbasic/Util/JsUtil.java

@@ -0,0 +1,26 @@
+package com.haochuan.hciptvbasic.Util;
+
+import android.app.Activity;
+import android.content.Context;
+import android.os.Build;
+import android.util.Log;
+import android.webkit.WebView;
+
+public class JsUtil {
+    /**
+     * 调用js事件
+     */
+    public static void evaluateJavascript(Context context, WebView webView, String script) {
+        Activity activity = (Activity)context;
+        if (webView == null) {
+            return;
+        }
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            activity.runOnUiThread(()-> webView.evaluateJavascript(script, value -> {
+                //此处为 js 返回的结果
+            }));
+        } else {
+            activity.runOnUiThread(()-> webView.loadUrl(script));
+        }
+    }
+}

+ 30 - 3
app/src/main/java/com/haochuan/hciptvbasic/Util/Logger.java

@@ -5,21 +5,48 @@ import android.util.Log;
 
 import androidx.annotation.NonNull;
 
+import com.haochuan.hciptvbasic.BaseWebActivity;
 import com.haochuan.hciptvbasic.BuildConfig;
 import com.haochuan.hciptvbasic.MainActivity;
 
 public class Logger {
     static String  TAG = "HcIPTV";
+    static Context context;
 
+    public static void init(Context appContext){
+        context = appContext;
+    }
 
-    public static void show(@NonNull Context context, @NonNull String message){
+    public static void d(@NonNull String message){
+        message = "调试 " + message;
         if(BuildConfig.isDebug){
             Log.d(TAG,message);
         }
+        messageToJs(message);
+    }
+
+    public static void w(@NonNull String message){
+        message = "警告! " + message;
+        if(BuildConfig.isDebug){
+            Log.w(TAG,message);
+        }
+        messageToJs(message);
+    }
+
+    public static void e(@NonNull String message){
+        message = "错误! " + message;
+        if(BuildConfig.isDebug){
+            Log.e(TAG,message);
+        }
+        messageToJs(message);
+    }
+
+
+    private static void messageToJs(@NonNull String message){
         //将日志传给MainActivity,然后传给js
         if(context instanceof MainActivity){
-            MainActivity mainActivity = (MainActivity)context;
-            mainActivity.loggerToJs(message);
+            BaseWebActivity baseWebActivity = (BaseWebActivity) context;
+            baseWebActivity.loggerToJs(message);
         }
     }
 

+ 28 - 0
app/src/main/java/com/haochuan/hciptvbasic/Util/MathUtil.java

@@ -0,0 +1,28 @@
+package com.haochuan.hciptvbasic.Util;
+
+import java.util.regex.Pattern;
+
+public class MathUtil {
+
+    public static boolean isDigitsOnly(String str) {
+        return isInteger(str) || isDouble(str);
+    }
+
+    // 判断整数(int)
+    public static boolean isInteger(String str) {
+        if (null == str || "".equals(str)) {
+            return false;
+        }
+        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
+        return pattern.matcher(str).matches();
+    }
+
+    //判断浮点数(double和float)
+    public static boolean isDouble(String str) {
+        if (null == str || "".equals(str)) {
+            return false;
+        }
+        Pattern pattern = Pattern.compile("^[-\\+]?[.\\d]*$");
+        return pattern.matcher(str).matches();
+    }
+}

+ 45 - 0
app/src/main/java/com/haochuan/hciptvbasic/Util/Md5Util.java

@@ -0,0 +1,45 @@
+package com.haochuan.hciptvbasic.Util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.MessageDigest;
+
+public class Md5Util {
+    public static String getFileMD5(File file) {
+        if (!file.isFile()) {
+            return null;
+        }
+        MessageDigest digest = null;
+        FileInputStream in = null;
+        byte buffer[] = new byte[1024];
+        int len;
+        try {
+            digest = MessageDigest.getInstance("MD5");
+            in = new FileInputStream(file);
+            while ((len = in.read(buffer, 0, 1024)) != -1) {
+                digest.update(buffer, 0, len);
+            }
+            in.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+        return bytesToHexString(digest.digest());
+    }
+
+    public static String bytesToHexString(byte[] src) {
+        StringBuilder stringBuilder = new StringBuilder("");
+        if (src == null || src.length <= 0) {
+            return null;
+        }
+        for (int i = 0; i < src.length; i++) {
+            int v = src[i] & 0xFF;
+            String hv = Integer.toHexString(v);
+            if (hv.length() < 2) {
+                stringBuilder.append(0);
+            }
+            stringBuilder.append(hv);
+        }
+        return stringBuilder.toString();
+    }
+}

+ 190 - 0
app/src/main/java/com/haochuan/hciptvbasic/Util/ToolsUtil.java

@@ -0,0 +1,190 @@
+package com.haochuan.hciptvbasic.Util;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Base64;
+import android.util.Log;
+
+import com.yanzhenjie.nohttp.NoHttp;
+import com.yanzhenjie.nohttp.RequestMethod;
+import com.yanzhenjie.nohttp.rest.OnResponseListener;
+import com.yanzhenjie.nohttp.rest.StringRequest;
+
+import org.json.JSONObject;
+
+import java.util.Iterator;
+import java.util.Set;
+
+public class ToolsUtil {
+
+    public boolean checkSubAppInstalled(Context context, String pkgName) {
+        if(context == null){
+            Logger.e("checkSubAppInstalled() context is null,不能执行");
+            return false;
+        }
+        if (pkgName== null || pkgName.isEmpty()) {
+            return false;
+        }
+        PackageInfo packageInfo;
+        try {
+            packageInfo = context.getPackageManager().getPackageInfo(pkgName, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            packageInfo = null;
+            e.printStackTrace();
+        }
+        if(packageInfo == null) {
+            return false;
+        } else {
+            return true;//true为安装了,false为未安装
+        }
+    }
+
+    public void installApk(Context context,String filePath) {
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//4.0以上系统弹出安装成功打开界面
+        context.startActivity(intent);
+    }
+
+    public void uninstall(Context context,String pkgName){
+        Uri uri = Uri.fromParts("package", pkgName, null);
+        Intent intent = new Intent(Intent.ACTION_DELETE, uri);
+        context.startActivity(intent);
+    }
+
+    /*
+     * 获得intent参数集
+     * */
+    public String getIntentJson(Context context){
+        try{
+            Activity activity = (Activity)context;
+            Intent intent = activity.getIntent();
+            if(intent != null){
+                Bundle bundle = intent.getExtras();
+                if(bundle != null){
+                    Set<String> keySet = bundle.keySet();
+                    JSONObject intentJson = new JSONObject();
+                    for(String key : keySet){
+                        Object bundleValue = bundle.get(key);
+                        intentJson.put(key,bundleValue);
+                    }
+                    String getIntentJson = intentJson.toString();
+                    Logger.d("getIntentJson:" + getIntentJson);
+                    return getIntentJson;
+                }else{
+                    Logger.d("getIntentJson, bundle is null");
+                    return "";
+                }
+            }else{
+                Logger.d("getIntentJson, intent is null");
+                return "";
+            }
+        }catch (Exception e){
+            e.printStackTrace();
+            return "";
+        }
+    }
+
+    /*
+     *js 通过apk客户端访问网络接口
+     *@param paramJson 请求参数集,格式为json字符串
+     *@param headJson 请求头部集,格式为json字符串
+     *@param method 请求方法,1,get;2,post
+     *@param ignoreResult 是否忽略结果,true,忽略;false,不忽略.
+     *@param tag 透传参数,将在结果回调中一并返回,主要区别多个并发请求
+     * */
+    public void clientWebRequest(Context context,String url,String paramJson,
+                                 String headJson,int method, boolean ignoreResult,
+                                 String tag,IResponseListener listener){
+        if(url == null || paramJson == null || headJson == null || tag == null){
+            Logger.w(String.format("参数不能为null,url:%s;paramJson:%s;headJson:%s;" +
+                            "method:%s;ignoreResult:%s;tag:%s",url,paramJson,headJson,method,ignoreResult?"忽略结果":"不忽略结果",tag));
+            return;
+        }
+        try{
+            RequestMethod requestMethod ;
+            switch (method){
+                case 1:
+                    requestMethod = RequestMethod.GET;
+                    break;
+                case 2:
+                    requestMethod = RequestMethod.POST;
+                    break;
+                default:
+                    requestMethod = RequestMethod.GET;
+                    break;
+            }
+            if(url.isEmpty()){
+                Logger.w("clientWebRequest,url 不能为空");
+                return;
+            }
+            final StringRequest request = new StringRequest(url, requestMethod);
+            if(!paramJson.isEmpty()){
+                JSONObject jsonParams = new JSONObject(paramJson);
+                Iterator<String> paramIterators = jsonParams.keys();
+                while (paramIterators.hasNext()){
+                    String paramKey = paramIterators.next();
+                    String paramValue = jsonParams.getString(paramKey);
+                    request.add(paramKey,paramValue);
+                }
+            }
+            if(!headJson.isEmpty()){
+                JSONObject headParams = new JSONObject(headJson);
+                Iterator<String> headIterators = headParams.keys();
+                while (headIterators.hasNext()){
+                    String paramKey = headIterators.next();
+                    String paramValue = headParams.getString(paramKey);
+                    request.addHeader(paramKey,paramValue);
+                }
+            }
+
+            NoHttp.newRequestQueue().add(100, request, new OnResponseListener<String>() {
+                @Override
+                public void onStart(int what) {
+                    Logger.d("clientWebRequest,开始请求");
+                }
+
+                @Override
+                public void onSucceed(int what, com.yanzhenjie.nohttp.rest.Response<String> response) {
+                    String data = response.get();
+                    Logger.d("clientWebRequest,请求认证成功!");
+                    String base64Response = Base64.encodeToString(data.getBytes(),Base64.NO_WRAP);
+                    base64Response = base64Response.replace("\n","");
+                    if(ignoreResult){
+                        listener.OnResponse(0,"{}",tag);
+                    }else{
+                        listener.OnResponse(0,base64Response,tag);
+                    }
+                }
+
+                @Override
+                public void onFailed(int what, com.yanzhenjie.nohttp.rest.Response<String> response) {
+                    Logger.w("clientWebRequest,请求认证失败:" + what);
+                    listener.OnResponse(-1,"{}",tag);
+                }
+
+                @Override
+                public void onFinish(int what) {
+                    Logger.d("clientWebRequest,请求认证结束");
+                }
+            });
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+
+
+    /*
+    * clientWebRequest 结果response接口
+    * */
+    public interface IResponseListener{
+        public void OnResponse(int what,String response,String tag);
+    }
+
+}

+ 19 - 9
app/src/main/java/com/haochuan/hciptvbasic/test/TestActivity.java

@@ -1,13 +1,16 @@
 package com.haochuan.hciptvbasic.test;
 
+import android.bluetooth.le.BluetoothLeScanner;
 import android.content.Intent;
 import android.os.Bundle;
 import android.widget.Button;
 
 import com.haochuan.hciptvbasic.BaseWebActivity;
 import com.haochuan.hciptvbasic.R;
+import com.haochuan.hciptvbasic.Util.Logger;
 import com.haochuan.hciptvbasic.Util.ScreenSnap;
 import com.haochuan.hciptvbasic.webview.PlayerToJS;
+import com.haochuan.hciptvbasic.webview.ToolToJS;
 
 public class TestActivity extends BaseWebActivity {
 
@@ -16,10 +19,6 @@ public class TestActivity extends BaseWebActivity {
         return "";
     }
 
-    @Override
-    protected void handleIntent(Intent intent) {
-
-    }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -29,11 +28,11 @@ public class TestActivity extends BaseWebActivity {
         Button playBtn = findViewById(R.id.play_btn);
         playBtn.setOnClickListener(v -> {
             String url = "https://gzhc-sxrj.oss-cn-shenzhen.aliyuncs.com/gzhc-djbl/djbl01.mp4";
-            int x = 0;
-            int y = 0;
-            int width = ScreenSnap.getScreenWidth(TestActivity.this);
-            int height = ScreenSnap.getScreenHeight(TestActivity.this);
-            getPlayerToJS().play(url,x,y,width,height);
+            String x = "0";
+            String y = "0";
+            String width = "1280";
+            String height = "720";
+            getPlayerToJS().play(url,"20",x,y,width,height);
         });
 
         Button pauseBtn = findViewById(R.id.pause_btn);
@@ -64,6 +63,17 @@ public class TestActivity extends BaseWebActivity {
 
         Button exitBtn = findViewById(R.id.exit_btn);
         exitBtn.setOnClickListener(v -> getPlayerToJS().exit());
+
+
+        /*String intentJson = new ToolToJS(this,getWebView()).getIntentJson();
+        Logger.d("intentJson:" + intentJson);*/
+
+        ToolToJS toolToJS = new ToolToJS(this,getWebView());
+        String url = "http://117.169.11.222:8018/tv/index.php";
+        String paramJson = "{\"m\":\"Home\",\"c\":\"Activity\",\"a\":\"getActStatus\"}";
+        String headJson = "{\"cookie\":\"head=123123123131fdfsfsdfs\"}";
+        toolToJS.clientWebRequest(url,paramJson,headJson,2,false,"test");
+        //toolToJS.download("http://202.99.114.74:56251/dudu_youxi/h5/gameList/apk/jiSuKuangBiao.apk");
     }
 
 

+ 7 - 0
app/src/main/java/com/haochuan/hciptvbasic/video/BaseMediaPlayer.java

@@ -29,6 +29,13 @@ public abstract class BaseMediaPlayer extends FrameLayout {
     * */
     public abstract void play(String url);
 
+
+    /*
+     * 设置开始时间
+     *@param url
+     * */
+    public abstract void setStartTime(int time);
+
     /*
      * 恢复
      *@param url

+ 13 - 0
app/src/main/java/com/haochuan/hciptvbasic/video/EmptyControlVideoView.java

@@ -16,6 +16,7 @@ import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer;
 public class EmptyControlVideoView extends StandardGSYVideoPlayer {
 
     IVideoPlayer iVideoPlayerListener ;
+    private int startTime = 0;                                 //播放器开始的时间
 
     public EmptyControlVideoView(Context context, Boolean fullFlag) {
         super(context, fullFlag);
@@ -68,6 +69,15 @@ public class EmptyControlVideoView extends StandardGSYVideoPlayer {
         if(iVideoPlayerListener != null){
             iVideoPlayerListener.onPlaying();
         }
+
+    }
+
+    @Override
+    public void onPrepared() {
+        super.onPrepared();
+        if(startTime > 0){
+            seekTo(startTime);
+        }
     }
 
     @Override
@@ -116,6 +126,9 @@ public class EmptyControlVideoView extends StandardGSYVideoPlayer {
         this.iVideoPlayerListener = iVideoPlayer;
     }
 
+    public void setStartTime(int time){
+        this.startTime = time;
+    };
 
     /*-----------------*/
 

+ 9 - 3
app/src/main/java/com/haochuan/hciptvbasic/video/HCGsyVideoPlayer.java

@@ -14,6 +14,7 @@ public class HCGsyVideoPlayer extends BaseMediaPlayer {
 
     private EmptyControlVideoView mEmptyControlVideo;        //GSY播放器实例
 
+
     public HCGsyVideoPlayer(@NonNull Context context) {
         super(context);
         init(context);
@@ -51,6 +52,11 @@ public class HCGsyVideoPlayer extends BaseMediaPlayer {
     }
 
     @Override
+    public void setStartTime(int time){
+        mEmptyControlVideo.setStartTime(time);
+    };
+
+    @Override
     public void resume() {
         mEmptyControlVideo.onVideoResume();
     }
@@ -65,7 +71,7 @@ public class HCGsyVideoPlayer extends BaseMediaPlayer {
         if(isPrePared()){
             mEmptyControlVideo.seekTo(position);
         }else{
-            Logger.show(mEmptyControlVideo.getCurrentContext(),"视频未准备,不能拖动");
+            Logger.w("视频未准备,不能拖动");
         }
     }
 
@@ -88,7 +94,7 @@ public class HCGsyVideoPlayer extends BaseMediaPlayer {
         if(isPrePared()){
             return mEmptyControlVideo.getDuration();
         }else{
-            Logger.show(mEmptyControlVideo.getCurrentContext(),"视频未准备,不能获得视频总时长");
+            Logger.w("视频未准备,不能获得视频总时长");
             return 0;
         }
     }
@@ -98,7 +104,7 @@ public class HCGsyVideoPlayer extends BaseMediaPlayer {
         if(isPrePared()){
             return mEmptyControlVideo.getCurrentPositionWhenPlaying();
         }else{
-            Logger.show(mEmptyControlVideo.getCurrentContext(),"视频未准备,不能获得视频当前位置");
+            Logger.w("视频未准备,不能获得视频当前位置");
             return 0;
         }
     }

+ 9 - 6
app/src/main/java/com/haochuan/hciptvbasic/video/HCPlayer.java

@@ -55,7 +55,7 @@ public class HCPlayer extends BaseMediaPlayer implements IVideoPlayer{
         if(iVideoPlayerListener != null){
             iVideoPlayerListener.onPreparing();
         }else{
-            Logger.show(CommonUtil.getActivityContext(getContext()),"错误!HCPlayer 未设置监听接口");
+            Logger.e("HCPlayer 未设置监听接口");
         }
     }
 
@@ -64,7 +64,7 @@ public class HCPlayer extends BaseMediaPlayer implements IVideoPlayer{
         if(iVideoPlayerListener != null){
             iVideoPlayerListener.onPlaying();
         }else{
-            Logger.show(CommonUtil.getActivityContext(getContext()),"错误!HCPlayer 未设置监听接口");
+            Logger.e("HCPlayer 未设置监听接口");
         }
     }
 
@@ -78,7 +78,7 @@ public class HCPlayer extends BaseMediaPlayer implements IVideoPlayer{
         if(iVideoPlayerListener != null){
             iVideoPlayerListener.onPause();
         }else{
-            Logger.show(CommonUtil.getActivityContext(getContext()),"错误!HCPlayer 未设置监听接口");
+            Logger.e("HCPlayer 未设置监听接口");
         }
     }
 
@@ -93,7 +93,7 @@ public class HCPlayer extends BaseMediaPlayer implements IVideoPlayer{
         if(iVideoPlayerListener != null){
             iVideoPlayerListener.onPlayingBuffering();
         }else{
-            Logger.show(CommonUtil.getActivityContext(getContext()),"错误!HCPlayer 未设置监听接口");
+            Logger.e("HCPlayer 未设置监听接口");
         }
     }
 
@@ -102,7 +102,7 @@ public class HCPlayer extends BaseMediaPlayer implements IVideoPlayer{
         if(iVideoPlayerListener != null){
             iVideoPlayerListener.onCompletion();
         }else{
-            Logger.show(CommonUtil.getActivityContext(getContext()),"错误!HCPlayer 未设置监听接口");
+            Logger.e("HCPlayer 未设置监听接口");
         }
     }
 
@@ -112,7 +112,7 @@ public class HCPlayer extends BaseMediaPlayer implements IVideoPlayer{
         if(iVideoPlayerListener != null){
             iVideoPlayerListener.onError(what,extra);
         }else{
-            Logger.show(CommonUtil.getActivityContext(getContext()),"错误!HCPlayer 未设置监听接口");
+            Logger.e("HCPlayer 未设置监听接口");
         }
     }
 
@@ -123,6 +123,9 @@ public class HCPlayer extends BaseMediaPlayer implements IVideoPlayer{
     }
 
     @Override
+    public void setStartTime(int time){mHcGsyVideoPlayer.setStartTime(time);};
+
+    @Override
     public void resume() {
         mHcGsyVideoPlayer.resume();
     }

+ 24 - 59
app/src/main/java/com/haochuan/hciptvbasic/webview/PayToJS.java

@@ -1,79 +1,41 @@
 package com.haochuan.hciptvbasic.webview;
 
 import android.content.Context;
-import android.os.Build;
-import android.util.Log;
 import android.webkit.JavascriptInterface;
 import android.webkit.WebView;
 
-import androidx.annotation.StringDef;
-
+import com.haochuan.hciptvbasic.Util.JsUtil;
 import com.haochuan.hciptvbasic.Util.Logger;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-import static com.haochuan.hciptvbasic.webview.PayToJS.JsEvent.JS_EVENT_AUTH_RESULT;
-import static com.haochuan.hciptvbasic.webview.PayToJS.JsEvent.JS_EVENT_PAY_RESULT;
-import static com.haochuan.hciptvbasic.webview.PayToJS.JsEvent.JS_EVENT_SDK_INIT_RESULT;
-
 public class PayToJS {
     private Context context;                        //MainActivity 句柄
     private WebView webView;
 
-    public PayToJS(Context context, WebView webView) {
-        this.context = context;
-        this.webView = webView;
-    }
-
     /**
-     * JS调用类型
+     * 将SDK初始化结果传递给js
+     * 参数:0,成功;-1,失败
      */
-    @StringDef({JS_EVENT_SDK_INIT_RESULT,JS_EVENT_AUTH_RESULT,JS_EVENT_PAY_RESULT})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface JsEvent{
+    String JS_EVENT_SDK_INIT_RESULT = "javascript:onSDKInitResult(%s)";
 
-        /**
-         * 将SDK初始化结果传递给js
-         * 参数:0,成功;-1,失败
-         */
-        String JS_EVENT_SDK_INIT_RESULT = "javascript:onSDKInitResult(%s)";
-
-        /**
-         * 将SDK鉴权结果传递给js
-         * 参数:json字符串
-         */
-        String JS_EVENT_AUTH_RESULT = "javascript:onAuthResult('%s')";
+    /**
+     * 将SDK鉴权结果传递给js
+     * 参数:json字符串
+     */
+    String JS_EVENT_AUTH_RESULT = "javascript:onAuthResult('%s')";
 
 
-        /*
-        * 将计费结果传递给js
-        * 参数:json字符串
-        * */
-        String JS_EVENT_PAY_RESULT = "javascript:onPayResult('%s')";
+    /*
+     * 将计费结果传递给js
+     * 参数:json字符串
+     * */
+    String JS_EVENT_PAY_RESULT = "javascript:onPayResult('%s')";
 
 
+    public PayToJS(Context context, WebView webView) {
+        this.context = context;
+        this.webView = webView;
     }
 
-    /*--------------------功能性函数-----------------------------*/
-    /**
-     * 调用js事件
-     */
-    private void evaluateJavascript(WebView webView, @PayToJS.JsEvent String script) {
-        Logger.show(context,"ToolToJS 执行脚本:" + script);
-        if (webView == null) {
-            Logger.show(context,"webView对象为空,JS事件调用无法执行");
-            return;
-        }
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            webView.evaluateJavascript(script, value -> {
-                //此处为 js 返回的结果
-                Logger.show(context,value);
-            });
-        } else {
-            webView.loadUrl(script);
-        }
-    }
 
     /*---------------------------功能性事件--------------------------------*/
 
@@ -83,6 +45,7 @@ public class PayToJS {
     @JavascriptInterface
     public void sdkInit(String paramsJson){
         //在这里添加SDK初始化逻辑
+        Logger.d("sdkInit");
     }
 
     /*
@@ -91,6 +54,7 @@ public class PayToJS {
     @JavascriptInterface
     public void auth(String paramsJson){
         //在这里添加鉴权逻辑
+        Logger.d("auth");
     }
 
 
@@ -100,6 +64,7 @@ public class PayToJS {
     @JavascriptInterface
     public void pay(String paramsJson){
         //在这里添加支付逻辑
+        Logger.d("pay");
 
     }
 
@@ -109,7 +74,7 @@ public class PayToJS {
     @JavascriptInterface
     public String getUserId(){
         //这这里添加获取用户ID逻辑
-
+        Logger.d("getUserId");
         return "";
     }
 
@@ -120,7 +85,7 @@ public class PayToJS {
      * 参数:0,成功;-1,失败
      */
     public void onSDKInitResult(int code){
-        evaluateJavascript(webView, String.format(JS_EVENT_SDK_INIT_RESULT,code));
+        JsUtil.evaluateJavascript(context,webView, String.format(JS_EVENT_SDK_INIT_RESULT,code));
     }
 
     /**
@@ -128,7 +93,7 @@ public class PayToJS {
      * 参数:json字符串
      */
     public void onAuthResult(String paramJson){
-        evaluateJavascript(webView, String.format(JS_EVENT_SDK_INIT_RESULT,paramJson));
+        JsUtil.evaluateJavascript(context,webView, String.format(JS_EVENT_SDK_INIT_RESULT,paramJson));
     }
 
     /*
@@ -136,6 +101,6 @@ public class PayToJS {
      * 参数:json字符串
      * */
     public void onPayResult(String paramJson){
-        evaluateJavascript(webView, String.format(JS_EVENT_SDK_INIT_RESULT,paramJson));
+        JsUtil.evaluateJavascript(context,webView, String.format(JS_EVENT_SDK_INIT_RESULT,paramJson));
     }
 }

+ 69 - 103
app/src/main/java/com/haochuan/hciptvbasic/webview/PlayerToJS.java

@@ -2,30 +2,17 @@ package com.haochuan.hciptvbasic.webview;
 
 import android.app.Activity;
 import android.content.Context;
-import android.os.Build;
-import android.util.Log;
 import android.view.ViewGroup;
 import android.webkit.JavascriptInterface;
 import android.webkit.WebView;
 import android.widget.FrameLayout;
 
-import androidx.annotation.StringDef;
-
+import com.haochuan.hciptvbasic.Util.JsUtil;
 import com.haochuan.hciptvbasic.Util.Logger;
+import com.haochuan.hciptvbasic.Util.MathUtil;
+import com.haochuan.hciptvbasic.Util.ScreenSnap;
 import com.haochuan.hciptvbasic.video.BaseMediaPlayer;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-import static com.haochuan.hciptvbasic.webview.PlayerToJS.JsEvent.JS_EVENT_COMPLETE;
-import static com.haochuan.hciptvbasic.webview.PlayerToJS.JsEvent.JS_EVENT_DESTROY;
-import static com.haochuan.hciptvbasic.webview.PlayerToJS.JsEvent.JS_EVENT_LOG;
-import static com.haochuan.hciptvbasic.webview.PlayerToJS.JsEvent.JS_EVENT_PAUSE;
-import static com.haochuan.hciptvbasic.webview.PlayerToJS.JsEvent.JS_EVENT_PLAYERROR;
-import static com.haochuan.hciptvbasic.webview.PlayerToJS.JsEvent.JS_EVENT_PLAYING;
-import static com.haochuan.hciptvbasic.webview.PlayerToJS.JsEvent.JS_EVENT_PLAYINGBUFFER;
-import static com.haochuan.hciptvbasic.webview.PlayerToJS.JsEvent.JS_EVENT_PREPARING;
-import static com.haochuan.hciptvbasic.webview.PlayerToJS.JsEvent.JS_EVENT_RESUME;
 
 public class PlayerToJS {
     private Context context;                        //MainActivity 句柄
@@ -33,124 +20,80 @@ public class PlayerToJS {
     private WebView webView;
 
 
+    /*--------------------传给前端的播放器事件--------------------------*/
+    String JS_EVENT_PREPARING = "javascript:onPlayerPreparing()";
+    String JS_EVENT_PLAYING = "javascript:onPlayerPlaying()";
+    String JS_EVENT_RESUME = "javascript:onPlayerResume()";
+    String JS_EVENT_PAUSE = "javascript:onPlayerPause()";
+    String JS_EVENT_DESTROY="javascript:onPlayerDestroy()";
+    String JS_EVENT_PLAYINGBUFFER = "javascript:onPlayingBuffer()";
+    String JS_EVENT_COMPLETE = "javascript:onPlayerComplete()";
+    String JS_EVENT_PLAYERROR="javascript:onPlayerError(%s,%s)";
+
+
     public PlayerToJS(Context context, WebView webView, BaseMediaPlayer mediaPlayer) {
         this.context = context;
         this.baseMediaPlayer = mediaPlayer;
         this.webView = webView;
     }
 
-    /**
-     * JS调用类型
-     */
-    @StringDef({JS_EVENT_LOG,JS_EVENT_PREPARING,JS_EVENT_PLAYING,
-            JS_EVENT_RESUME,JS_EVENT_PAUSE,JS_EVENT_DESTROY,JS_EVENT_PLAYINGBUFFER,
-            JS_EVENT_COMPLETE,JS_EVENT_PLAYERROR})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface JsEvent{
-
-
-        /**
-         * 将日志传递给js
-         */
-        String JS_EVENT_LOG = "javascript:onLog('%s')";
-
-        /*--------------------传给前端的播放器事件--------------------------*/
-        String JS_EVENT_PREPARING = "javascript:onPlayerPreparing()";
-        String JS_EVENT_PLAYING = "javascript:onPlayerPlaying()";
-        String JS_EVENT_RESUME = "javascript:onPlayerResume()";
-        String JS_EVENT_PAUSE = "javascript:onPlayerPause()";
-        String JS_EVENT_DESTROY="javascript:onPlayerDestroy()";
-        String JS_EVENT_PLAYINGBUFFER = "javascript:onPlayingBuffer()";
-        String JS_EVENT_COMPLETE = "javascript:onPlayerComplete()";
-        String JS_EVENT_PLAYERROR="javascript:onPlayerError(%s,%s)";
-    }
-
-    /*--------------------功能性函数-----------------------------*/
-    /**
-     * 调用js事件
-     */
-    private void evaluateJavascript(WebView webView, @JsEvent String script) {
-        Logger.show(context,"PlayerToJS 执行脚本:" + script);
-        if (webView == null) {
-            Logger.show(context,"webView对象为空,JS事件调用无法执行");
-            return;
-        }
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            webView.evaluateJavascript(script, value -> {
-                //此处为 js 返回的结果
-                Logger.show(context,value);
-            });
-        } else {
-            webView.loadUrl(script);
-        }
-    }
-
-    /**-----------------------------------写入前端函数实现-----------------------------------**/
 
 
-    /*
-    * 将log传递给前端
-    * */
-    public void logToJs(String log){
-        evaluateJavascript(webView,
-                String.format(JS_EVENT_LOG,log));
-    }
-
     /*---------------------------事件函数---------------------------*/
     /*
      * 播放器准备事件
      * */
     public void onPlayerPreparing(){
-        evaluateJavascript(webView,JS_EVENT_PREPARING);
+        JsUtil.evaluateJavascript(context,webView,JS_EVENT_PREPARING);
     }
 
     /*
      * 播放器开始播放事件
      * */
     public void onPlayerPlaying(){
-        evaluateJavascript(webView,JS_EVENT_PLAYING);
+        JsUtil.evaluateJavascript(context,webView,JS_EVENT_PLAYING);
     }
 
     /*
      * 播放器继续播放事件
      * */
     public void onPlayerResume(){
-        evaluateJavascript(webView,JS_EVENT_RESUME);
+        JsUtil.evaluateJavascript(context,webView,JS_EVENT_RESUME);
     }
 
     /*
      * 播放器暂停播放事件
      * */
     public void onPlayerPause(){
-        evaluateJavascript(webView,JS_EVENT_PAUSE);
+        JsUtil.evaluateJavascript(context,webView,JS_EVENT_PAUSE);
     }
 
     /*
      * 播放器销毁释放事件
      * */
     public void onPlayerDestroy(){
-        evaluateJavascript(webView,JS_EVENT_DESTROY);
+        JsUtil.evaluateJavascript(context,webView,JS_EVENT_DESTROY);
     }
 
     /*
      * 播放器缓冲事件
      * */
     public void onPlayingBuffer(){
-        evaluateJavascript(webView,JS_EVENT_PLAYINGBUFFER);
+        JsUtil.evaluateJavascript(context,webView,JS_EVENT_PLAYINGBUFFER);
     }
 
     /*
      * 播放器播放完毕事件
      * */
     public void onPlayerComplete(){
-        evaluateJavascript(webView,JS_EVENT_COMPLETE);
+        JsUtil.evaluateJavascript(context,webView,JS_EVENT_COMPLETE);
     }
 
     /*
      * 播放器播放错误事件
      * */
     public void onPlayerError(int what, int extra){
-        evaluateJavascript(webView,String.format(JS_EVENT_PLAYERROR,what,extra));
+        JsUtil.evaluateJavascript(context,webView,String.format(JS_EVENT_PLAYERROR,what,extra));
     }
 
     /*----------------------------------播放器功能函数----------------------------------------*/
@@ -159,17 +102,8 @@ public class PlayerToJS {
     * 播放函数
     * */
     @JavascriptInterface
-    public void play(String url, int x,int y,int width, int height){
-        if(baseMediaPlayer == null){
-            Logger.show(context,"播放器为空,不能播放");
-            return;
-        }
-        Activity activity = (Activity)context;
-        activity.runOnUiThread(()->{
-            initVideoParamsIfNoInit(baseMediaPlayer,x, y, width, height);
-            baseMediaPlayer.play(url);
-            webView.requestFocus();
-        });
+    public void play(String url,String seekTime, String x,String y,String width, String height){
+        videoPlay(url,seekTime,x,y,width,height);
     }
 
     /*
@@ -178,7 +112,7 @@ public class PlayerToJS {
     @JavascriptInterface
     public void pause(){
         if(baseMediaPlayer == null){
-            Logger.show(context,"播放器为空,不能暂停");
+            Logger.e("播放器为空,不能暂停");
             return;
         }
         baseMediaPlayer.pause();
@@ -190,7 +124,7 @@ public class PlayerToJS {
     @JavascriptInterface
     public void resume(){
         if(baseMediaPlayer == null){
-            Logger.show(context,"播放器为空,不能恢复");
+            Logger.e("播放器为空,不能恢复");
             return;
         }
         baseMediaPlayer.resume();
@@ -202,19 +136,12 @@ public class PlayerToJS {
     @JavascriptInterface
     public void seek(int position){
         if(baseMediaPlayer == null){
-            Logger.show(context,"播放器为空,不能拖动");
+            Logger.e("播放器为空,不能拖动");
             return;
         }
         baseMediaPlayer.seek(position);
     }
 
-  /*  *//*
-     * 设定播放速率
-     * *//*
-    @JavascriptInterface
-    public void setPlaySpeed(String speed){
-
-    }*/
 
     /*
      * 资源释放
@@ -222,7 +149,7 @@ public class PlayerToJS {
     @JavascriptInterface
     public void release(){
         if(baseMediaPlayer == null){
-            Logger.show(context,"播放器为空,不能释放资源");
+            Logger.e("播放器为空,不能释放资源");
             return;
         }
         baseMediaPlayer.release();
@@ -234,7 +161,7 @@ public class PlayerToJS {
     @JavascriptInterface
     public void exit(){
         if(baseMediaPlayer == null){
-            Logger.show(context,"播放器为空,不能退出");
+            Logger.e("播放器为空,不能退出");
             return;
         }
         Activity activity = (Activity)context;
@@ -243,6 +170,45 @@ public class PlayerToJS {
 
     /**-------------------------------------------功能函数-----------------------------------------------*/
 
+    /*
+    * 播放
+    * */
+    private void videoPlay(String url,String seekTime, String x,String y,String width, String height){
+        if(baseMediaPlayer == null){
+            Logger.e("播放器为空,不能播放");
+            return;
+        }
+        if(MathUtil.isDigitsOnly(x) && MathUtil.isDigitsOnly(y) && MathUtil.isDigitsOnly(width) && MathUtil.isDigitsOnly(height) && MathUtil.isDigitsOnly(seekTime)){
+            int screenWidth = ScreenSnap.getScreenWidth(context);
+            int screenHeight = ScreenSnap.getScreenHeight(context);
+            int transformX = (int) (Float.parseFloat(x) * screenWidth / 1280);
+            int transformY = (int) (Float.parseFloat(y) * screenHeight / 720);
+            int transformWidth = (int) (Float.parseFloat(width) * screenWidth / 1280);
+            int transformHeight = (int) (Float.parseFloat(height) * screenHeight / 720);
+
+            int transformSeekTime = Integer.parseInt(seekTime);
+            if(transformSeekTime < 0){
+                transformSeekTime = 0;
+            }else{
+                transformSeekTime *= 1000;
+            }
+            final int realSeekTime = transformSeekTime;
+
+            Logger.d(String.format("调用小窗口播放。转换坐标(%s, %s),宽高(%s, %s)", transformX, transformY, transformWidth, transformHeight));
+
+            Activity activity = (Activity)context;
+            activity.runOnUiThread(()->{
+                initVideoParamsIfNoInit(baseMediaPlayer,transformX, transformY, transformWidth, transformHeight);
+                baseMediaPlayer.play(url);
+                baseMediaPlayer.setStartTime(realSeekTime);
+                webView.requestFocus();
+            });
+        }
+
+
+
+    }
+
 
     /*
      * 在视频未初始化的情况下,调用该函数初始化
@@ -253,7 +219,7 @@ public class PlayerToJS {
      * */
     private void initVideoParamsIfNoInit(BaseMediaPlayer baseMediaPlayer,int x, int y, int width, int height){
         if(baseMediaPlayer == null){
-            Logger.show(context,"播放器为空,不能执行initVideoParamsIfNoInit函数");
+            Logger.e("播放器为空,不能执行initVideoParamsIfNoInit函数");
             return;
         }
         FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);

+ 124 - 57
app/src/main/java/com/haochuan/hciptvbasic/webview/ToolToJS.java

@@ -1,75 +1,73 @@
 package com.haochuan.hciptvbasic.webview;
 
 import android.app.Activity;
+import android.app.Dialog;
 import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Build;
+import android.util.TypedValue;
 import android.webkit.JavascriptInterface;
 import android.webkit.WebView;
-
-import androidx.annotation.StringDef;
+import android.widget.TextView;
 
 import com.haochuan.hciptvbasic.BuildConfig;
+import com.haochuan.hciptvbasic.Util.DownloadUtils;
+import com.haochuan.hciptvbasic.Util.JsUtil;
 import com.haochuan.hciptvbasic.Util.Logger;
 import com.haochuan.hciptvbasic.Util.MacUtil;
+import com.haochuan.hciptvbasic.Util.Md5Util;
+import com.haochuan.hciptvbasic.Util.ToolsUtil;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-import static com.haochuan.hciptvbasic.webview.ToolToJS.JsEvent.JS_EVENT_BACK;
+import java.io.File;
 
 
 public class ToolToJS {
     private Context context;                        //MainActivity 句柄
     private WebView webView;
+    private ToolsUtil toolsUtil;
 
-    public ToolToJS(Context context, WebView webView){
-        this.context = context;
-        this.webView = webView;
-    }
+    //将遥控返回按键事件传递给前端
+    String JS_EVENT_BACK = "javascript:onBackEvent()";
 
-    /**
-     * JS调用类型
-     */
-    @StringDef({JS_EVENT_BACK})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface JsEvent{
+    //将日志传递给js
+    String JS_EVENT_LOG = "javascript:onLog('%s')";
+
+    //将response传递给js
+    String JS_EVENT_RESPONSE ="javascript:onWebRequestResponse('%s','%s')";
+
+    //开始下载事件
+    String JS_EVENT_DOWNLOAD_START = "javascript:onDownloadStart()";
+
+    //下载进度通知,参数progress,下载进度
+    String JS_EVENT_DOWNLOAD_PROGRESS = "javascript:onDownloadProgress(%s)";
+
+    //下载成功事件,参数filePath,下载路径
+    String JS_EVENT_DOWNLOAD_SUCCESS = "javascript:onDownloadSuccess('%s')";
+
+    //下载失败事件,参数errorMessage,错误信息
+    String JS_EVENT_DOWNLOAD_FAIL = "javascript:onDownloadFail('%s')";
 
-        /**
-         * 将遥控返回按键传递给js
-         */
-        String JS_EVENT_BACK = "javascript:onBackEvent()";
 
+    public ToolToJS(Context context, WebView webView){
+        this.context = context;
+        this.webView = webView;
+        toolsUtil = new ToolsUtil();
     }
 
     /*------------------------------------功能性函数-----------------------------------------*/
     /*---------------------------------------------------------------------------------------*/
 
-    /**
-     * 调用js事件
-     */
-    private void evaluateJavascript(WebView webView, @ToolToJS.JsEvent String script) {
-        Logger.show(context,"ToolToJS 执行脚本:" + script);
-        if (webView == null) {
-            Logger.show(context,"webView对象为空,JS事件调用无法执行");
-            return;
-        }
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-            webView.evaluateJavascript(script, value -> {
-                //此处为 js 返回的结果
-                Logger.show(context,value);
-            });
-        } else {
-            webView.loadUrl(script);
-        }
+    /*
+     * 将log传递给前端
+     * */
+    public void logToJs(String log){
+        JsUtil.evaluateJavascript(context,webView,
+                String.format(JS_EVENT_LOG,log));
     }
 
     /*
      * webView对象获取"返回"按键事件
      * */
     public void onBackPressed(){
-        evaluateJavascript(webView, JS_EVENT_BACK);
+        JsUtil.evaluateJavascript(context,webView, JS_EVENT_BACK);
     }
 
     /*---------------------------------获取本地参数--------------------------*/
@@ -98,14 +96,69 @@ public class ToolToJS {
         return MacUtil.getMac(context);
     }
 
+    /*
+    * 获取intent启动参数
+    * */
+    @JavascriptInterface
+    public String getIntentJson(){
+        return toolsUtil.getIntentJson(context);
+    }
+
     /*-----------------------------操作APK-------------------------------------*/
 
+    /**
+     * 判定是否安装第三方应用
+     * packageName,包名
+     * 返回 0,安装;-1,未安装
+     * **/
+    @JavascriptInterface
+    public int checkAppInstalled(String packageName){
+        return toolsUtil.checkSubAppInstalled(context,packageName)?1:-1;
+    }
+
+
+    /*
+    * 下载
+    * */
+    @JavascriptInterface
+    public void download(String downloadUrl){
+        DownloadUtils.download(downloadUrl, context.getPackageName() + getVersionCode(), "apk", new DownloadUtils.DownloadProgressListener() {
+            @Override
+            public void onDownloadStart(String fileName) {
+                JsUtil.evaluateJavascript(context,webView,JS_EVENT_DOWNLOAD_START);
+            }
+
+            @Override
+            public void onDownloadProgress(int progress) {
+                JsUtil.evaluateJavascript(context,webView,
+                        String.format(JS_EVENT_DOWNLOAD_START,progress));
+            }
+
+            @Override
+            public void onDownloadSuccessful(String filePath) {
+                JsUtil.evaluateJavascript(context,webView,
+                        String.format(JS_EVENT_DOWNLOAD_SUCCESS,filePath));
+            }
+
+            @Override
+            public void onDownloadFail(String message){
+                JsUtil.evaluateJavascript(context,webView,
+                        String.format(JS_EVENT_DOWNLOAD_FAIL,message));
+            }
+        });
+    }
+
     /*
-    * 查看目标包名app是否安装
+    * 获得下载文件MD5值
     * */
     @JavascriptInterface
-    public void checkInstall(String pkgName) {
-        //((Activity) context).runOnUiThread(() -> installApk(apkPath));
+    public String getMD5(String filePath){
+        try{
+            return Md5Util.getFileMD5(new File(filePath));
+        }catch (Exception e){
+            e.printStackTrace();
+            return "";
+        }
     }
 
     /**
@@ -114,25 +167,39 @@ public class ToolToJS {
      */
     @JavascriptInterface
     public void install(String apkPath) {
-        ((Activity) context).runOnUiThread(() -> installApk(apkPath));
+        ((Activity) context).runOnUiThread(() -> toolsUtil.installApk(context,apkPath));
     }
 
-    private void installApk(String filePath) {
-        Intent intent = new Intent(Intent.ACTION_VIEW);
-        intent.setDataAndType(Uri.parse("file://" + filePath), "application/vnd.android.package-archive");
-        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//4.0以上系统弹出安装成功打开界面
-        context.startActivity(intent);
-    }
+
 
     /**
      * 卸载app
      */
     @JavascriptInterface
-    public void uninstall() {
-        ((Activity) context).runOnUiThread(() -> {
-            Uri uri = Uri.fromParts("package", context.getPackageName(), null);
-            Intent intent = new Intent(Intent.ACTION_DELETE, uri);
-            context.startActivity(intent);
-        });
+    public void uninstall(String pkgName) {
+        ((Activity) context).runOnUiThread(() -> toolsUtil.uninstall(context,pkgName));
+    }
+
+    /*---------------------------通过客户端请求接口------------------------*/
+
+    /*
+     *js 通过apk客户端访问网络接口
+     *@param paramJson 请求参数集,格式为json字符串
+     *@param headJson 请求头部集,格式为json字符串
+     *@param method 请求方法,1,get;2,post
+     *@param ignoreResult 是否忽略结果,true,忽略;false,不忽略.
+     *@param tag 透传参数,将在结果回调中一并返回,主要区别多个并发请求
+     * */
+    @JavascriptInterface
+    public void clientWebRequest(String url,String paramJson,String headJson,int method,boolean ignoreResult,String tag){
+        toolsUtil.clientWebRequest(context, url, paramJson, headJson, method, ignoreResult, tag,
+                (int what,String response,String tag1)->{
+                        if(what == 0){
+                            Logger.d(String.format("response:%s;tag:%s",response,tag1));
+                            JsUtil.evaluateJavascript(context,webView,
+                                    String.format(JS_EVENT_RESPONSE,response,tag1));
+                        }
+                });
     }
+
 }