Pārlūkot izejas kodu

commit by xulin
20190315

lyn 6 gadi atpakaļ
vecāks
revīzija
163f22be44
30 mainītis faili ar 800 papildinājumiem un 109 dzēšanām
  1. 6 3
      app/build.gradle
  2. 1 1
      app/release/output.json
  3. 0 35
      app/src/main/AndroidManifest.xml
  4. 127 16
      app/src/main/java/com/hc/webapp/MainActivity.java
  5. 4 4
      app/src/main/java/com/hc/webapp/video/VideoControlDelegate.java
  6. 22 2
      app/src/main/java/com/hc/webapp/web/AndroidToJS.java
  7. 62 0
      app/src/main/java/com/hc/webapp/web/BaseWebActivity.java
  8. 87 0
      app/src/main/java/com/hc/webapp/web/DownloadInstall.java
  9. 1 1
      app/src/main/java/com/hc/webapp/web/MD5.java
  10. BIN
      app/src/main/res/drawable-hdpi/img_start_bg.jpg
  11. BIN
      app/src/main/res/drawable-ldpi/img_start_bg.jpg
  12. BIN
      app/src/main/res/drawable-mdpi-1280x720/img_start_bg.jpg
  13. BIN
      app/src/main/res/drawable-mdpi-1920x1080/img_start_bg.jpg
  14. BIN
      app/src/main/res/drawable-mdpi/img_start_bg.jpg
  15. BIN
      app/src/main/res/drawable-xhdpi/img_start_bg.jpg
  16. BIN
      app/src/main/res/drawable-xxhdpi/img_start_bg.jpg
  17. 7 2
      core/src/main/java/com/jewel/mplayer/system/SystemVideoView.java
  18. 143 0
      lib/src/main/java/com/hc/lib/store/LastPlayTimeStore.java
  19. 38 0
      lib/src/main/java/com/hc/lib/store/TvDB.java
  20. 5 0
      lib/src/main/java/com/hc/lib/video/IVideoPlayer.java
  21. 227 40
      lib/src/main/java/com/hc/lib/video/MVideoPlayer.java
  22. 8 5
      lib/src/main/java/com/hc/lib/video/VideoPauseDialog.java
  23. 27 0
      lib/src/main/res/layout/layout_m_player.xml
  24. 5 0
      lib/src/main/res/values-hdpi/dimens.xml
  25. 5 0
      lib/src/main/res/values-ldpi/dimens.xml
  26. 5 0
      lib/src/main/res/values-mdpi-1280x720/dimens.xml
  27. 5 0
      lib/src/main/res/values-mdpi-1920x1080/dimens.xml
  28. 5 0
      lib/src/main/res/values-xhdpi/dimens.xml
  29. 5 0
      lib/src/main/res/values-xxhdpi/dimens.xml
  30. 5 0
      lib/src/main/res/values-xxxhdpi/dimens.xml

+ 6 - 3
app/build.gradle

@@ -11,16 +11,17 @@ android {
     }
     compileSdkVersion versions.compileSdk
     defaultConfig {
-        applicationId "com.sxyd.dudutoy"
+        applicationId "com.sxyd.duduUp"
         minSdkVersion versions.minSdk
         targetSdkVersion versions.targetSdk
-        versionCode 1
-        versionName "v1.0.1"
+        versionCode 4
+        versionName "v1.0.4"
         ndk {
             //APP的build.gradle设置支持的SO库架构
             abiFilters 'armeabi', 'armeabi-v7a'
         }
         testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        buildConfigField 'int','platformType','2'   ////1:百事通,2:银河,3:未来
     }
     buildTypes {
         debug {
@@ -65,4 +66,6 @@ dependencies {
         exclude group: "com.android.support"
     }
     implementation 'com.squareup.okhttp3:okhttp:3.12.1'
+    implementation 'com.liulishuo.filedownloader:library:1.7.5'
+    implementation 'com.android.volley:volley:1.1.1'
 }

+ 1 - 1
app/release/output.json

@@ -1 +1 @@
-[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"v1.0.1","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
+[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":4,"versionName":"v1.0.4","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]

+ 0 - 35
app/src/main/AndroidManifest.xml

@@ -2,49 +2,14 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.hc.webapp">
 
-    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
     <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
-    <uses-permission android:name="android.permission.RECORD_AUDIO" />
-
-    <!-- 电信易视腾所需权限 -->
-    <uses-permission android:name="android.permission.SEND_SMS" />
-    <uses-permission android:name="android.permission.READ_CONTACTS" />
-
     <!-- 未来电视所需权限 -->
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.READ_LOGS" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
-    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
-    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
-    <uses-permission android:name="android.permission.GET_TASKS" />
-    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
-    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-    <uses-permission android:name="android.permission.REORDER_TASKS" />
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
-    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
-    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
-
-    <uses-permission android:name="android.permission.GET_TASKS" />
-
-    <uses-permission android:name="android.permission.REAL_GET_TASKS" />
-
-    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
-
-    <uses-permission android:name="com.starcor.hunan.ReadUserinfo" />
-
-    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
-
-    <uses-permission android:name="com.huawei.hmt.provider.stbconfig.permission.READ" />
-
-    <uses-permission android:name="com.huawei.hmt.provider.stbconfig.permission.WRITE" />
-
-    <uses-permission android:name="android.permission.WAKE_LOCK" />
 
     <application
         android:name=".BaseApp"

+ 127 - 16
app/src/main/java/com/hc/webapp/MainActivity.java

@@ -17,6 +17,11 @@ import android.view.animation.LinearInterpolator;
 import android.widget.FrameLayout;
 import android.widget.Toast;
 
+import com.android.volley.NetworkResponse;
+import com.android.volley.VolleyError;
+import com.android.volley.toolbox.HttpHeaderParser;
+import com.android.volley.toolbox.StringRequest;
+import com.android.volley.toolbox.Volley;
 import com.hc.lib.http.GetRequest;
 import com.hc.lib.http.GetRequestListener;
 import com.hc.lib.video.MVideoPlayer;
@@ -31,12 +36,17 @@ import com.orhanobut.logger.Logger;
 import org.json.JSONArray;
 import org.json.JSONObject;
 
+import java.io.UnsupportedEncodingException;
 import java.util.Timer;
 import java.util.TimerTask;
 
+
 public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVideoListener {
 
-    final String url = com.hc.model.BuildConfig.Domain + com.hc.model.BuildConfig.port + "/h5v2/index.html";
+        final String url = com.hc.model.BuildConfig.Domain + com.hc.model.BuildConfig.port + "/h5v2/index.html";
+    //final String url = "http://112.35.32.145:8090/h5v2/template/haochuan.html";  //活动测试地址
+    //final String url ="http://112.35.32.145:8090/h5v2/subject/zt20190222/index.html";
+    //final String url = com.hc.model.BuildConfig.Domain + com.hc.model.BuildConfig.port + "/h5v2/template/haochuan.html";
     //final String url ="http://112.35.32.145:8090/h5v2/sxyd_djbl.html?epgServer=http://111.20.42.147:33200&sourceId=1363&token=tgS09L3h7qp3w9-StjtSpqfq5";
 
 //    public static final String[] urls = {"http://9890.vod.myqcloud.com/9890_4e292f9a3dd011e6b4078980237cc3d3.f20.mp4",
@@ -56,7 +66,7 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
 
     private VideoInfo lastVideoInfo;
 
-    private String TAG ="SXYD";
+    private String TAG ="MainActivity";
 
     //add by 许林
     //float density = 0;
@@ -69,6 +79,9 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
 
    // String myUid = "123456";
 
+    //private VideoInfo currentFloatInfo;
+
+
     @Override
     protected void onCreate(@Nullable Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -78,6 +91,7 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
         screenHeight = displayMetrics.heightPixels;
         Log.d("MainActivity", "; width:" + screenWidth + "; height:" + screenHeight);
 
+
         videoPlayer = new MVideoPlayer(MainActivity.this);
         videoPlayer.setActivity(this);
         // 是否需要显示流量提示
@@ -86,6 +100,9 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
         controlDelegate = new VideoControlDelegate(this, videoPlayer);
         controlDelegate.subscribeData();
         controlDelegate.getExitPlayingEvent().observe(this, aBoolean -> {
+            //判断视频是否播放完成,来判断是否要储存上次播放时间
+            videoPlayer.storeLastPlayTime();
+
             if (hadFloatVideo) {
                 videoPlayer.hideAllWidget();
                 changeVideo2Float();
@@ -100,7 +117,6 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
             }
         });
 
-
         videoPlayer.setOnPlayerPausedListener(controlDelegate);
 
         //test
@@ -110,6 +126,33 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
 //        videoPlayer.setLooping(false);
     }
 
+   /* private void initMediaPlayer(){
+        videoPlayer = new MVideoPlayer(MainActivity.this);
+        videoPlayer.setActivity(this);
+        controlDelegate = new VideoControlDelegate(this, videoPlayer);
+        controlDelegate.subscribeData();
+        controlDelegate.getExitPlayingEvent().observe(this, aBoolean -> {
+            //判断视频是否播放完成,来判断是否要储存上次播放时间
+            videoPlayer.storeLastPlayTime();
+
+            if (hadFloatVideo) {
+                videoPlayer.hideAllWidget();
+                changeVideo2Float();
+            } else {
+                destroyVideo();
+            }
+        });
+        controlDelegate.getPlayNextEvent().observe(this, playNext -> {
+            Logger.d("请求下一个视频 %s", playNext);
+            if(playNext != null && playNext) {
+                AndroidToJS.evaluateJavascript(getWebView(), AndroidToJS.JS_EVENT_PLAY_NEXT);
+            }
+        });
+
+        videoPlayer.setOnPlayerPausedListener(controlDelegate);
+    }*/
+
+
     @Override
     protected void destroyVideoView() {
         destroyVideo();
@@ -182,10 +225,7 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
     @Override
     public void playFloatVideo(final String url, final int x, final int y, final int width, final int height,
                                final String uid, final String sourceId, final String title, boolean needMute) {
-        if(url.isEmpty() || url == null){
-            Toast.makeText(this,"视频链接错误!",Toast.LENGTH_SHORT).show();
-            return;
-        }
+        //currentFloatInfo = new VideoInfo(url,x,y,width,height,uid,sourceId,title,needMute);
         if(!hasShowWebView){
             hasOneFloatViewToShow = true;
             lastVideoInfo = new VideoInfo(url,x,y,width,height,uid,sourceId,title,needMute);
@@ -201,17 +241,16 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
     @Override
     public void playFullVideo(final String url, final String title, final String uid, final String sourceId, final long playTime,
                               final boolean hadFloatVideo, boolean showCompleteDialog, int seekTime) {
-        if(url.isEmpty() || url == null){
-            Toast.makeText(this,"视频链接错误!",Toast.LENGTH_SHORT).show();
-            return;
-        }
+
         this.hadFloatVideo = hadFloatVideo;
         videoPlayer.setShowCompleteDialog(showCompleteDialog);
         runOnUiThread(() -> {
             if (hadFloatVideo && TextUtils.isEmpty(url)) {
                 changeVideo2Full();
+                Log.d(TAG,"changeVideo2Full");
             } else {
                 playVideo(url, title, uid, sourceId, playTime, seekTime);
+                Log.d(TAG,"playVideo");
             }
         });
     }
@@ -221,6 +260,7 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
     * */
 
     public void favoritePlay(String sourceId,String title){
+        videoPlayer.storeLastPlayTime();
         String url = "http://112.35.32.145:8090/index.php?m=Home&c=Order&a=authorize&sourceId="
                 + sourceId + "&EpgServer=" + getUserEpgServer() + "&token=" + getUserToken();
         new GetRequest().RequestAsync(url, new GetRequestListener() {
@@ -257,6 +297,52 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
         runOnUiThread(this::destroyVideo);
     }
 
+    @Override
+    public void webRequest(String tag, String url) {
+        Log.d(TAG,"webRequest,url:" + url);
+        MyRequest stringRequest = new MyRequest(com.android.volley.Request.Method.GET,url, new com.android.volley.Response.Listener<String>() {
+            @Override
+            public void onResponse(String response) {
+                //Log.d(TAG,"访问成功,data:" + response);
+                backToWeb(tag,response);
+            }
+        }, new com.android.volley.Response.ErrorListener() {
+            @Override
+            public void onErrorResponse(VolleyError error) {
+
+            }
+        });
+        Volley.newRequestQueue(this).add(stringRequest);
+    }
+
+    public void backToWeb(String tag,String response){
+        String script = "javascript:onWebRequestResponse('"+tag+"','"+response+"')";
+        Log.d(TAG,script);
+        AndroidToJS.evaluateJavascript(getWebView(),"javascript:onWebRequestResponse('"+tag+"','"+response+"')");
+    }
+
+    class MyRequest extends StringRequest {
+
+        public MyRequest(int method, String url, com.android.volley.Response.Listener<String> listener, @Nullable com.android.volley.Response.ErrorListener errorListener) {
+            super(method, url, listener, errorListener);
+        }
+
+        @Override
+        protected com.android.volley.Response<String> parseNetworkResponse(NetworkResponse response) {
+            String parsed;
+            try {
+                parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers,"utf-8"));
+            } catch (UnsupportedEncodingException e) {
+                // Since minSdkVersion = 8, we can't call
+                // new String(response.data, Charset.defaultCharset())
+                // So suppress the warning instead.
+                parsed = new String(response.data);
+            }
+            return com.android.volley.Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));
+        }
+
+    }
+
     /**
      * 全屏播放逻辑
      */
@@ -353,6 +439,11 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
         if (!isFullScreenVideo) {
             return;
         }
+
+        if (videoPlayer != null && videoPlayer.getWidth() == screenWidth) {
+            AndroidToJS.evaluateJavascript(getWebView(), AndroidToJS.JS_EVENT_PLAY_FINISH);
+            Log.d(TAG,"PLAY_FINISH");
+        }
         if (videoPlayer != null) {
             isFullScreenVideo = false;
             controlDelegate.setFullVideo(false);
@@ -363,6 +454,15 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
             animChanged(0, floatVideoX, 0, floatVideoY,
                     screenWidth, floatVideoWidth,
                     screenHeight, floatVideoHeight,false);
+
+           /* destroyVideo();
+
+            initMediaPlayer();
+
+            playVideo(currentFloatInfo.url,currentFloatInfo.title,currentFloatInfo.uid,currentFloatInfo.sourceId,
+                    currentFloatInfo.x,currentFloatInfo.y,currentFloatInfo.width,currentFloatInfo.height,
+                    currentFloatInfo.needMute);*/
+
         }
     }
 
@@ -396,15 +496,24 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
     }
 
     private void destroyVideo() {
-        isFullScreenVideo = false;
-        controlDelegate.setFullVideo(false);
-        if (videoPlayer != null && videoPlayer.getWidth() == screenWidth) {
-
-            AndroidToJS.evaluateJavascript(getWebView(), AndroidToJS.JS_EVENT_PLAY_FINISH);
+        try{
+            isFullScreenVideo = false;
+            controlDelegate.setFullVideo(false);
+            if(videoPlayer == null){
+                return;
+            }
+            if (videoPlayer != null && videoPlayer.getWidth() == screenWidth) {
+                AndroidToJS.evaluateJavascript(getWebView(), AndroidToJS.JS_EVENT_PLAY_FINISH);
+                Log.d(TAG,"PLAY_FINISH");
+            }
+            videoPlayer.hideSeekContainer();
             videoPlayer.onVideoPause();
             videoPlayer.onVideoDestroy();
+
             ViewGroup viewGroup = (ViewGroup) getWindow().getDecorView();
             viewGroup.removeView(videoPlayer);
+        }catch (Exception e){
+            e.printStackTrace();
         }
     }
 
@@ -439,6 +548,7 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
             Cursor cursor = getContentResolver().query(queryUri,new String[]{"value"},"name='user_token'",null,null);
             cursor.moveToFirst();
             String userToken = cursor.getString(cursor.getColumnIndexOrThrow("value"));
+            //userToken = "Se48ja9jiqjq-Stjhd4izfd";
             Log.d(TAG,"userToken:" + userToken);
             return userToken;
         }catch (Exception e){
@@ -453,6 +563,7 @@ public class MainActivity extends BaseWebActivity implements AndroidToJS.PlayVid
             Cursor cursor = getContentResolver().query(queryUri,new String[]{"value"},"name='epg_server'",null,null);
             cursor.moveToFirst();
             String epgServer = cursor.getString(cursor.getColumnIndexOrThrow("value"));
+            //epgServer = "http://111.20.42.163:33200";
             Log.d(TAG,"epgServer:" + epgServer);
             return epgServer;
         }catch (Exception e){

+ 4 - 4
app/src/main/java/com/hc/webapp/video/VideoControlDelegate.java

@@ -129,9 +129,9 @@ public class VideoControlDelegate implements VideoPauseDialog.OnPlayItemSelected
     }
 
     public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
-            playResume(false);
-
+        if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
+            //playResume(false);
+            videoPlayer.keyCodeBack();
         }
         else {
             videoPlayer.onKeyDown(keyCode, event);
@@ -191,7 +191,7 @@ public class VideoControlDelegate implements VideoPauseDialog.OnPlayItemSelected
     }
 
     @Override
-    public void playExit() {
+    public void playExit(boolean playComplete) {
         exitPlayingEvent.setValue(true);
     }
 

+ 22 - 2
app/src/main/java/com/hc/webapp/web/AndroidToJS.java

@@ -50,6 +50,8 @@ public class AndroidToJS {
 //    private String testVideo = "http://163.com-www-letv.com/20180509/457_79ed60e3/index.m3u8";
     private String testVideo = "http://192.168.2.112/000079/000079.m3u8";
 
+    private int platformType = BuildConfig.platformType; //1:百事通,2:银河,3:未来
+
     /**
      * JS调用类型
      */
@@ -115,7 +117,6 @@ public class AndroidToJS {
     public void playFull(String url, String sourceId, String title, String time, String hadFloatVideo, String isNextVideo, String showCompleteDialog, int seekTime) {
         Logger.d("调用全屏播放。源ID(%s),标题(%s),播放地址(%s)", sourceId, title, url);
         if (playVideoListener != null) {
-
             playTime = PLAY_TIME_NO_LIMIT;
             if (isDigitsOnly(time)) {
                 playTime = Long.parseLong(time);
@@ -132,7 +133,7 @@ public class AndroidToJS {
         if (isNextVideo) { // 播放下一条视频时,直接在当前全屏窗口开启新视频的播放
             playVideoListener.playFullVideo(url, title, getUserName(), sourceId, time, hadFloat, showCompleteDialog, seekTime);
         } else if (hadFloat) { // 有小窗时,直接切换成全屏
-            playVideoListener.playFullVideo(null, title, getUserName(), sourceId, time, true, showCompleteDialog, 0);
+            playVideoListener.playFullVideo(url, title, getUserName(), sourceId, time, true, showCompleteDialog, 0);
         } else { // 开启新的全屏播放窗口
             playVideoListener.playFullVideo(url, title, getUserName(), sourceId, time, false, showCompleteDialog, seekTime);
         }
@@ -252,10 +253,20 @@ public class AndroidToJS {
     }
 
     @JavascriptInterface
+    public int getPlatformType() {
+        return platformType;
+    }
+
+    @JavascriptInterface
     public void pay() {
     }
 
     @JavascriptInterface
+    public void webRequest(String tag,String url){
+        playVideoListener.webRequest(tag,url);
+    }
+
+    @JavascriptInterface
     public void appExit() {
         ((Activity) context).runOnUiThread(() -> ((Activity) context).finish());
         System.exit(0);
@@ -383,6 +394,8 @@ public class AndroidToJS {
             Cursor cursor = context.getContentResolver().query(queryUri,new String[]{"value"},"name='user_token'",null,null);
             cursor.moveToFirst();
             String userToken = cursor.getString(cursor.getColumnIndexOrThrow("value"));
+            //userToken = "nBoKXx@OHP3fUP6fmcypIgl135856057";
+            //userToken = "Se48ja9jiqjq-Stjhd4izfd";
             Log.d(TAG,"userToken:" + userToken);
             return userToken;
         }catch (Exception e){
@@ -397,6 +410,8 @@ public class AndroidToJS {
             Cursor cursor = context.getContentResolver().query(queryUri,new String[]{"value"},"name='epg_server'",null,null);
             cursor.moveToFirst();
             String epgServer = cursor.getString(cursor.getColumnIndexOrThrow("value"));
+            //epgServer = "http://111.20.105.85:9330";
+            //epgServer = "http://111.20.42.163:33200";
             Log.d(TAG,"epgServer:" + epgServer);
             return epgServer;
         }catch (Exception e){
@@ -436,5 +451,10 @@ public class AndroidToJS {
          * 结束小窗播放
          */
         void stopFloatVideo();
+
+        /*
+         * 前端网络访问;
+         * */
+        void webRequest(String tag,String url);
     }
 }

+ 62 - 0
app/src/main/java/com/hc/webapp/web/BaseWebActivity.java

@@ -1,14 +1,17 @@
 package com.hc.webapp.web;
 
 import android.annotation.SuppressLint;
+import android.app.DownloadManager;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
+import android.net.Uri;
 import android.net.wifi.WifiManager;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Environment;
 import android.support.annotation.Nullable;
 import android.support.v4.content.ContextCompat;
 import android.support.v7.app.AppCompatActivity;
@@ -17,22 +20,29 @@ import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.WindowManager;
+import android.webkit.URLUtil;
 import android.webkit.WebSettings;
 import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.RelativeLayout;
+import android.widget.Toast;
 
 import com.hc.webapp.BuildConfig;
+import com.hc.webapp.MainActivity;
 import com.hc.webapp.NetworkConnectChangedListener;
 import com.hc.webapp.NetworkConnectChangedReceiver;
 import com.hc.webapp.R;
 
 
+import org.json.JSONObject;
+
+import java.net.HttpURLConnection;
 import java.util.Timer;
 import java.util.TimerTask;
 
+
 @SuppressWarnings("unused")
 public abstract class BaseWebActivity extends AppCompatActivity {
 
@@ -56,6 +66,9 @@ public abstract class BaseWebActivity extends AppCompatActivity {
      */
     private boolean shouldOverrideBackPressToJS = true;
 
+    private int platformType = BuildConfig.platformType; //1:百事通,2:银河,3:未来
+
+
     /**
      * 监听网络状态广播
      */
@@ -357,11 +370,13 @@ public abstract class BaseWebActivity extends AppCompatActivity {
             @Override
             public void onPageFinished(WebView view, String url)
             {
+                Log.d("MainActivity","onPageFinished");
                 hasShowWebView = true;
                 webView.setVisibility(View.VISIBLE);
                 if(hasOneFloatViewToShow){
                     delayShowFloatView();
                 }
+                updateApk();
             }
 
             @Override
@@ -375,6 +390,53 @@ public abstract class BaseWebActivity extends AppCompatActivity {
         }
     }
 
+    protected void updateApk(){
+        String url = "http://112.35.32.145:8090/index.php?m=Home&c=AndroidApi&a=uploadVersion&origin="+platformType;
+        GetRuquest getRuquest = new GetRuquest();
+        getRuquest.RequestAsync(url, new GetRequestListener() {
+            @Override
+            public void onResult(String msg) {
+                try{
+                    JSONObject jsonObject = new JSONObject(msg);
+                    int code = jsonObject.getInt("code");
+                    if(code == 0){
+                        JSONObject data = jsonObject.getJSONObject("data");
+                        int versionCode = data.getInt("versionCode");
+                        int currentVCode = BaseWebActivity.this.getPackageManager().getPackageInfo(
+                                BaseWebActivity.this.getPackageName(),0
+                        ).versionCode;
+                        boolean hasUpdate = false;
+                        if(versionCode > currentVCode){
+                            hasUpdate = true;
+                            Toast("版本有更新,后台正在下载中...");
+                            String versionName = data.getString("versionName");
+                            String url = data.getString("url");
+                            int size = data.getInt("size");
+                            String updateContent = data.getString("updateContent");
+                            String md5 = data.getString("md5");
+                            new DownloadInstall(BaseWebActivity.this).start(url,md5);
+                        }
+
+                    }
+                }catch (Exception e){
+                    e.printStackTrace();
+                }
+            }
+        });
+    }
+
+
+
+
+    private void Toast(String msg){
+        BaseWebActivity.this.runOnUiThread(new Runnable() {
+            @Override
+            public void run() {
+                Toast.makeText(BaseWebActivity.this,msg,Toast.LENGTH_SHORT).show();
+            }
+        });
+    }
+
     protected abstract void delayShowFloatView();
 
     @Override

+ 87 - 0
app/src/main/java/com/hc/webapp/web/DownloadInstall.java

@@ -1,4 +1,91 @@
 package com.hc.webapp.web;
 
+import android.app.DownloadManager;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.support.v4.content.FileProvider;
+import android.util.Log;
+import android.webkit.URLUtil;
+
+import com.hc.webapp.BuildConfig;
+import com.liulishuo.filedownloader.BaseDownloadTask;
+import com.liulishuo.filedownloader.FileDownloadListener;
+import com.liulishuo.filedownloader.FileDownloader;
+import com.liulishuo.filedownloader.util.FileDownloadUtils;
+
+import java.io.File;
+
 public class DownloadInstall {
+    private String TAG = "DownloadInstall";
+    private Context context;
+    public  DownloadInstall(Context context){
+        this.context = context;
+    }
+    public void start(String url,String md5){
+        downloadApk(url,md5);
+    }
+
+    private void downloadApk(final String url,final String md5){
+        String filePath = FileDownloadUtils.getDefaultSaveRootPath();
+        FileDownloader.getImpl().create(url)
+                .setPath(filePath,true)
+                .setCallbackProgressTimes(300)
+                .setMinIntervalUpdateSpeed(400)
+                .setListener(new FileDownloadListener() {
+                    @Override
+                    protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
+
+                    }
+
+                    @Override
+                    protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
+
+                    }
+
+                    @Override
+                    protected void completed(BaseDownloadTask task) {
+                        File file = new File( FileDownloadUtils.getDefaultSaveFilePath(url));
+                        String apkMD5 = MD5.getFileMD5(file).toUpperCase();
+                        String updateD5 = md5.toUpperCase();
+                        if(!apkMD5.equals(updateD5)){
+                            file.delete();
+                            downloadApk(url,md5);
+                        }else{
+                            apkInstall(file);
+                        }
+                    }
+
+                    @Override
+                    protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
+
+                    }
+
+                    @Override
+                    protected void error(BaseDownloadTask task, Throwable e) {
+                        e.printStackTrace();
+                    }
+
+                    @Override
+                    protected void warn(BaseDownloadTask task) {
+
+                    }
+                })
+                .start();
+    }
+
+    private void apkInstall(File apkFile){
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){
+            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+            Uri contentUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".fileProvider", apkFile);
+            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
+        }else{
+            intent.setDataAndType(Uri.fromFile(apkFile),
+                    "application/vnd.android.package-archive");
+        }
+        context.startActivity(intent);
+    }
 }

+ 1 - 1
app/src/main/java/com/hc/webapp/web/MD5.java

@@ -1,4 +1,4 @@
-package com.guangzhou.haochuan.jxtv.util;
+package com.hc.webapp.web;
 
 import java.io.File;
 import java.io.FileInputStream;

BIN
app/src/main/res/drawable-hdpi/img_start_bg.jpg


BIN
app/src/main/res/drawable-ldpi/img_start_bg.jpg


BIN
app/src/main/res/drawable-mdpi-1280x720/img_start_bg.jpg


BIN
app/src/main/res/drawable-mdpi-1920x1080/img_start_bg.jpg


BIN
app/src/main/res/drawable-mdpi/img_start_bg.jpg


BIN
app/src/main/res/drawable-xhdpi/img_start_bg.jpg


BIN
app/src/main/res/drawable-xxhdpi/img_start_bg.jpg


+ 7 - 2
core/src/main/java/com/jewel/mplayer/system/SystemVideoView.java

@@ -78,6 +78,7 @@ public class SystemVideoView extends CoreVideoView {
     @Override
     public void seekTo(int milliseconds) {
         if(canSeek()) {
+            Log.d(TAG, "seek to milliseconds:" + milliseconds);
             videoView.seekTo(milliseconds);
         }
     }
@@ -113,9 +114,13 @@ public class SystemVideoView extends CoreVideoView {
 
     public int getDuration() {
         if (mediaPlayer != null) {
-            return mediaPlayer.getDuration();
-        }
+            try{
+                return mediaPlayer.getDuration();
+            }catch (Exception e){
+                e.printStackTrace();
+            }
 
+        }
         return -1;
     }
 

+ 143 - 0
lib/src/main/java/com/hc/lib/store/LastPlayTimeStore.java

@@ -0,0 +1,143 @@
+package com.hc.lib.store;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/18.
+ */
+
+public class LastPlayTimeStore {
+    private static LastPlayTimeStore instance = null;
+    private TvDB tvDB = null;
+
+    public LastPlayTimeStore(Context context){
+        tvDB = TvDB.getInstance(context);
+    }
+
+    public static final synchronized LastPlayTimeStore getInstance(Context context){
+        if(instance == null){
+            instance = new LastPlayTimeStore(context);
+        }
+        return instance;
+    }
+
+    public void onCreate(SQLiteDatabase db){
+        String createTableSql = "CREATE VIRTUAL TABLE IF NOT EXISTS " + SearchIndexColumns.tableName
+                +" USING fts3 "
+                + " ( "
+                + SearchIndexColumns.sourceId + " STRING ,"
+                + SearchIndexColumns.time + " STRING ,"
+                + SearchIndexColumns.insertTime + " DATETIME DEFAULT CURRENT_TIMESTAMP ) ";
+        try{
+            db.execSQL(createTableSql);
+        }catch (Exception e){
+            e.printStackTrace();
+        }
+    }
+
+    public boolean tableIsExist(SQLiteDatabase db, String tableName){
+        boolean result = false;
+        if(tableName == null){
+            return false;
+        }
+        Cursor cursor = null;
+        try {
+            String sql = "select count(*) as c from Sqlite_master  where type ='table' and name ='"+tableName.trim()+"' ";
+            cursor = db.rawQuery(sql, null);
+            if(cursor.moveToNext()){
+                int count = cursor.getInt(0);
+                if(count>0){
+                    result = true;
+                }
+            }
+            cursor.close();
+        } catch (Exception e) {
+            // TODO: handle exception
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+    public void insert(String time,String sourceId){
+        delete(sourceId);
+        SQLiteDatabase database = tvDB.getWritableDatabase();
+        if(!tableIsExist(database,SearchIndexColumns.tableName)){
+            return;
+        }
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(SearchIndexColumns.sourceId,sourceId);
+        contentValues.put(SearchIndexColumns.time,time);
+        SimpleDateFormat dateFormat = new SimpleDateFormat(
+                "yyyy-MM-dd HH:mm:ss");
+        Date nowDate = new Date();
+        contentValues.put(SearchIndexColumns.insertTime,dateFormat.format(nowDate));
+        database.insert(SearchIndexColumns.tableName,null,contentValues);
+    }
+
+    public void delete(String sourceId){
+        SQLiteDatabase database = tvDB.getWritableDatabase();
+        if(!tableIsExist(database,SearchIndexColumns.tableName)){
+            return;
+        }
+        ContentValues contentValues = new ContentValues();
+        contentValues.put(SearchIndexColumns.sourceId,sourceId);
+        SimpleDateFormat dateFormat = new SimpleDateFormat(
+                "yyyy-MM-dd HH:mm:ss");
+        Date nowDate = new Date();
+        contentValues.put(SearchIndexColumns.insertTime,dateFormat.format(nowDate));
+        String[] deleteArgs = { sourceId };
+        database.delete(SearchIndexColumns.tableName,SearchIndexColumns.sourceId + " = ?",deleteArgs);
+    }
+
+    public void deleteAll(){
+        SQLiteDatabase database = tvDB.getWritableDatabase();
+        if(!tableIsExist(database,SearchIndexColumns.tableName)){
+            return;
+        }
+        database.delete(SearchIndexColumns.tableName,null,null);
+    }
+
+    public String getTimeBySourceId(String sourceId){
+        SQLiteDatabase sqLiteDatabase = tvDB.getReadableDatabase();
+        if(!tableIsExist(sqLiteDatabase,SearchIndexColumns.tableName)){
+            return null;
+        }
+        Cursor c;
+        String sql = "select * from " +SearchIndexColumns.tableName+ " where "+SearchIndexColumns.sourceId+ " = ?";
+        String[] args = {sourceId};
+        c = sqLiteDatabase.rawQuery(sql,args);
+
+
+
+        c.moveToFirst();
+        if(c.getCount() == 0){
+            return "";
+        }
+
+        String time = c.getString(c.getColumnIndexOrThrow(SearchIndexColumns.time));
+        c.close();
+        return time;
+    }
+
+    /* -------------------------------------------------------------------------------------------- */
+    /* table columns interface */
+    public interface SearchIndexColumns{
+        //表名
+        String tableName = "last_play_store";
+
+        //字段定义
+
+        String sourceId = "sourceId";
+
+        String time = "time";
+
+        String insertTime = "insert_time";
+    }
+}

+ 38 - 0
lib/src/main/java/com/hc/lib/store/TvDB.java

@@ -0,0 +1,38 @@
+package com.hc.lib.store;
+
+import android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+/**
+ * Created by yunhaipiaodi on 2017/9/18.
+ */
+
+public class TvDB extends SQLiteOpenHelper {
+    public static final String DATABASENAME = "houchuan_tv.db";
+    private static final int VERSION = 1;
+    private static TvDB instance = null;
+    private static Context mContext;
+
+    public TvDB(Context context) {
+        super(context, DATABASENAME, null, VERSION);
+        mContext = context;
+    }
+
+    public static final synchronized TvDB getInstance(final Context context){
+        if(instance ==null){
+            instance = new TvDB(context);
+        }
+        return instance;
+    }
+
+    @Override
+    public void onCreate(SQLiteDatabase db) {
+        LastPlayTimeStore.getInstance(mContext).onCreate(db);
+    }
+
+    @Override
+    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+
+    }
+}

+ 5 - 0
lib/src/main/java/com/hc/lib/video/IVideoPlayer.java

@@ -42,4 +42,9 @@ public interface IVideoPlayer {
     void onVideoDestroy();
 
     void restart();
+
+    /**
+     * 返回键按下
+     */
+    void keyCodeBack();
 }

+ 227 - 40
lib/src/main/java/com/hc/lib/video/MVideoPlayer.java

@@ -6,8 +6,8 @@ import android.util.Log;
 import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
-import android.webkit.WebView;
 import android.widget.FrameLayout;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 import android.widget.SeekBar;
@@ -15,6 +15,7 @@ import android.widget.TextView;
 import android.widget.Toast;
 
 import com.hc.lib.R;
+import com.hc.lib.store.LastPlayTimeStore;
 import com.jewel.mplayer.ControlView;
 import com.jewel.mplayer.CoreVideoView;
 import com.jewel.mplayer.OnVideoChangeListener;
@@ -44,10 +45,8 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
     private boolean needSeek = false;
     private SeekBar progressBar;
 
-
-
-
     private VideoHideControlViewRunnable videoHideControlViewRunnable;
+    private VideoHideLastPlayBarRunnable videoHideLastPlayBarRunnable;
     private OnPlayerPausedListener onPlayerPausedListener;
 
     //add by 许林 2018/12/5
@@ -58,7 +57,7 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
     TextView percentText;
 
     //延迟滑动计时器
-    private Timer timer ;
+    private Timer timer;
     private TimerTask timerTask;
 
     private VideoData currentVideoData;
@@ -66,6 +65,16 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
     //页面activity
     Activity mainActivity;
 
+    //本地存储
+    LastPlayTimeStore lastPlayTimeStore;
+    String mLastPlayTime = "";
+    static boolean isShowLastPlayBar = false;
+
+    //上次退出界面
+    LinearLayout lastPlayBar;
+    TextView lastTimeText;
+    ImageView resumePlayButton;
+
     private int seekPercent = 5; //快进百分比
 
     private String TAG = "MVideoPlayer";
@@ -78,7 +87,7 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
         }
     }
 
-    public MVideoPlayer(Context context) {
+    public MVideoPlayer(final Context context) {
         super(context);
 
         View root = View.inflate(getContext(), R.layout.layout_m_player, this);
@@ -97,6 +106,11 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
         seekBar = findViewById(R.id.seek_bar_tv);
         percentText = findViewById(R.id.percent_text);
 
+        //上次退出界面 add by 许林 2019/2/26
+        lastPlayBar = findViewById(R.id.last_play_bar);
+        lastTimeText = findViewById(R.id.last_time_text);
+        resumePlayButton = findViewById(R.id.resume_play_btn);
+
 
         seekBar.setMax(1000);
         seekBar.setProgress(0);
@@ -139,7 +153,27 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
         videoView.addOnVideoChangeListener(new OnVideoChangeListener() {
             @Override
             public void onVideoPrepared(CoreVideoView coreVideoView) {
+                Log.d(TAG,"lastPlayTimeInt:" + mLastPlayTime);
                 isPrepared = true;
+                if(isFullVideo && !mLastPlayTime.isEmpty()){
+                    new Timer().schedule(new TimerTask() {
+                        @Override
+                        public void run() {
+                            Activity activity = (Activity)context;
+                            activity.runOnUiThread(new Runnable() {
+                                @Override
+                                public void run() {
+                                    int lastPlayTimeInt = Integer.parseInt(mLastPlayTime);
+                                    Log.d(TAG,"lastPlayTimeInt:" + lastPlayTimeInt);
+                                    videoView.seekTo(lastPlayTimeInt);
+                                    showLastTimeBar(mLastPlayTime);
+                                    hideAllWidget();
+                                }
+                            });
+                        }
+                    },200);
+
+                }
             }
 
             @Override
@@ -216,9 +250,11 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
 
             }
         });
+
+        lastPlayTimeStore = new LastPlayTimeStore(context);
     }
 
-    public void start(VideoData videoData) {
+    public void start(final VideoData videoData) {
         currentVideoData = videoData;
         if (videoData != null) {
             onVideoDestroy();
@@ -228,8 +264,17 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
             }
             videoView.start();
             controlView.setTitle(videoData.getTitle());
+            //获取上次播放时间,add by xulin 2019/2/26
             if (isFullVideo) {
-                showControlWidget();
+                String lastPlayTime = getLastPlayTime(videoData.getId());
+                //Log.d(TAG,"lastPlayTime:" + lastPlayTime + ";  sourceId:" + videoData.getId());
+                lastPlayTimeStore.delete(videoData.getId());
+                if(!lastPlayTime.isEmpty()){
+                    mLastPlayTime = lastPlayTime;
+                }else{
+                    showControlWidget();
+                    mLastPlayTime= "";
+                }
             }
         }
         if(layoutLoading != null){
@@ -237,6 +282,16 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
         }
     }
 
+    public void resumePlay(){
+        lastPlayBar.setVisibility(INVISIBLE);
+        isShowLastPlayBar = false;
+        videoView.seekTo(0);
+    }
+
+    private String getLastPlayTime(String sourceId){
+        return lastPlayTimeStore.getTimeBySourceId(sourceId);
+    }
+
     public void start() {
         videoView.start();
     }
@@ -278,10 +333,34 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
      * by xuling 20180726
      */
     public int getDuration(){
-        if(!isPrepared){
+        try{
+            if(!isPrepared){
+                return 0;
+            }
+
+            return videoView.getDuration();
+        }catch (Exception e){
+            e.printStackTrace();
+            return 0;
+        }
+
+    }
+
+    /**
+     * 获取当前播放时间(毫秒)
+     * by xuling 20180726
+     */
+    public int getCurrentPos(){
+        try{
+            if(!isPrepared){
+                return 0;
+            }
+
+            return videoView.getCurrentPositionWhenPlaying();
+        }catch (Exception e){
+            e.printStackTrace();
             return 0;
         }
-        return videoView.getDuration();
 
     }
 
@@ -289,6 +368,18 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
      * 延迟执行视频快进任务
      * by xuling 20180726
      */
+    public void storeLastPlayTime(){
+        int currentPos = getCurrentPos();
+        int duration = getDuration();
+        if(currentPos < duration){
+            lastPlayTimeStore.insert(String.valueOf(currentPos),currentVideoData.getId());
+        }
+    }
+
+    /*
+     * 延迟执行视频快进任务
+     * by xuling 20180726
+     */
     private void initTimer(){
         if(mainActivity == null){
             Log.d(TAG,"请向播放器传递activity实例");
@@ -306,7 +397,10 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
                         long myCurrentTime = Calendar.getInstance().getTimeInMillis();
                         if(myCurrentTime - currentTime > 3){
                             int position = seekBar.getProgress();
-                            position = position* getDuration()/1000;
+                            int duration = getDuration();
+                            float fPostion = position;
+                            float fDuration = duration;
+                            position = (int)(fPostion*fDuration/1000);
                             seekTo(position);
                             seekContainer.setVisibility(GONE);
                         }
@@ -315,7 +409,7 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
             }
         };
 
-        timer.schedule(timerTask,3000);
+        timer.schedule(timerTask,2000);
     }
 
     /* 跳转
@@ -330,16 +424,18 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
         Logger.d("HCVideoPlayer onKeyDown start: %s, %s", keyCode, event.getAction());
         switch (keyCode) {
             case KeyEvent.KEYCODE_DPAD_LEFT:
-                /*if (event.getAction() == KeyEvent.ACTION_DOWN) {
+               /* if (event.getAction() == KeyEvent.ACTION_DOWN) {
                     changeProgress(true);
                 } else if (event.getAction() == KeyEvent.ACTION_UP) {
                     isChangingProgress = false;
                 }*/
-                if(isPrepared){
-                    seekBack();
-                }else{
-                    Toast.makeText(mainActivity,"视频准备中,暂时不能拖动快进",Toast.LENGTH_SHORT).show();
-                }
+               if(!isShowLastPlayBar){
+                   if(isPrepared){
+                       seekBack();
+                   }else{
+                       Toast.makeText(mainActivity,"视频准备中,暂时不能拖动快进",Toast.LENGTH_SHORT).show();
+                   }
+               }
                 return true;
             case KeyEvent.KEYCODE_DPAD_RIGHT:
 //                if(isChangingProgress) {
@@ -348,32 +444,42 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
 //                        seekToTime = 10 * 60 * 1000;
 //                    }
 //                }
-              /*  if (event.getAction() == KeyEvent.ACTION_DOWN) {
+               /* if (event.getAction() == KeyEvent.ACTION_DOWN) {
                     changeProgress(false);
                 } else if (event.getAction() == KeyEvent.ACTION_UP) {
                     isChangingProgress = false;
                 }*/
-                if(isPrepared){
-                    seekForward();
-                }else{
-                    Toast.makeText(mainActivity,"视频准备中,暂时不能拖动快进",Toast.LENGTH_SHORT).show();
+                if(!isShowLastPlayBar){
+                    if(isPrepared){
+                        seekForward();
+                    }else{
+                        Toast.makeText(mainActivity,"视频准备中,暂时不能拖动快进",Toast.LENGTH_SHORT).show();
+                    }
                 }
                 return true;
             case KeyEvent.KEYCODE_DPAD_UP:
-                showControlWidget();
+                if(!isShowLastPlayBar){
+                    showControlWidget();
+                }
 //                changeVolume(true);
                 break;
             case KeyEvent.KEYCODE_DPAD_DOWN:
-                showControlWidget();
+                if(!isShowLastPlayBar){
+                    showControlWidget();
+                }
 //                changeVolume(false);
                 break;
             case KeyEvent.KEYCODE_DPAD_CENTER:
-                if (event.getAction() == KeyEvent.ACTION_DOWN) {
-                    pauseOrPlay(false);
+                if(isShowLastPlayBar){
+                    resumePlay();
+                }else{
+                    if (event.getAction() == KeyEvent.ACTION_DOWN ) {
+                        pauseOrPlay(false);
+                    }
                 }
                 break;
             case KeyEvent.KEYCODE_ENTER:
-                if (event.getAction() == KeyEvent.ACTION_DOWN) {
+                if (event.getAction() == KeyEvent.ACTION_DOWN ) {
                     pauseOrPlay(false);
                 }
                 break;
@@ -384,28 +490,33 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
         return super.onKeyDown(keyCode, event);
     }
 
+    @Override
+    public void keyCodeBack(){
+        if(isShowLastPlayBar){
+            lastPlayBar.setVisibility(INVISIBLE);
+            isShowLastPlayBar = false;
+        }else{
+            pauseOrPlay(false);
+        }
+    }
+
     //add by 许林 ,2018/12/5
     private void seekBack(){
-        /*if(vipState == -1){
-            if(isFee != 1){
-                return;
-            }
-        }*/
-
         if(seekContainer.getVisibility() != VISIBLE){
             mainActivity.runOnUiThread(new Runnable() {
                 @Override
                 public void run() {
                     hideAllWidget();
                     seekContainer.setVisibility(VISIBLE);
-                    int position = (videoView.getCurrentPositionWhenPlaying() * 1000)/ videoView.getDuration();
+                    int currentPos = videoView.getCurrentPositionWhenPlaying();
+                    int durationSec = videoView.getDuration()/1000;
+                    int position = currentPos/ durationSec;
                     seekBar.setProgress(position);
                     currentTime =Calendar.getInstance().getTimeInMillis();
                 }
             });
         }
 
-
         int position = seekBar.getProgress() - seekPercent* 10;
         seek(position);
     }
@@ -423,14 +534,15 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
                 public void run() {
                     hideAllWidget();
                     seekContainer.setVisibility(VISIBLE);
-                    int position = (videoView.getCurrentPositionWhenPlaying() * 1000)/ videoView.getDuration();
+                    int currentPos = videoView.getCurrentPositionWhenPlaying();
+                    int durationSec = videoView.getDuration()/1000;
+                    int position = currentPos/ durationSec;
                     seekBar.setProgress(position);
                     currentTime =Calendar.getInstance().getTimeInMillis();
                 }
             });
         }
 
-
         int position = seekBar.getProgress() + seekPercent* 10;
         seek(position);
     }
@@ -463,11 +575,66 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
         Log.d(TAG,"hideAllWidget,layoutLoading gone");
     }
 
+    /*
+    * 显示上次退出播放的时间
+    * */
+    private void showLastTimeBar(String lastTime){
+        lastPlayBar.setVisibility(VISIBLE);
+        //resumePlayButton.requestFocus();
+        isShowLastPlayBar = true;
+        int lastTimeCount = Integer.parseInt(lastTime)/1000;
+        String lastTimeToShow = "上次观看到" + secToTime(lastTimeCount)+ ",已为您继续播放";
+        lastTimeText.setText(lastTimeToShow);
+
+        if (videoHideLastPlayBarRunnable == null) {
+            videoHideLastPlayBarRunnable = new VideoHideLastPlayBarRunnable(lastPlayBar);
+        }
+        getRootView().getHandler().removeCallbacks(videoHideLastPlayBarRunnable);
+        getRootView().getHandler().postDelayed(videoHideLastPlayBarRunnable, 5000);
+    }
+
+    /*
+    * 将秒转化为时秒分
+    * */
+    public static String secToTime(int time) {
+        String timeStr = null;
+        int hour = 0;
+        int minute = 0;
+        int second = 0;
+        if (time <= 0)
+            return "00:00";
+        else {
+            minute = time / 60;
+            if (minute < 60) {
+                second = time % 60;
+                timeStr = unitFormat(minute) + ":" + unitFormat(second);
+            } else {
+                hour = minute / 60;
+                if (hour > 99)
+                    return "99:59:59";
+                minute = minute % 60;
+                second = time - hour * 3600 - minute * 60;
+                timeStr = unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second);
+            }
+        }
+        return timeStr;
+    }
+
+    public static String unitFormat(int i) {
+        String retStr = null;
+        if (i >= 0 && i < 10)
+            retStr = "0" + Integer.toString(i);
+        else
+            retStr = "" + i;
+        return retStr;
+    }
+
+
+
     /**
      * 显示控制器
      */
     private void showControlWidget() {
-
         layoutTop.setVisibility(VISIBLE);
         layoutBottom.setVisibility(VISIBLE);
 
@@ -514,7 +681,9 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
     }
 
     public void hideSeekContainer(){
-        seekContainer.setVisibility(INVISIBLE);
+        if(seekContainer != null){
+            seekContainer.setVisibility(INVISIBLE);
+        }
     }
 
     @Override
@@ -561,6 +730,8 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
         start(currentVideoData);
     }
 
+
+
     /**
      * 视频控制视图消失线程
      */
@@ -579,6 +750,22 @@ public class MVideoPlayer extends FrameLayout implements IVideoPlayer {
         }
     }
 
+    private static class VideoHideLastPlayBarRunnable implements Runnable {
+
+        private View view;
+
+        VideoHideLastPlayBarRunnable(View view) {
+            this.view = view;
+        }
+
+        @Override
+        public void run() {
+            view.setVisibility(INVISIBLE);
+            isShowLastPlayBar = false;
+        }
+    }
+
+
 
     /**
      * 视频控制视图消失线程

+ 8 - 5
lib/src/main/java/com/hc/lib/video/VideoPauseDialog.java

@@ -19,6 +19,7 @@ import com.bumptech.glide.Glide;
 import com.hc.lib.R;
 import com.hc.lib.http.GetRequestListener;
 import com.hc.lib.http.GetRequest;
+import com.hc.lib.store.LastPlayTimeStore;
 import com.makeramen.roundedimageview.RoundedImageView;
 
 import org.json.JSONArray;
@@ -106,15 +107,12 @@ public class VideoPauseDialog extends Dialog implements View.OnClickListener {
         title2 = pauseDialogContentView.findViewById(R.id.title_2);
         title3 = pauseDialogContentView.findViewById(R.id.title_3);
 
-
-
         try{
             setOnFocusListener();
         }catch (Exception e){
             e.printStackTrace();
         }
 
-
         //add by xu lin 2018/12/25 end
         if(hasDialogComplete){
             btnResume.setImageResource(R.drawable.restart_play);
@@ -287,7 +285,12 @@ public class VideoPauseDialog extends Dialog implements View.OnClickListener {
             onPlayItemSelectedListener.playCollect();
         } else if (view.getId() == R.id.btn_exit_image) {
             dialogDismiss();
-            onPlayItemSelectedListener.playExit();
+            if(hasDialogComplete){
+                onPlayItemSelectedListener.playExit(true);
+            }else{
+                onPlayItemSelectedListener.playExit(false);
+            }
+
         }
     }
 
@@ -328,7 +331,7 @@ public class VideoPauseDialog extends Dialog implements View.OnClickListener {
         /**
          * 退出播放
          */
-        void playExit();
+        void playExit(boolean Complete);
 
 
         /**

+ 27 - 0
lib/src/main/res/layout/layout_m_player.xml

@@ -37,6 +37,7 @@
         android:layout_marginLeft="@dimen/player_bottom_notice_text_margin_left"
         android:layout_marginTop="@dimen/player_bottom_notice_text_margin_left"
         android:layout_marginRight="@dimen/player_bottom_notice_text_margin_left"
+        android:visibility="invisible"
         android:background="#b3000000"
         >
 
@@ -129,6 +130,7 @@
     <LinearLayout
         android:id="@+id/layout_bottom"
         android:layout_width="match_parent"
+        android:visibility="invisible"
         android:layout_height="@dimen/player_top_bar_height"
         android:paddingLeft="@dimen/video_bottom_padding"
         android:paddingRight="@dimen/video_bottom_padding"
@@ -197,6 +199,31 @@
             tools:ignore="SpUsage" />
     </LinearLayout>
 
+    <!--断点续播提示条-->
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/player_top_bar_height"
+        android:id="@+id/last_play_bar"
+        android:orientation="horizontal"
+        android:gravity="center"
+        android:background="#b3000000"
+        android:visibility="invisible"
+        android:layout_alignParentBottom="true">
+        <TextView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/last_time_text"
+            android:textSize="@dimen/last_play_time_bar_text_size"
+            android:textColor="@color/white"
+            android:text="上次观看到9分25秒,已为您继续播放"/>
+        <ImageView
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:id="@+id/resume_play_btn"
+            android:src="@drawable/anniu_2"
+            android:layout_marginLeft="@dimen/last_play_time_bar_image_margin_left"/>
+    </LinearLayout>
+
     <com.jewel.mplayer.ControlView
         android:id="@+id/controlView"
         android:layout_width="match_parent"

+ 5 - 0
lib/src/main/res/values-hdpi/dimens.xml

@@ -732,4 +732,9 @@
     <dimen name="exit_margin_left">765.3333dp</dimen>
     <dimen name="exit_margin_top">498.66666dp</dimen>
     <dimen name="play_title_width">560.0dp</dimen>
+
+    <!--last play time bar-->
+    <dimen name="last_play_time_bar_height">72.0dp</dimen>
+    <dimen name="last_play_time_bar_text_size">26.0dp</dimen>
+    <dimen name="last_play_time_bar_image_margin_left">10.666667dp</dimen>
 </resources>

+ 5 - 0
lib/src/main/res/values-ldpi/dimens.xml

@@ -732,4 +732,9 @@
     <dimen name="exit_margin_left">1530.6666dp</dimen>
     <dimen name="exit_margin_top">997.3333dp</dimen>
     <dimen name="play_title_width">1120.0dp</dimen>
+
+    <!--last play time bar-->
+    <dimen name="last_play_time_bar_height">144.0dp</dimen>
+    <dimen name="last_play_time_bar_text_size">52.0dp</dimen>
+    <dimen name="last_play_time_bar_image_margin_left">21.333334dp</dimen>
 </resources>

+ 5 - 0
lib/src/main/res/values-mdpi-1280x720/dimens.xml

@@ -732,4 +732,9 @@
     <dimen name="exit_margin_left">765.3333dp</dimen>
     <dimen name="exit_margin_top">498.66666dp</dimen>
     <dimen name="play_title_width">560.0dp</dimen>
+
+    <!--last play time bar-->
+    <dimen name="last_play_time_bar_height">72.0dp</dimen>
+    <dimen name="last_play_time_bar_text_size">26.0dp</dimen>
+    <dimen name="last_play_time_bar_image_margin_left">10.666667dp</dimen>
 </resources>

+ 5 - 0
lib/src/main/res/values-mdpi-1920x1080/dimens.xml

@@ -732,4 +732,9 @@
     <dimen name="exit_margin_left">1148.0dp</dimen>
     <dimen name="exit_margin_top">748.0dp</dimen>
     <dimen name="play_title_width">840.0dp</dimen>
+
+    <!--last play time bar-->
+    <dimen name="last_play_time_bar_height">108.0dp</dimen>
+    <dimen name="last_play_time_bar_text_size">39.0dp</dimen>
+    <dimen name="last_play_time_bar_image_margin_left">16.0dp</dimen>
 </resources>

+ 5 - 0
lib/src/main/res/values-xhdpi/dimens.xml

@@ -732,4 +732,9 @@
     <dimen name="exit_margin_left">574dp</dimen>
     <dimen name="exit_margin_top">374dp</dimen>
     <dimen name="play_title_width">420dp</dimen>
+
+    <!--last play time bar-->
+    <dimen name="last_play_time_bar_height">54dp</dimen>
+    <dimen name="last_play_time_bar_text_size">19.5dp</dimen>
+    <dimen name="last_play_time_bar_image_margin_left">8dp</dimen>
 </resources>

+ 5 - 0
lib/src/main/res/values-xxhdpi/dimens.xml

@@ -732,4 +732,9 @@
     <dimen name="exit_margin_left">382.66666dp</dimen>
     <dimen name="exit_margin_top">249.33333dp</dimen>
     <dimen name="play_title_width">280.0dp</dimen>
+
+    <!--last play time bar-->
+    <dimen name="last_play_time_bar_height">36.0dp</dimen>
+    <dimen name="last_play_time_bar_text_size">13.0dp</dimen>
+    <dimen name="last_play_time_bar_image_margin_left">5.3333335dp</dimen>
 </resources>

+ 5 - 0
lib/src/main/res/values-xxxhdpi/dimens.xml

@@ -732,4 +732,9 @@
     <dimen name="exit_margin_left">287.0dp</dimen>
     <dimen name="exit_margin_top">187.0dp</dimen>
     <dimen name="play_title_width">210.0dp</dimen>
+
+    <!--last play time bar-->
+    <dimen name="last_play_time_bar_height">27.0dp</dimen>
+    <dimen name="last_play_time_bar_text_size">9.75dp</dimen>
+    <dimen name="last_play_time_bar_image_margin_left">4.0dp</dimen>
 </resources>