11 커밋 d8175b6462 ... db29be57ea

작성자 SHA1 메시지 날짜
  LAPTOP-K69FCNBP\crius db29be57ea Merge branch 'master' of http://116.62.119.248:10082/cheng_zq/EffectDemo into lwz_ 2 년 전
  LAPTOP-K69FCNBP\crius b591f876c1 Merge branch 'master' of http://116.62.119.248:10082/cheng_zq/EffectDemo into lwz_ 2 년 전
  czq 8556e741d8 修改接口,上传文件 2 년 전
  LAPTOP-K69FCNBP\crius f9ea5b7804 Merge branch 'master' of http://116.62.119.248:10082/cheng_zq/EffectDemo into lwz_ 2 년 전
  czq 06c9b37f52 上传签名文件 2 년 전
  czq f612994a15 添加网络请求 2 년 전
  LAPTOP-K69FCNBP\crius 6feaea07ec 点图发声 2 년 전
  czq 7ae5af07aa Merge branch 'master' into czq 2 년 전
  czq 1eb0a65ecf 修改包名 2 년 전
  czq 64abf7f3ad 乐播投屏接入修改 2 년 전
  czq 1d100118dc 乐播投屏接入 2 년 전
76개의 변경된 파일3309개의 추가작업 그리고 139개의 파일을 삭제
  1. 2 15
      .idea/misc.xml
  2. BIN
      app/bestvedu.jks
  3. 25 8
      app/build.gradle
  4. 6 1
      app/proguard-rules.pro
  5. 9 6
      app/src/main/AndroidManifest.xml
  6. 27 7
      app/src/main/java/com/xunao/effectdemo/App.java
  7. 92 0
      app/src/main/java/com/xunao/effectdemo/activity/AudioActivity.java
  8. 0 1
      app/src/main/java/com/xunao/effectdemo/activity/CongratulationsActivity.kt
  9. 0 1
      app/src/main/java/com/xunao/effectdemo/activity/DragSelectActivity.java
  10. 5 5
      app/src/main/java/com/xunao/effectdemo/activity/GSXYVideoPlayerActivity.java
  11. 0 1
      app/src/main/java/com/xunao/effectdemo/activity/LottieActivity.kt
  12. 35 3
      app/src/main/java/com/xunao/effectdemo/activity/MapChallengeActivity.java
  13. 0 3
      app/src/main/java/com/xunao/effectdemo/activity/ProgressDemoActivity.kt
  14. 0 1
      app/src/main/java/com/xunao/effectdemo/activity/QuxianActivity.java
  15. 1 1
      app/src/main/java/com/xunao/effectdemo/activity/SongLyricActivity.kt
  16. 0 1
      app/src/main/java/com/xunao/effectdemo/activity/SoundActivity.java
  17. 0 8
      app/src/main/java/com/xunao/effectdemo/activity/StarsActivity.java
  18. 0 1
      app/src/main/java/com/xunao/effectdemo/activity/Test2Activity.java
  19. 0 8
      app/src/main/java/com/xunao/effectdemo/activity/TestActivity.java
  20. 14 0
      app/src/main/java/com/xunao/effectdemo/activity/VideoDemandActivity.java
  21. 187 0
      app/src/main/java/com/xunao/effectdemo/adapter/AudioAdapter.java
  22. 27 0
      app/src/main/java/com/xunao/effectdemo/adapter/AudioDemandAdapter.java
  23. 80 0
      app/src/main/java/com/xunao/effectdemo/adapter/DeviceAdapter.java
  24. 0 1
      app/src/main/java/com/xunao/effectdemo/adapter/VideoDemandAdapter.java
  25. 0 1
      app/src/main/java/com/xunao/effectdemo/anim/Anim.java
  26. 0 3
      app/src/main/java/com/xunao/effectdemo/anim/AnimBaiYeChuang.java
  27. 0 1
      app/src/main/java/com/xunao/effectdemo/anim/AnimCaChu.java
  28. 0 2
      app/src/main/java/com/xunao/effectdemo/anim/AnimHeZhuang.java
  29. 0 3
      app/src/main/java/com/xunao/effectdemo/anim/AnimJieTi.java
  30. 0 1
      app/src/main/java/com/xunao/effectdemo/anim/AnimLingXing.java
  31. 0 2
      app/src/main/java/com/xunao/effectdemo/anim/AnimLunZi.java
  32. 0 1
      app/src/main/java/com/xunao/effectdemo/anim/AnimPiLie.java
  33. 0 2
      app/src/main/java/com/xunao/effectdemo/anim/AnimQiPan.java
  34. 0 2
      app/src/main/java/com/xunao/effectdemo/anim/AnimQieRu.java
  35. 0 1
      app/src/main/java/com/xunao/effectdemo/anim/AnimShanXingZhanKai.java
  36. 0 1
      app/src/main/java/com/xunao/effectdemo/anim/AnimShiZiXingKuoZhan.java
  37. 0 3
      app/src/main/java/com/xunao/effectdemo/anim/AnimSuiJiXianTiao.java
  38. 0 2
      app/src/main/java/com/xunao/effectdemo/anim/AnimXiangNeiRongJie.java
  39. 0 1
      app/src/main/java/com/xunao/effectdemo/anim/AnimYuanXingKuoZhan.java
  40. 226 0
      app/src/main/java/com/xunao/effectdemo/dlan/CastManager.java
  41. 197 0
      app/src/main/java/com/xunao/effectdemo/dlan/DLNAControlCenter.java
  42. 172 0
      app/src/main/java/com/xunao/effectdemo/dlan/DeviceManager.java
  43. 19 0
      app/src/main/java/com/xunao/effectdemo/dlan/IUIUpdateListener.java
  44. 0 2
      app/src/main/java/com/xunao/effectdemo/dragview/DragViewUtil.java
  45. 81 0
      app/src/main/java/com/xunao/effectdemo/fragment/AudioDemandFragment.java
  46. 14 5
      app/src/main/java/com/xunao/effectdemo/fragment/VideoDemandFragment.java
  47. 287 0
      app/src/main/java/com/xunao/effectdemo/net/ApiHttpClient.java
  48. 14 0
      app/src/main/java/com/xunao/effectdemo/net/ApiUrl.java
  49. 51 0
      app/src/main/java/com/xunao/effectdemo/net/BaseBean.java
  50. 68 0
      app/src/main/java/com/xunao/effectdemo/net/CSMHttpCallback.java
  51. 32 0
      app/src/main/java/com/xunao/effectdemo/net/MapBodyBean.java
  52. 0 9
      app/src/main/java/com/xunao/effectdemo/umeng/UmInitConfig.java
  53. 30 0
      app/src/main/java/com/xunao/effectdemo/utils/EncryptUtil.java
  54. 0 4
      app/src/main/java/com/xunao/effectdemo/utils/FocusUtils.java
  55. 0 2
      app/src/main/java/com/xunao/effectdemo/utils/MediaRecorderDemo.java
  56. 777 0
      app/src/main/java/com/xunao/effectdemo/utils/StringUtil.java
  57. 35 0
      app/src/main/java/com/xunao/effectdemo/utils/TimeZoneUtil.java
  58. 0 1
      app/src/main/java/com/xunao/effectdemo/view/Calculator.java
  59. 0 2
      app/src/main/java/com/xunao/effectdemo/view/FireworkView.java
  60. 0 1
      app/src/main/java/com/xunao/effectdemo/view/GuideImageView.java
  61. 0 1
      app/src/main/java/com/xunao/effectdemo/view/MaskFilterView.java
  62. 0 2
      app/src/main/java/com/xunao/effectdemo/view/MyGuideCaseQueue.java
  63. 0 3
      app/src/main/java/com/xunao/effectdemo/view/MyGuideCaseView.java
  64. 0 2
      app/src/main/java/com/xunao/effectdemo/view/MyLikeView.java
  65. 434 2
      app/src/main/java/com/xunao/effectdemo/view/VideoPreviewPlay.java
  66. 0 1
      app/src/main/java/com/xunao/effectdemo/view/circleprogress/DialProgress.java
  67. 37 0
      app/src/main/res/layout/activity_audio.xml
  68. 1 0
      app/src/main/res/layout/activity_gsxy_video.xml
  69. 269 0
      app/src/main/res/layout/activity_my_video.xml
  70. 8 0
      app/src/main/res/layout/activity_video_demand.xml
  71. 5 0
      app/src/main/res/layout/fragment_audio_demand.xml
  72. 1 2
      app/src/main/res/layout/fragment_first.xml
  73. 1 2
      app/src/main/res/layout/fragment_second.xml
  74. 1 0
      app/src/main/res/layout/fragment_video_demand.xml
  75. 25 0
      app/src/main/res/layout/item_audio_demand.xml
  76. 14 0
      app/src/main/res/layout/item_device.xml

+ 2 - 15
.idea/misc.xml

@@ -8,6 +8,8 @@
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_count_down.xml" value="0.25" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_drag_select.xml" value="0.12708333333333333" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_enty_anim.xml" value="0.11979166666666667" />
+        <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_gsxy_video.xml" value="0.1" />
+        <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_ijkplay.xml" value="0.1390625" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_lottie.xml" value="0.1" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_main.xml" value="0.1375" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_progress.xml" value="0.22" />
@@ -23,21 +25,6 @@
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_view.xml" value="0.25" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/activity_web.xml" value="0.1816123188405797" />
         <entry key="..\:/Progect/gitee/EffectDemo/app/src/main/res/layout/demo_activity.xml" value="0.18020833333333333" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/drawable/check_box_bg.xml" value="0.1" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/drawable/left_round_bg.xml" value="0.1355" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/drawable/right_round_bg.xml" value="0.139" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/activity_gsxy_video.xml" value="0.24179260031266284" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/activity_main.xml" value="0.20852641334569044" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/activity_map_challenge.xml" value="0.21241050119331742" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/activity_quxian.xml" value="0.8631178707224335" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/activity_test2.xml" value="0.2600652883569097" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/activity_video_demand.xml" value="0.1" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/activity_word_cut.xml" value="0.42962962962962964" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/demo_activity.xml" value="0.35025641025641024" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/item_video_demand.xml" value="0.3850877192982456" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/item_word_cut.xml" value="0.2577777777777778" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/view_linear.xml" value="0.17407407407407408" />
-        <entry key="..\:/work/mozhi/qiqu/EffectDemo/app/src/main/res/layout/view_video_demand.xml" value="0.22864583333333333" />
       </map>
     </option>
   </component>

BIN
app/bestvedu.jks


+ 25 - 8
app/build.gradle

@@ -13,7 +13,7 @@ android {
     buildToolsVersion "30.0.3"
 
     defaultConfig {
-        applicationId "com.xunao.effectdemo"
+        applicationId "com.bestv.app"
         minSdkVersion 21
         targetSdkVersion 30
         versionCode 1
@@ -49,15 +49,24 @@ android {
         }
 
         debug {
-            storeFile file("effect.jks")
-            storePassword "xunao123"
-            keyAlias "xuantu"
-            keyPassword "xunao123"
-            v1SigningEnabled true
-            v2SigningEnabled true
+//            storeFile file("effect.jks")
+//            storePassword "xunao123"
+//            keyAlias "xuantu"
+//            keyPassword "xunao123"
+            storeFile file("bestvedu.jks")
+            storePassword "bestv001!"
+            keyAlias "bestvedu"
+            keyPassword "bestv001!"
+//            v1SigningEnabled true
+//            v2SigningEnabled true
         }
     }
     buildTypes {
+        debug {
+            minifyEnabled false
+            signingConfig signingConfigs.debug
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
         release {
             minifyEnabled false
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
@@ -155,5 +164,13 @@ dependencies {
 
     //完整版引入
     implementation 'com.shuyu:GSYVideoPlayer:8.1.2'
-
+    implementation 'com.blankj:utilcodex:1.31.0'
+    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.3'
+
+    //网络请求
+    //RxJava
+    implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
+    implementation 'io.reactivex.rxjava2:rxjava:2.2.8'
+    implementation 'com.zhy:okhttputils:2.6.2'
+    implementation 'com.squareup.okhttp3:okhttp:4.2.2'
 }

+ 6 - 1
app/proguard-rules.pro

@@ -18,4 +18,9 @@
 
 # If you keep the line number information, uncomment this to
 # hide the original source file name.
-#-renamesourcefileattribute SourceFile
+#-renamesourcefileattribute SourceFile
+
+###Lebo
+-keep class com.hpplay.**{*;}
+-keep class com.hpplay.**$*{*;}
+-dontwarn com.hpplay.**

+ 9 - 6
app/src/main/AndroidManifest.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:tools="http://schemas.android.com/tools"
-    package="com.xunao.effectdemo">
+    package="com.xunao.effectdemo" >
 
     <uses-sdk tools:overrideLibrary="com.qmuiteam.qmui" />
 
@@ -31,8 +31,8 @@
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
         android:theme="@style/AppTheme"
-        android:usesCleartextTraffic="true">
-        <activity android:name=".activity.MainActivity">
+        android:usesCleartextTraffic="true" >
+        <activity android:name=".activity.MainActivity" >
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
 
@@ -77,7 +77,7 @@
             android:name=".receiver.MyService"
             android:enabled="true"
             android:exported="false"
-            android:process=":pushcore">
+            android:process=":pushcore" >
             <intent-filter>
                 <action android:name="cn.jiguang.user.service.action" />
             </intent-filter>
@@ -86,7 +86,7 @@
         <receiver
             android:name=".receiver.PushMessageReceiver"
             android:enabled="true"
-            android:exported="false">
+            android:exported="false" >
             <intent-filter>
                 <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
 
@@ -98,7 +98,7 @@
             android:name="cn.jiguang.union.ads.service.JAdFileProvider"
             android:authorities="${applicationId}.JAdFileProvider"
             android:exported="false"
-            android:grantUriPermissions="true">
+            android:grantUriPermissions="true" >
             <meta-data
                 android:name="android.support.FILE_PROVIDER_PATHS"
                 android:resource="@xml/jpush_file_paths" />
@@ -135,6 +135,9 @@
         <activity
             android:name=".activity.VideoDemandActivity"
             android:screenOrientation="landscape" />
+        <activity
+            android:name=".activity.AudioActivity"
+            android:screenOrientation="landscape" />
     </application>
 
 </manifest>

+ 27 - 7
app/src/main/java/com/xunao/effectdemo/App.java

@@ -7,7 +7,12 @@ import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.util.Log;
 
+import com.xunao.effectdemo.dlan.CastManager;
+import com.blankj.utilcode.util.DeviceUtils;
+import com.hpplay.sdk.source.api.IBindSdkListener;
+import com.hpplay.sdk.source.api.ILelinkPlayerListener;
 import com.hpplay.sdk.source.api.LelinkSourceSDK;
+import com.hpplay.sdk.source.browse.api.IAPI;
 import com.uc.crashsdk.export.CrashApi;
 import com.umeng.analytics.MobclickAgent;
 import com.umeng.commonsdk.UMConfigure;
@@ -15,6 +20,8 @@ import com.xunao.effectdemo.umeng.UmInitConfig;
 
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Locale;
 
 import cn.jpush.android.api.JPushInterface;
@@ -29,7 +36,7 @@ import cn.jpush.android.api.JPushInterface;
 public class App extends Application {
 
 	public static App app;
-
+	private IBindSdkListener mBindSdkListener;
 	public static App getInstance() {
 		return app;
 	}
@@ -41,16 +48,29 @@ public class App extends Application {
 		JPushInterface.setDebugMode(true);
 		JPushInterface.init(this);
 //		getSHA1Signature(this);
-
+		initLebo();
 	}
-
+	private final List<ILelinkPlayerListener> mListenerList = new ArrayList<>();
 	void initLebo(){
-//		LelinkSourceSDK.getInstance()
-//				//FIXME WARN: 这里替换为您申请的AppID & AppSecret,build.gradle替换为您的应用包名
-//				.setSdkInitInfo(this, getString(R.string.app_id), getString(R.string.app_secret))
-//				.easyPush(mBrowseContainer);
+
+		mBindSdkListener = new IBindSdkListener() {
+			@Override
+			public void onBindCallback(boolean success) {
+				Log.e("LeBo","初始化:"+success);
+				LelinkSourceSDK.getInstance().setPermissionMode( IAPI.PERMISSION_MODE_CLOUD_LICENSE, DeviceUtils.getUniqueDeviceId());
+			}
+		};
+//		DLNAControlCenter.getInstance();
+		LelinkSourceSDK.getInstance()
+				.setBindSdkListener(mBindSdkListener)
+				.setPlayListener(CastManager.getInstance().getLelinkPlayerListener())
+				.setSdkInitInfo(this, "17894", "69ce8955094258d339c1b6eadef2ec09")
+//				.setSdkInitInfo(this,"20268", "30ff4917114c5241eddbef00e5be7f6b")
+				.bindSdk();
 	}
 
+
+
 	/**
 	 * 初始化友盟SDK
 	 */

+ 92 - 0
app/src/main/java/com/xunao/effectdemo/activity/AudioActivity.java

@@ -0,0 +1,92 @@
+package com.xunao.effectdemo.activity;
+
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentActivity;
+import androidx.viewpager.widget.ViewPager;
+
+import android.os.Bundle;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.xunao.effectdemo.R;
+import com.xunao.effectdemo.adapter.AudioDemandAdapter;
+import com.xunao.effectdemo.adapter.VideoDemandAdapter;
+import com.xunao.effectdemo.fragment.AudioDemandFragment;
+import com.xunao.effectdemo.fragment.VideoDemandFragment;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class AudioActivity extends FragmentActivity {
+
+    private ViewPager viewPager;
+
+    private String[][] datas = {{"a", "b", "c"}, {"d", "e", "f"}};
+
+    private List<Fragment> list;
+    private AudioDemandAdapter adapter;
+
+    private int selectedNum = 0;
+    private TextView tvNumAudio;
+    private int length;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_audio);
+        length = 0;
+        for(String[] data : datas){
+            length = data.length + length;
+        }
+        initView();
+    }
+
+    private void initView(){
+        tvNumAudio = findViewById(R.id.tv_num_audio);
+        tvNumAudio.setText("探索 0/" + length);
+        viewPager = findViewById(R.id.view_pager_audio);
+        //把Fragment添加到List集合里面
+        list = new ArrayList<>();
+        for(String[] data : datas){
+            AudioDemandFragment audioDemandFragment = new AudioDemandFragment();
+            Bundle bundle = new Bundle();
+            bundle.putStringArray("data",data);
+            audioDemandFragment.setArguments(bundle);
+            list.add(audioDemandFragment);
+        }
+        adapter = new AudioDemandAdapter(getSupportFragmentManager(), list);
+//        viewPager.setAdapter(new VideoDemandAdapter(this, datas));
+        viewPager.setAdapter(adapter);
+        viewPager.setOffscreenPageLimit(datas.length);
+        viewPager.setCurrentItem(0);
+
+        // 上一个
+        ImageView ivAudioPrevious = findViewById(R.id.iv_audio_previous);
+        ivAudioPrevious.setOnClickListener(v -> {
+            int current = viewPager.getCurrentItem();
+            if(current > 0){
+                viewPager.setCurrentItem(current - 1);
+            }
+        });
+
+        // 下一个
+        ImageView ivAudioNext = findViewById(R.id.iv_audio_next);
+        ivAudioNext.setOnClickListener(v -> {
+            int current = viewPager.getCurrentItem();
+            if(current < datas.length - 1){
+                viewPager.setCurrentItem(current + 1);
+            }
+        });
+    }
+
+    public void addSelectedNum() {
+
+        selectedNum = selectedNum + 1;
+        if(selectedNum == length){
+            tvNumAudio.setText("完成");
+        }else{
+            tvNumAudio.setText("探索 "+selectedNum+"/" + length);
+        }
+    }
+}

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/activity/CongratulationsActivity.kt

@@ -4,7 +4,6 @@ import android.app.Activity
 import android.os.Bundle
 import com.xunao.effectdemo.R
 import kotlinx.android.synthetic.main.activity_congratulations.*
-import kotlinx.android.synthetic.main.activity_lottie.*
 
 /**
  * author : 程中强

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/activity/DragSelectActivity.java

@@ -16,7 +16,6 @@ import android.view.animation.DecelerateInterpolator;
 import android.view.animation.RotateAnimation;
 import android.view.animation.ScaleAnimation;
 import android.view.animation.TranslateAnimation;
-import android.widget.ImageView;
 import android.widget.SeekBar;
 
 import androidx.annotation.NonNull;

+ 5 - 5
app/src/main/java/com/xunao/effectdemo/activity/GSXYVideoPlayerActivity.java

@@ -1,17 +1,14 @@
 package com.xunao.effectdemo.activity;
 
 import android.app.Activity;
-import android.content.pm.ActivityInfo;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.Button;
-import android.widget.ImageView;
 
 import androidx.annotation.Nullable;
 
 import com.shuyu.gsyvideoplayer.GSYVideoManager;
 import com.shuyu.gsyvideoplayer.utils.OrientationUtils;
-import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer;
 import com.xunao.effectdemo.R;
 import com.xunao.effectdemo.view.VideoPreviewPlay;
 
@@ -28,6 +25,7 @@ public class GSXYVideoPlayerActivity extends Activity {
 	private OrientationUtils orientationUtils;
 	private Button btn;
 	private boolean isFirst = false;
+
 	private String url = "http://v3.cztv.com/cztv/vod/2018/06/28/7c45987529ea410dad7c088ba3b53dac/h264_1500k_mp4.mp4";
 	@Override
 	protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -36,6 +34,8 @@ public class GSXYVideoPlayerActivity extends Activity {
 		init();
 	}
 
+
+
 	void init(){
 		videoPlayer = findViewById(R.id.video_play);
 		videoPlayer.setUp(url, true, "null");
@@ -57,10 +57,10 @@ public class GSXYVideoPlayerActivity extends Activity {
 
 		btn = findViewById(R.id.btn_finish);
 		btn.setOnClickListener(v->{
+			videoPlayer.onVideoPause();
 			isFirst = !isFirst;
 			videoPlayer.setIsFinish(isFirst);
-//			videoPlayer.setIsTouchWiget(isFirst);
-//			videoPlayer.setIsTouchWigetFull(isFirst);
+			videoPlayer.stopDlan();
 		});
 	}
 

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/activity/LottieActivity.kt

@@ -4,7 +4,6 @@ import android.app.Activity
 import android.os.Bundle
 import com.xunao.effectdemo.R
 import kotlinx.android.synthetic.main.activity_lottie.*
-import kotlinx.android.synthetic.main.activity_lottie.view.*
 
 /**
  * author : 程中强

+ 35 - 3
app/src/main/java/com/xunao/effectdemo/activity/MapChallengeActivity.java

@@ -5,10 +5,17 @@ import androidx.appcompat.app.AppCompatActivity;
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
+import android.util.Log;
 import android.view.View;
 import android.widget.Button;
 
 import com.xunao.effectdemo.R;
+import com.xunao.effectdemo.net.ApiHttpClient;
+import com.xunao.effectdemo.net.ApiUrl;
+import com.xunao.effectdemo.net.CSMHttpCallback;
+
+import java.util.HashMap;
+import java.util.Map;
 
 /**
  * 地图闯关
@@ -18,6 +25,9 @@ public class MapChallengeActivity extends Activity {
 
     Intent intent;
 
+    private String name = "13004166772";
+    private String pwd = "123890";
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -28,17 +38,39 @@ public class MapChallengeActivity extends Activity {
     void initView(){
         btnMap1 = findViewById(R.id.btn_map_1);
         btnMap2 = findViewById(R.id.btn_map_2);
-        btnMap3 = findViewById(R.id.btn_map_3);
-        btnMap3.setOnClickListener(new View.OnClickListener() {
+        btnMap2.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                intent = new Intent(MapChallengeActivity.this, VideoDemandActivity.class);
+                intent = new Intent(MapChallengeActivity.this, AudioActivity.class);
                 startActivity(intent);
             }
         });
+        btnMap3 = findViewById(R.id.btn_map_3);
+        btnMap3.setOnClickListener(v -> {
+            intent = new Intent(MapChallengeActivity.this, VideoDemandActivity.class);
+            startActivity(intent);
+        });
         btnMap4 = findViewById(R.id.btn_map_4);
         btnMap5 = findViewById(R.id.btn_map_5);
         btnMap6 = findViewById(R.id.btn_map_6);
+
+    }
+
+    void login(){
+        Map<String, String> params = new HashMap<>();
+        params.put("ptcmobile",name);
+        params.put("ptcpswd",pwd);
+        ApiHttpClient.get(ApiUrl.login,params, new CSMHttpCallback() {
+            @Override
+            protected void onSuccess(String jsonStr) {
+
+            }
+
+            @Override
+            protected void onFail(String msg) {
+
+            }
+        });
     }
 
 }

+ 0 - 3
app/src/main/java/com/xunao/effectdemo/activity/ProgressDemoActivity.kt

@@ -3,9 +3,6 @@ package com.xunao.effectdemo.activity
 import android.app.Activity
 import android.os.Bundle
 import android.util.Log
-import android.widget.SeekBar
-import com.xuexiang.xui.widget.picker.XSeekBar
-import com.xuexiang.xui.widget.progress.HorizontalProgressView
 import com.xunao.effectdemo.R
 import kotlinx.android.synthetic.main.activity_progress.*
 

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/activity/QuxianActivity.java

@@ -14,7 +14,6 @@ import android.view.animation.LinearInterpolator;
 import android.view.animation.RotateAnimation;
 import android.view.animation.TranslateAnimation;
 import android.widget.Button;
-import android.widget.ImageView;
 import android.widget.RelativeLayout;
 
 import androidx.annotation.Nullable;

+ 1 - 1
app/src/main/java/com/xunao/effectdemo/activity/SongLyricActivity.kt

@@ -45,7 +45,7 @@ class SongLyricActivity : AppCompatActivity() {
 //            )
             lyricList.forEach {
                 val startIndexTemp = startIndex
-                val duration = (1500 + Math.random() * 500).toLong()
+                val duration = (1500 + it.length*Math.random() * 500).toLong()
                 text.postDelayed(
                     {
                         text.startPlayLine(

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/activity/SoundActivity.java

@@ -9,7 +9,6 @@ import android.os.Handler;
 import android.os.Message;
 import android.util.Log;
 import android.view.MotionEvent;
-import android.view.View;
 import android.view.animation.Animation;
 import android.view.animation.ScaleAnimation;
 import android.widget.RelativeLayout;

+ 0 - 8
app/src/main/java/com/xunao/effectdemo/activity/StarsActivity.java

@@ -2,10 +2,7 @@ package com.xunao.effectdemo.activity;
 
 import android.app.Activity;
 import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
 import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
 import android.view.animation.ScaleAnimation;
 import android.view.animation.TranslateAnimation;
 import android.widget.ImageView;
@@ -15,12 +12,7 @@ import android.widget.TextView;
 import androidx.annotation.Nullable;
 
 import com.airbnb.lottie.LottieAnimationView;
-import com.umeng.analytics.MobclickAgent;
-import com.xunao.effectdemo.App;
 import com.xunao.effectdemo.R;
-import com.xunao.effectdemo.bean.World;
-
-import cn.jpush.android.api.JPushInterface;
 
 /**
  * author : 程中强

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/activity/Test2Activity.java

@@ -9,7 +9,6 @@ import android.animation.ValueAnimator;
 import android.app.Activity;
 
 
-import android.content.ClipData;
 import android.graphics.PointF;
 import android.os.Bundle;
 import android.os.Handler;

+ 0 - 8
app/src/main/java/com/xunao/effectdemo/activity/TestActivity.java

@@ -4,16 +4,11 @@ import android.animation.Animator;
 import android.animation.TypeEvaluator;
 import android.animation.ValueAnimator;
 import android.app.Activity;
-import android.content.ClipData;
-import android.content.Intent;
 import android.graphics.PointF;
 import android.os.Handler;
 import android.os.Message;
-import android.os.SystemClock;
 import android.os.Bundle;
 import android.util.Log;
-import android.view.DragEvent;
-import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
@@ -21,8 +16,6 @@ import android.view.animation.Animation;
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.TranslateAnimation;
 import android.widget.Button;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.RelativeLayout;
 
@@ -30,7 +23,6 @@ import androidx.annotation.NonNull;
 
 import com.xunao.effectdemo.R;
 import com.xunao.effectdemo.bean.ListBean;
-import com.xunao.effectdemo.dragview.DragViewUtil;
 import com.xunao.effectdemo.view.MaskFilterView;
 
 import java.util.ArrayList;

+ 14 - 0
app/src/main/java/com/xunao/effectdemo/activity/VideoDemandActivity.java

@@ -6,6 +6,7 @@ import androidx.viewpager.widget.ViewPager;
 
 import android.os.Bundle;
 import android.widget.ImageView;
+import android.widget.TextView;
 
 import com.xunao.effectdemo.R;
 import com.xunao.effectdemo.adapter.VideoDemandAdapter;
@@ -25,6 +26,9 @@ public class VideoDemandActivity extends FragmentActivity {
     private List<Fragment> list;
     private VideoDemandAdapter adapter;
 
+    private int selectedNum = 0;
+    private TextView tvNum;
+
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -34,6 +38,8 @@ public class VideoDemandActivity extends FragmentActivity {
     }
 
     private void initView(){
+        tvNum = findViewById(R.id.tv_num);
+        tvNum.setText("探索 0/"+datas.length);
         viewPager = findViewById(R.id.view_pager);
         //把Fragment添加到List集合里面
         list = new ArrayList<>();
@@ -69,4 +75,12 @@ public class VideoDemandActivity extends FragmentActivity {
         });
     }
 
+    public void addSelectedNum() {
+        selectedNum = selectedNum + 1;
+        if(selectedNum == datas.length){
+            tvNum.setText("完成");
+        }else{
+            tvNum.setText("探索 "+selectedNum+"/"+datas.length);
+        }
+    }
 }

+ 187 - 0
app/src/main/java/com/xunao/effectdemo/adapter/AudioAdapter.java

@@ -0,0 +1,187 @@
+package com.xunao.effectdemo.adapter;
+
+import static android.view.View.GONE;
+
+import static com.mobile.auth.gatewayauth.utils.ReflectionUtils.getActivity;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.content.Context;
+import android.media.MediaPlayer;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+
+import com.xunao.effectdemo.R;
+import com.xunao.effectdemo.activity.AudioActivity;
+import com.xunao.effectdemo.activity.VideoDemandActivity;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class AudioAdapter extends RecyclerView.Adapter<AudioAdapter.ViewHolder> {
+    private final String TAG = "AudioAdapter";
+
+    private AnimatorSet mRightOutSet; // 右出动画
+    private AnimatorSet mLeftInSet; // 左入动画
+    private List<String> wordList;
+    private final Context context;
+    private String url = "http://www.mobvcasting.com/android/audio/goodmorningandroid.mp3";
+
+    private MediaPlayer mediaPlayer;
+    private List<Integer> selectList = new ArrayList<>();
+
+    public AudioAdapter(String[] wordList, Context context) {
+        this.wordList = Arrays.asList(wordList);
+        this.context = context;
+    }
+
+    @NonNull
+    @Override
+    public AudioAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
+        View view = LayoutInflater.from(viewGroup.getContext())
+                .inflate(R.layout.item_audio_demand,viewGroup,false);
+        ViewHolder holder = new ViewHolder(view);
+        return holder;
+    }
+
+    @Override
+    public void onBindViewHolder(@NonNull AudioAdapter.ViewHolder viewHolder, int i) {
+
+        if(selectList.contains(i)){
+//            viewHolder.tvBack.setVisibility(GONE);
+            Log.i(TAG, "点击后" + selectList.toString());
+        }
+
+        setAnimators(viewHolder, i);
+        setCameraDistance(viewHolder);
+
+        mediaPlayer = new MediaPlayer();
+        mediaPlayer.setOnPreparedListener(mp -> Log.i(TAG,"onPrepared:准备完成"));
+        mediaPlayer.setOnCompletionListener(mp -> Log.i(TAG,"OnCompletion:播放完成"));
+        try {
+            mediaPlayer.setDataSource(url);
+            mediaPlayer.prepareAsync();// 开始在后台缓冲音频文件并返回
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+
+        viewHolder.tvBack.setOnClickListener(v -> {
+            Log.i(TAG, "点击前1" + selectList.toString() + "---" + i);
+            if(!selectList.contains(i)){
+                selectList.add(i);
+                notifyItemChanged(i);
+                flipCard(viewHolder);
+
+                AudioActivity audioActivity = (AudioActivity) getActivity();
+                assert audioActivity != null;
+                audioActivity.addSelectedNum();
+
+                Log.i(TAG, "点击前2" + selectList.toString() + "---" + i);
+            }else {
+                // 重播
+//                mediaPlayer.stop();
+                if(mediaPlayer.isPlaying()){
+                    mediaPlayer.seekTo(0);
+                }else{
+                    mediaPlayer.start();
+                }
+                Log.i(TAG, "重新播放音频");
+            }
+        });
+
+    }
+
+
+
+    @Override
+    public int getItemCount() {
+        Log.i(TAG, "getItemCount" + wordList.size());
+        return wordList.isEmpty() ? 0 : wordList.size();
+    }
+
+    // 设置动画
+    private void setAnimators(AudioAdapter.ViewHolder viewHolder, int pos) {
+        mRightOutSet = (AnimatorSet) AnimatorInflater.loadAnimator(context, R.animator.anim_out);
+        mLeftInSet = (AnimatorSet) AnimatorInflater.loadAnimator(context, R.animator.anim_in);
+
+        // 设置点击事件
+        mRightOutSet.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                super.onAnimationStart(animation);
+                viewHolder.tvBack.setClickable(false);
+            }
+        });
+        mLeftInSet.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                viewHolder.tvBack.setClickable(true);
+
+                if(mediaPlayer != null){
+                    mediaPlayer.start();
+                }
+                Log.i(TAG, "播放音频");
+            }
+        });
+    }
+
+    // 改变视角距离, 贴近屏幕
+    private void setCameraDistance(AudioAdapter.ViewHolder viewHolder) {
+        int distance = 1000000;
+        float scale = context.getResources().getDisplayMetrics().density * distance;
+        viewHolder.tvFront.setCameraDistance(scale);
+        viewHolder.tvBack.setCameraDistance(scale);
+        Log.i(TAG, "setCameraDistance:改变视角距离" + scale);
+    }
+
+    // 翻转卡片
+    public void flipCard(AudioAdapter.ViewHolder viewHolder) {
+        // 正面朝上
+//        if (!mIsShowBack) {
+//            mRightOutSet.setTarget(tvFront);
+//            mLeftInSet.setTarget(tvBack);
+//            mRightOutSet.start();
+//            mLeftInSet.start();
+//            mIsShowBack = true;
+//            Log.i(TAG, "flipCard:正面朝上");
+//        } else { // 背面朝上
+            mRightOutSet.setTarget(viewHolder.tvBack);
+            mLeftInSet.setTarget(viewHolder.tvFront);
+            mRightOutSet.start();
+            mLeftInSet.start();
+//            mIsShowBack = false;
+            Log.i(TAG, "flipCard:背面朝上");
+//        }
+    }
+
+    public void release(){
+        mediaPlayer.release();
+        mediaPlayer = null;
+        Log.i(TAG, "release");
+    }
+
+    public static class ViewHolder extends RecyclerView.ViewHolder {
+
+        private TextView tvFront;
+        private TextView tvBack;
+
+        public ViewHolder(@NonNull View itemView) {
+            super(itemView);
+            tvFront = itemView.findViewById(R.id.tv_previous_audio);
+            tvBack = itemView.findViewById(R.id.tv_back_audio);
+        }
+    }
+}

+ 27 - 0
app/src/main/java/com/xunao/effectdemo/adapter/AudioDemandAdapter.java

@@ -0,0 +1,27 @@
+package com.xunao.effectdemo.adapter;
+
+import androidx.fragment.app.Fragment;
+import androidx.fragment.app.FragmentManager;
+import androidx.fragment.app.FragmentPagerAdapter;
+
+import java.util.List;
+
+public class AudioDemandAdapter extends FragmentPagerAdapter {
+
+    private List<Fragment> mlist;
+
+    public AudioDemandAdapter(FragmentManager fm, List<Fragment> list) {
+        super(fm);
+        this.mlist = list;
+    }
+    //显示第几个页面
+    @Override
+    public Fragment getItem(int position) {
+        return mlist.get(position);
+    }
+    //一共有几个页面,注意,使用Fragment特有的构造器时,和ViewPager的原生构造器的方法不同
+    @Override
+    public int getCount() {
+        return mlist.size();
+    }
+}

+ 80 - 0
app/src/main/java/com/xunao/effectdemo/adapter/DeviceAdapter.java

@@ -0,0 +1,80 @@
+package com.xunao.effectdemo.adapter;
+
+import android.content.Context;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.BaseAdapter;
+import android.widget.TextView;
+
+import androidx.annotation.Nullable;
+
+import com.xunao.effectdemo.R;
+import com.hpplay.sdk.source.browse.api.LelinkServiceInfo;
+
+import java.util.List;
+
+/**
+ * author : 程中强
+ * e-mail : 740479946@qq.com
+ * date : 2022/9/2114:22
+ * desc :
+ * version: 1.0
+ */
+public class DeviceAdapter extends BaseAdapter {
+
+	private List<LelinkServiceInfo> data;
+	private Context context;
+
+	public DeviceAdapter(Context context, @Nullable List<LelinkServiceInfo> data) {
+
+		this.context = context;
+		this.data = data;
+	}
+
+//	@Override
+//	protected void convert(@NonNull BaseViewHolder helper, LelinkServiceInfo item) {
+//		Log.e("MyTag","设备:"+item.getName());
+//		helper
+//				.setText(R.id.tv_name_item, TextUtils.isEmpty(item.getName())?"":item.getName())
+//
+//		;
+//	}
+
+	@Override
+	public int getCount() {
+		return data.size();
+	}
+
+	@Override
+	public Object getItem(int i) {
+		return data.get(i);
+	}
+
+	@Override
+	public long getItemId(int i) {
+		return i;
+	}
+
+	@Override
+	public View getView(int i, View convertView, ViewGroup viewGroup) {
+		MyViewHolder holder;
+		if (convertView == null) {
+			holder = new MyViewHolder();
+			convertView = LayoutInflater.from(context).inflate(R.layout.item_device, null);
+			holder.tv_name = convertView.findViewById(R.id.tv_name_item);
+			convertView.setTag(holder);
+		} else {
+			holder = (MyViewHolder) convertView.getTag();
+		}
+		Log.e("MyTag","结果收到消息111");
+		holder.tv_name.setText(TextUtils.isEmpty(data.get(i).getName())?"":data.get(i).getName());
+		return convertView;
+	}
+
+	class MyViewHolder {
+		TextView tv_name;
+	}
+}

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/adapter/VideoDemandAdapter.java

@@ -16,7 +16,6 @@ import java.util.List;
 
 public class VideoDemandAdapter extends FragmentPagerAdapter {
 
-    private FragmentManager mfragmentManager;
     private List<Fragment> mlist;
 
     public VideoDemandAdapter(FragmentManager fm, List<Fragment> list) {

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/anim/Anim.java

@@ -1,7 +1,6 @@
 package com.xunao.effectdemo.anim;
 
 import android.graphics.Canvas;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 3
app/src/main/java/com/xunao/effectdemo/anim/AnimBaiYeChuang.java

@@ -2,9 +2,6 @@ package com.xunao.effectdemo.anim;
 
 import android.graphics.Canvas;
 import android.graphics.Path;
-import android.graphics.Region;
-import android.util.Log;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/anim/AnimCaChu.java

@@ -1,7 +1,6 @@
 package com.xunao.effectdemo.anim;
 
 import android.graphics.Canvas;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 2
app/src/main/java/com/xunao/effectdemo/anim/AnimHeZhuang.java

@@ -2,8 +2,6 @@ package com.xunao.effectdemo.anim;
 
 import android.graphics.Canvas;
 import android.graphics.Region;
-import android.util.Log;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 3
app/src/main/java/com/xunao/effectdemo/anim/AnimJieTi.java

@@ -2,9 +2,6 @@ package com.xunao.effectdemo.anim;
 
 import android.graphics.Canvas;
 import android.graphics.Path;
-import android.graphics.Region;
-import android.util.Log;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/anim/AnimLingXing.java

@@ -3,7 +3,6 @@ package com.xunao.effectdemo.anim;
 import android.graphics.Canvas;
 import android.graphics.Path;
 import android.graphics.Region;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 2
app/src/main/java/com/xunao/effectdemo/anim/AnimLunZi.java

@@ -3,8 +3,6 @@ package com.xunao.effectdemo.anim;
 import android.graphics.Canvas;
 import android.graphics.Path;
 import android.graphics.RectF;
-import android.graphics.Region;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/anim/AnimPiLie.java

@@ -2,7 +2,6 @@ package com.xunao.effectdemo.anim;
 
 import android.graphics.Canvas;
 import android.graphics.Region;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 2
app/src/main/java/com/xunao/effectdemo/anim/AnimQiPan.java

@@ -2,8 +2,6 @@ package com.xunao.effectdemo.anim;
 
 import android.graphics.Canvas;
 import android.graphics.Path;
-import android.graphics.Region;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 2
app/src/main/java/com/xunao/effectdemo/anim/AnimQieRu.java

@@ -1,8 +1,6 @@
 package com.xunao.effectdemo.anim;
 
 import android.graphics.Canvas;
-import android.graphics.Region;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/anim/AnimShanXingZhanKai.java

@@ -3,7 +3,6 @@ package com.xunao.effectdemo.anim;
 import android.graphics.Canvas;
 import android.graphics.Path;
 import android.graphics.RectF;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/anim/AnimShiZiXingKuoZhan.java

@@ -2,7 +2,6 @@ package com.xunao.effectdemo.anim;
 
 import android.graphics.Canvas;
 import android.graphics.Region;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 3
app/src/main/java/com/xunao/effectdemo/anim/AnimSuiJiXianTiao.java

@@ -2,9 +2,6 @@ package com.xunao.effectdemo.anim;
 
 import android.graphics.Canvas;
 import android.graphics.Path;
-import android.graphics.Region;
-import android.util.Log;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 2
app/src/main/java/com/xunao/effectdemo/anim/AnimXiangNeiRongJie.java

@@ -2,8 +2,6 @@ package com.xunao.effectdemo.anim;
 
 import android.graphics.Canvas;
 import android.graphics.Path;
-import android.graphics.Region;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/anim/AnimYuanXingKuoZhan.java

@@ -4,7 +4,6 @@ import android.graphics.Canvas;
 import android.graphics.Path;
 import android.graphics.RectF;
 import android.graphics.Region;
-import android.view.View;
 
 import com.xunao.effectdemo.view.EnterAnimLayout;
 

+ 226 - 0
app/src/main/java/com/xunao/effectdemo/dlan/CastManager.java

@@ -0,0 +1,226 @@
+package com.xunao.effectdemo.dlan;
+
+import android.util.Log;
+
+import com.hpplay.sdk.source.api.ILelinkPlayerListener;
+import com.hpplay.sdk.source.api.INewPlayerListener;
+import com.hpplay.sdk.source.bean.CastBean;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 推送
+ */
+public class CastManager {
+    private final static String TAG = "DemoCastManager";
+    private static CastManager sInstance = null;
+    private final List<ILelinkPlayerListener> mListenerList = new ArrayList<>();
+    private final List<INewPlayerListener> mListenerList2 = new ArrayList<>();
+    private final ILelinkPlayerListener mLelinkPlayerListener = new ILelinkPlayerListener() {
+
+        @Override
+        public void onLoading() {
+            for (ILelinkPlayerListener listener : mListenerList) {
+                listener.onLoading();
+            }
+        }
+
+        @Override
+        public void onStart() {
+            for (ILelinkPlayerListener listener : mListenerList) {
+                listener.onStart();
+            }
+        }
+
+        @Override
+        public void onPause() {
+            for (ILelinkPlayerListener listener : mListenerList) {
+                listener.onPause();
+            }
+        }
+
+        @Override
+        public void onCompletion() {
+            for (ILelinkPlayerListener listener : mListenerList) {
+                listener.onCompletion();
+            }
+        }
+
+        @Override
+        public void onStop() {
+            for (ILelinkPlayerListener listener : mListenerList) {
+                listener.onStop();
+            }
+        }
+
+        @Override
+        public void onSeekComplete(int i) {
+            for (ILelinkPlayerListener listener : mListenerList) {
+                listener.onSeekComplete(i);
+            }
+        }
+
+        @Override
+        public void onInfo(final int what, final int extra) {
+            for (ILelinkPlayerListener listener : mListenerList) {
+                listener.onInfo(what, extra);
+            }
+        }
+
+        @Override
+        public void onInfo(int what, final String data) {
+            for (ILelinkPlayerListener listener : mListenerList) {
+                listener.onInfo(what, data);
+            }
+        }
+
+        @Override
+        public void onError(int what, int extra) {
+            Log.i(TAG, "onError what:" + what + " extra:" + extra);
+            for (ILelinkPlayerListener listener : mListenerList) {
+                listener.onError(what, extra);
+            }
+        }
+
+        @Override
+        public void onVolumeChanged(float v) {
+            for (ILelinkPlayerListener listener : mListenerList) {
+                listener.onVolumeChanged(v);
+            }
+        }
+
+        @Override
+        public void onPositionUpdate(long duration, long position) {
+            for (ILelinkPlayerListener listener : mListenerList) {
+                listener.onPositionUpdate(duration, position);
+            }
+        }
+    };
+
+    public synchronized static CastManager getInstance() {
+        synchronized (CastManager.class) {
+            if (sInstance == null) {
+                sInstance = new CastManager();
+            }
+        }
+        return sInstance;
+    }
+
+    private CastManager() {
+
+    }
+
+    public ILelinkPlayerListener getLelinkPlayerListener() {
+        return mLelinkPlayerListener;
+    }
+
+    public void addPlayerListener(ILelinkPlayerListener listener) {
+        if (mListenerList.size()>0){
+            mListenerList.clear();
+        }
+        mListenerList.add(listener);
+    }
+
+    public void removeListener(ILelinkPlayerListener listener) {
+        if (listener != null){
+            mListenerList.remove(listener);
+        }
+
+    }
+
+    private final INewPlayerListener mPlayerListener = new INewPlayerListener() {
+
+        @Override
+        public void onLoading(CastBean bean) {
+            for (INewPlayerListener listener : mListenerList2) {
+                listener.onLoading(bean);
+            }
+        }
+
+        @Override
+        public void onStart(CastBean bean) {
+            for (INewPlayerListener listener : mListenerList2) {
+                listener.onStart(bean);
+            }
+        }
+
+        @Override
+        public void onPause(CastBean bean) {
+            for (INewPlayerListener listener : mListenerList2) {
+                listener.onPause(bean);
+            }
+        }
+
+        @Override
+        public void onCompletion(CastBean bean, int type) {
+            for (INewPlayerListener listener : mListenerList2) {
+                listener.onCompletion(bean, type);
+            }
+        }
+
+        @Override
+        public void onStop(CastBean bean) {
+            for (INewPlayerListener listener : mListenerList2) {
+                listener.onStop(bean);
+            }
+        }
+
+        @Override
+        public void onSeekComplete(CastBean bean, int position) {
+            for (INewPlayerListener listener : mListenerList2) {
+                listener.onSeekComplete(bean, position);
+            }
+        }
+
+        @Override
+        public void onInfo(CastBean bean, final int what, final int extra) {
+            for (INewPlayerListener listener : mListenerList2) {
+                listener.onInfo(bean, what, extra);
+            }
+        }
+
+        @Override
+        public void onInfo(CastBean bean, int what, final String data) {
+            for (INewPlayerListener listener : mListenerList2) {
+                listener.onInfo(bean, what, data);
+            }
+        }
+
+        @Override
+        public void onError(CastBean bean, int what, int extra) {
+//            Logger.i(TAG, "onError what:" + what + " extra:" + extra);
+            for (INewPlayerListener listener : mListenerList2) {
+                listener.onError(bean, what, extra);
+            }
+        }
+
+        @Override
+        public void onVolumeChanged(CastBean bean, float percent) {
+            for (INewPlayerListener listener : mListenerList2) {
+                listener.onVolumeChanged(bean, percent);
+            }
+        }
+
+        @Override
+        public void onPositionUpdate(CastBean bean, long duration, long position) {
+            for (INewPlayerListener listener : mListenerList2) {
+                listener.onPositionUpdate(bean, duration, position);
+            }
+        }
+    };
+
+
+    public INewPlayerListener getPlayerListener() {
+        return mPlayerListener;
+    }
+
+    public void addPlayerListener(INewPlayerListener listener) {
+        mListenerList2.add(listener);
+    }
+
+    public void removeListener(INewPlayerListener listener) {
+        mListenerList2.remove(listener);
+    }
+
+}

+ 197 - 0
app/src/main/java/com/xunao/effectdemo/dlan/DLNAControlCenter.java

@@ -0,0 +1,197 @@
+package com.xunao.effectdemo.dlan;
+
+import android.os.Handler;
+import android.text.TextUtils;
+
+import com.xunao.effectdemo.App;
+import com.hpplay.sdk.source.api.LelinkPlayerInfo;
+import com.hpplay.sdk.source.api.LelinkSourceSDK;
+import com.hpplay.sdk.source.bean.BrowserConfigBean;
+import com.hpplay.sdk.source.bean.MediaAssetBean;
+import com.hpplay.sdk.source.browse.api.LelinkServiceInfo;
+
+import java.util.concurrent.ExecutorService;
+
+/**
+ * author : 程中强
+ * e-mail : 740479946@qq.com
+ * date : 2022/9/1916:56
+ * desc :
+ * version: 1.0
+ */
+public class DLNAControlCenter {
+
+	private volatile static DLNAControlCenter dlnaCenter;
+	private ExecutorService executorService;
+	private long startMiracastTime;
+	private Handler handler;
+	private boolean isDlnaMode = false;
+	//dlna投屏相关
+	private final static int PUSH_SEEK = 3; // 投屏seek
+	private final static int PUSH_STATE_LISTENING = 4;//投屏状态监听
+	private final static int PUSH_STATE_BACK = 5;//投屏状态返回
+	private final static int PUSH_PLAY = 6; // 投屏开始
+
+	public static DLNAControlCenter getInstance() {
+		if (null == dlnaCenter) {
+			synchronized (DLNAControlCenter.class) {
+				if (dlnaCenter == null) {
+					dlnaCenter = new DLNAControlCenter();
+				}
+			}
+		}
+		return dlnaCenter;
+	}
+
+
+	private DLNAControlCenter() {
+//        executorService = Executors.newCachedThreadPool();
+		DeviceManager connectManager = DeviceManager.getInstance();
+		//sdk初始化
+		LelinkSourceSDK.getInstance()
+				.setBindSdkListener(connectManager.getBindListener())
+				.setBrowseResultListener(connectManager.getBrowseListener())
+				.setConnectListener(connectManager.getConnectListener())
+				.setPlayListener(CastManager.getInstance().getLelinkPlayerListener())
+				//FIXME WARN: 这里替换为您申请的AppID & AppSecret,build.gradle替换为您的应用包名
+//                .setSdkInitInfo(AppVarManager.getInstance().getBaseContext(), "17894", "69ce8955094258d339c1b6eadef2ec09")
+				.setSdkInitInfo(App.getInstance(), "17894", "69ce8955094258d339c1b6eadef2ec09")
+				.bindSdk();
+	}
+
+	public synchronized void startLelinkSearch() {
+		try {
+			BrowserConfigBean configBean = new BrowserConfigBean();
+			configBean.useLelink = true;
+			configBean.useDlna = true;
+			configBean.useBLE = true;
+			configBean.useSonic = true;
+			LelinkSourceSDK.getInstance().startBrowse(configBean);
+		} catch (Throwable throwable) {
+			throwable.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * dlna播放
+	 *
+	 * @param device
+	 * @param castUrl
+	 */
+	public synchronized void dlnaPlay(LelinkServiceInfo device, String castUrl, String titleName, double duration) {
+		if (device == null || TextUtils.isEmpty(castUrl)) {
+			return;
+		}
+		try {
+			LelinkSourceSDK.getInstance().stopPlay();
+			startMiracastTime = System.currentTimeMillis();
+			LelinkPlayerInfo lelinkPlayerInfo = new LelinkPlayerInfo();
+			lelinkPlayerInfo.setUrl(castUrl);
+			lelinkPlayerInfo.setType(LelinkSourceSDK.MEDIA_TYPE_VIDEO);
+			MediaAssetBean mediaAssetBean = new MediaAssetBean();
+			mediaAssetBean.setName(titleName);
+			// 非必要参数,部分dlna不返回视频总长度,实现下一集时若需要兼容这种dlna接收端,需设置媒资总长度,单位秒
+			mediaAssetBean.setDuration((long) duration);
+			lelinkPlayerInfo.setMediaAsset(mediaAssetBean);
+			lelinkPlayerInfo.setLelinkServiceInfo(device);
+			LelinkSourceSDK.getInstance().startPlayMedia(lelinkPlayerInfo);
+		} catch (Throwable throwable) {
+			throwable.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * 投屏跳转相应位置
+	 *
+	 * @param device
+	 */
+	public synchronized void dlnaSeekToPlayPosition(LelinkServiceInfo device, int progress) {
+		try {
+			LelinkSourceSDK.getInstance().seekTo(progress);
+		} catch (Throwable throwable) {
+			throwable.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * dlna暂停
+	 *
+	 * @param curTPDevice
+	 */
+	public synchronized void dlnaPause(LelinkServiceInfo curTPDevice) {
+		if (curTPDevice == null) return;
+		try {
+			LelinkSourceSDK.getInstance().pause();
+		} catch (Throwable throwable) {
+			throwable.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * dlna开始
+	 */
+	public synchronized void dlnaResume() {
+		try {
+			LelinkSourceSDK.getInstance().resume();
+		} catch (Throwable throwable) {
+			throwable.printStackTrace();
+		}
+
+	}
+
+	/**
+	 * dlna投屏停止
+	 *
+	 * @param curTPDevice
+	 */
+	public synchronized void dlnaStop(LelinkServiceInfo curTPDevice, String titleId) {
+		try {
+
+			LelinkSourceSDK.getInstance().stopPlay();
+		} catch (Throwable throwable) {
+			throwable.printStackTrace();
+		}
+
+//        dlnaCenter = null;
+	}
+
+	/**
+	 * dlna设置音量
+	 */
+	public synchronized void dlnaVolume(boolean isAddVolume) {
+		try {
+			if (isAddVolume) {
+				LelinkSourceSDK.getInstance().addVolume();
+			} else {
+				LelinkSourceSDK.getInstance().subVolume();
+			}
+		} catch (Throwable throwable) {
+			throwable.printStackTrace();
+		}
+	}
+
+	/**
+	 * dlan上一次暂停位置上播放
+	 *
+	 * @param curTPDevice
+	 */
+	public synchronized void dlnaGoonPlayPosition(LelinkServiceInfo curTPDevice, int progress) {
+		if (curTPDevice == null) return;
+		try {
+			LelinkSourceSDK.getInstance().seekTo(progress);
+		} catch (Throwable throwable) {
+			throwable.printStackTrace();
+		}
+
+
+	}
+
+	public void setUIListener(IUIUpdateListener mUIListener) {
+		DeviceManager.getInstance().setUIListener(mUIListener);
+	}
+
+}

+ 172 - 0
app/src/main/java/com/xunao/effectdemo/dlan/DeviceManager.java

@@ -0,0 +1,172 @@
+package com.xunao.effectdemo.dlan;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.hpplay.sdk.source.api.IBindSdkListener;
+import com.hpplay.sdk.source.api.IConnectListener;
+import com.hpplay.sdk.source.api.IRelevantInfoListener;
+import com.hpplay.sdk.source.api.LelinkSourceSDK;
+import com.hpplay.sdk.source.browse.api.IBrowseListener;
+import com.hpplay.sdk.source.browse.api.LelinkServiceInfo;
+
+import java.util.List;
+
+/**
+ * 连接
+ */
+public class DeviceManager {
+    private final static String TAG = "DemoDeviceManager";
+
+    private static DeviceManager sInstance = null;
+    private LelinkServiceInfo mSelectInfo;
+    private IUIUpdateListener mUIListener;
+
+    private IBindSdkListener mBindSdkListener = new IBindSdkListener() {
+        @Override
+        public void onBindCallback(boolean success) {
+            Log.i(TAG, "onBindCallback " + success);
+            setPassThroughListener();
+            if (success) {
+                Log.e("LeBo","初始化:"+success);
+                if (mUIListener != null) {
+                    mUIListener.onBindSuccess();
+                }
+
+            }
+        }
+    };
+
+    private IBrowseListener mBrowseListener = new IBrowseListener() {
+
+        @Override
+        public void onBrowse(int i, List<LelinkServiceInfo> list) {
+            if (i == IBrowseListener.BROWSE_ERROR_AUTH) {
+                Log.e(TAG, "授权失败");
+                return;
+            }
+            if (i == IBrowseListener.BROWSE_STOP) {
+                Log.i(TAG, "搜索停止");
+            } else if (i == IBrowseListener.BROWSE_TIMEOUT) {
+                Log.i(TAG, "搜索超时");
+            }
+            if (mUIListener != null) {
+                mUIListener.onUpdateDevices(list);
+            }
+        }
+    };
+
+    private IConnectListener mConnectListener = new IConnectListener() {
+        @Override
+        public void onConnect(LelinkServiceInfo lelinkServiceInfo, int protocol) {
+            Log.i(TAG, "onConnect:" + lelinkServiceInfo.getName());
+            String type = protocol == IConnectListener.TYPE_LELINK ? "Lelink"
+                    : protocol == IConnectListener.TYPE_DLNA ? "DLNA"
+                    : protocol == IConnectListener.TYPE_IM ? "IM" : ("协议:" + protocol);
+            setSelectInfo(lelinkServiceInfo);
+            if (mUIListener != null) {
+                mUIListener.onConnect(lelinkServiceInfo);
+            }
+        }
+
+        @Override
+        public void onDisconnect(LelinkServiceInfo lelinkServiceInfo, int what, int extra) {
+            if (lelinkServiceInfo == null) {
+                return;
+            }
+            Log.i(TAG, "onDisconnect:" + lelinkServiceInfo.getName() + " disConnectType:" + what + " extra:" + extra);
+            String text = null;
+            if (what == IConnectListener.WHAT_HARASS_WAITING) {// 防骚扰,等待用户确认
+                // 乐播投屏防骚扰等待消息,请开发者务必处理该消息
+                text = lelinkServiceInfo.getName() + "等待用户确认";
+            } else if (what == IConnectListener.WHAT_DISCONNECT) {
+                switch (extra) {
+                    case IConnectListener.EXTRA_HARASS_REJECT:// 防骚扰,用户拒绝投屏
+                        text = lelinkServiceInfo.getName() + "连接被拒绝";
+                        break;
+                    case IConnectListener.EXTRA_HARASS_TIMEOUT:// 防骚扰,用户响应超时
+                        text = lelinkServiceInfo.getName() + "防骚扰响应超时";
+                        break;
+                    case IConnectListener.EXTRA_HARASS_BLACKLIST:// 防骚扰,该用户被加入黑名单
+                        text = lelinkServiceInfo.getName() + "已被加入投屏黑名单";
+                        break;
+                    case IConnectListener.EXTRA_CONNECT_DEVICE_OFFLINE:
+                        text = lelinkServiceInfo.getName() + "不在线";
+                        break;
+                    default:
+                        text = lelinkServiceInfo.getName() + "连接断开";
+                        break;
+                }
+            } else if (what == IConnectListener.WHAT_CONNECT_FAILED) {
+                switch (extra) {
+                    case IConnectListener.EXTRA_CONNECT_DEVICE_OFFLINE:
+                        text = lelinkServiceInfo.getName() + "不在线";
+                        break;
+                    default:
+                        text = lelinkServiceInfo.getName() + "连接失败";
+                        break;
+                }
+            }
+            if (TextUtils.isEmpty(text)) {
+                text = "onDisconnect " + what + "/" + extra;
+            }
+        }
+    };
+
+    public static synchronized DeviceManager getInstance() {
+        synchronized (DeviceManager.class) {
+            if (sInstance == null) {
+                sInstance = new DeviceManager();
+            }
+        }
+        return sInstance;
+    }
+
+    private DeviceManager() {
+
+    }
+
+    public void setUIListener(IUIUpdateListener listener) {
+        this.mUIListener = listener;
+    }
+
+    public void setSelectInfo(LelinkServiceInfo serviceInfo) {
+        mSelectInfo = serviceInfo;
+    }
+
+
+
+    public LelinkServiceInfo getSelectInfo() {
+        return mSelectInfo;
+    }
+
+    public IBindSdkListener getBindListener() {
+        return mBindSdkListener;
+    }
+
+    public IBrowseListener getBrowseListener() {
+        return mBrowseListener;
+    }
+
+    public IConnectListener getConnectListener() {
+        return mConnectListener;
+    }
+
+    /**
+     * 设置透传监听
+     */
+    private void setPassThroughListener() {
+        LelinkSourceSDK.getInstance().setPassThroughListener(new IRelevantInfoListener() {
+            @Override
+            public void onSendRelevantInfoResult(int option, String result) {
+
+            }
+
+            @Override
+            public void onReverseInfoResult(int option, final String result) {
+                Log.i(TAG, "onReverseInfoResult option = " + option + ", result = " + result);
+            }
+        });
+    }
+
+}

+ 19 - 0
app/src/main/java/com/xunao/effectdemo/dlan/IUIUpdateListener.java

@@ -0,0 +1,19 @@
+package com.xunao.effectdemo.dlan;
+
+import com.hpplay.sdk.source.browse.api.LelinkServiceInfo;
+
+import java.util.List;
+
+public interface IUIUpdateListener {
+
+    void onUpdateDevices(List<LelinkServiceInfo> list);
+
+    void onConnect(LelinkServiceInfo info);
+
+    void onDisconnect(LelinkServiceInfo info);
+
+    void onNetChanged();
+
+    void onBindSuccess();
+
+}

+ 0 - 2
app/src/main/java/com/xunao/effectdemo/dragview/DragViewUtil.java

@@ -1,11 +1,9 @@
 package com.xunao.effectdemo.dragview;
 
-import android.content.ClipData;
 import android.util.Log;
 import android.view.DragEvent;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
 
 /**
  * author : 程中强

+ 81 - 0
app/src/main/java/com/xunao/effectdemo/fragment/AudioDemandFragment.java

@@ -0,0 +1,81 @@
+package com.xunao.effectdemo.fragment;
+
+import static android.view.View.GONE;
+
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.media.MediaPlayer;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import androidx.fragment.app.Fragment;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
+import androidx.recyclerview.widget.SimpleItemAnimator;
+
+import com.shuyu.gsyvideoplayer.GSYVideoManager;
+import com.xunao.effectdemo.R;
+import com.xunao.effectdemo.activity.AudioActivity;
+import com.xunao.effectdemo.adapter.AudioAdapter;
+import com.xunao.effectdemo.adapter.WordCutAdapter;
+
+import java.io.IOException;
+import java.util.Objects;
+
+public class AudioDemandFragment extends Fragment {
+    private final String TAG = "AudioDemandFragment";
+
+    private AudioActivity activity = (AudioActivity) getActivity();
+
+    private String[] data;
+
+    private RecyclerView rvAudio;
+    private AudioAdapter audioAdapter;
+
+    private MediaPlayer mediaPlayer;
+    private String url = "http://www.mobvcasting.com/android/audio/goodmorningandroid.mp3";
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        View view = inflater.inflate(R.layout.fragment_audio_demand, container, false);
+
+        assert getArguments() != null;
+        data = getArguments().getStringArray("data");
+
+        rvAudio = view.findViewById(R.id.rv_audio);
+        ((SimpleItemAnimator) Objects.requireNonNull(rvAudio.getItemAnimator())).setSupportsChangeAnimations(false);
+        // 设置横向布局
+        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.HORIZONTAL, false){
+            @Override
+            public boolean canScrollHorizontally() {
+                return false;
+            }
+        };
+        rvAudio.setLayoutManager(linearLayoutManager);
+        audioAdapter = new AudioAdapter(data, getContext());
+        rvAudio.setAdapter(audioAdapter);
+
+        return view;
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        audioAdapter.release();
+    }
+
+    // 当前fragment 可见->不可见 或 不可见->可见时 会调用这个方法
+    @Override
+    public void setUserVisibleHint(boolean isVisibleToUser) {
+        super.setUserVisibleHint(isVisibleToUser);
+        Log.i(TAG, "setUserVisibleHint: " + isVisibleToUser + "--" + data);
+
+    }
+}

+ 14 - 5
app/src/main/java/com/xunao/effectdemo/fragment/VideoDemandFragment.java

@@ -6,9 +6,7 @@ import android.animation.Animator;
 import android.animation.AnimatorInflater;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
-import android.content.Context;
 import android.os.Bundle;
-import android.util.AttributeSet;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -16,12 +14,12 @@ import android.view.ViewGroup;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
-import androidx.annotation.Nullable;
 import androidx.fragment.app.Fragment;
 
 import com.shuyu.gsyvideoplayer.GSYVideoManager;
 import com.shuyu.gsyvideoplayer.listener.GSYVideoProgressListener;
 import com.xunao.effectdemo.R;
+import com.xunao.effectdemo.activity.VideoDemandActivity;
 import com.xunao.effectdemo.view.VideoPreviewPlay;
 
 public class VideoDemandFragment extends Fragment {
@@ -34,11 +32,13 @@ public class VideoDemandFragment extends Fragment {
     private TextView tvBack;
     private boolean mIsShowBack = true;
     private String url = "http://v3.cztv.com/cztv/vod/2018/06/28/7c45987529ea410dad7c088ba3b53dac/h264_1500k_mp4.mp4";
-    String data;
+//    private String url = "https://flutter.github.io/assets-for-api-docs/assets/videos/butterfly.mp4";
+    private String data;
+
 
     @Override
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
-        View view = inflater.inflate(R.layout.view_video_demand, container, false);
+        View view = inflater.inflate(R.layout.fragment_video_demand, container, false);
         videoFront = view.findViewById(R.id.video_front);
         videoFront.setUp(url, true, "null");
         videoFront.getTitleTextView().setVisibility(View.GONE);
@@ -58,12 +58,20 @@ public class VideoDemandFragment extends Fragment {
         rlContainer = view.findViewById(R.id.rl_container);
         tvBack.setOnClickListener(v -> {
             flipCard();
+
+            VideoDemandActivity videoDemandActivity = (VideoDemandActivity) getActivity();
+            assert videoDemandActivity != null;
+            videoDemandActivity.addSelectedNum();
+
+            videoFront.setUp(url, true, "null");
+            videoFront.startPlayLogic();
         });
         setAnimators(); // 设置动画
         setCameraDistance(); // 设置镜头距离
 
         assert getArguments() != null;
         data = getArguments().getString("data");
+        tvBack.setText("背面" + data);
         return view;
     }
 
@@ -152,6 +160,7 @@ public class VideoDemandFragment extends Fragment {
     public void setUserVisibleHint(boolean isVisibleToUser) {
         super.setUserVisibleHint(isVisibleToUser);
         Log.i(TAG, "setUserVisibleHint: " + isVisibleToUser + "--" + data);
+        // 不可见时暂停视频
         if(!isVisibleToUser && videoFront != null){
             videoFront.onVideoPause();
         }

+ 287 - 0
app/src/main/java/com/xunao/effectdemo/net/ApiHttpClient.java

@@ -0,0 +1,287 @@
+package com.xunao.effectdemo.net;
+
+import android.content.Context;
+import android.util.Base64;
+import android.util.Log;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.xunao.effectdemo.App;
+import com.xunao.effectdemo.utils.EncryptUtil;
+import com.zhy.http.okhttp.OkHttpUtils;
+import com.zhy.http.okhttp.builder.PostStringBuilder;
+import com.zhy.http.okhttp.callback.BitmapCallback;
+import com.zhy.http.okhttp.callback.StringCallback;
+import com.zhy.http.okhttp.cookie.CookieJarImpl;
+import com.zhy.http.okhttp.cookie.store.PersistentCookieStore;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URLEncoder;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.Callback;
+import okhttp3.FormBody;
+import okhttp3.MediaType;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import okhttp3.Response;
+
+
+public class ApiHttpClient {
+    private static String API_URL = "";
+
+    public static OkHttpClient client;
+    public static HashMap<String, String> headers = new HashMap<>();
+    public static HashMap<String, String> bodys = new HashMap<>();
+
+    public static final String MEDIA_TYPE_JSON = "application/json; charset=utf-8";
+
+    public static Context mContext;
+
+    public ApiHttpClient() {
+
+    }
+
+    public static OkHttpClient getHttpClient() {
+        return client;
+    }
+
+    public static void init() {
+        mContext = App.getInstance();
+
+        CookieJarImpl cookieJar = new CookieJarImpl(new PersistentCookieStore(mContext));
+        OkHttpClient client = new OkHttpClient.Builder()
+                .connectTimeout(30, TimeUnit.SECONDS)
+                .writeTimeout(30, TimeUnit.SECONDS)
+                .readTimeout(30, TimeUnit.SECONDS)
+                .followRedirects(true)
+                .cookieJar(cookieJar)
+                .retryOnConnectionFailure(true)
+                .build();
+        OkHttpUtils.initClient(client);
+
+        addHeader("Accept-Language", Locale.getDefault().toString());
+        addHeader("Accept", MEDIA_TYPE_JSON);
+    }
+
+    public static String getAbsoluteApiUrl(String partUrl) {
+//        String url = String.format(API_URL, partUrl);
+        return partUrl;
+    }
+
+    public static String getAbsoluteApiUrl(String partUrl,Map<String, String> params) {
+        String url = null;
+        for (String key:params.keySet()){
+            url = (url==null?"":(url+"&"))+key+":"+params.get(key);
+        }
+        return partUrl;
+    }
+
+    public static void get(String partUrl, CSMHttpCallback callback) {
+        OkHttpUtils
+                .get()
+                .url(getAbsoluteApiUrl(partUrl))
+                .headers(headers)
+                .build()
+                .execute(callback);
+    }
+
+    public static void get(String partUrl, Map<String, String> params,CSMHttpCallback callback) {
+        OkHttpUtils
+                .get()
+                .url(getAbsoluteApiUrl(partUrl,params))
+                .headers(headers)
+                .build()
+                .execute(callback);
+    }
+
+    public static void post(String partUrl, CSMHttpCallback callback) {
+        OkHttpUtils
+                .post()
+                .url(getAbsoluteApiUrl(partUrl))
+                .headers(headers)
+                .build()
+                .execute(callback);
+    }
+
+    public static void post(String partUrl, Map<String, String> params, CSMHttpCallback callback) {
+        try {
+//            params.put("app_type","android");
+//            params.put("app_version",BmonsterApplication.version);
+            addHeader("param", generateSignStr(params));//
+            String jsonParam = new Gson().toJson(params);
+            params = new Gson().fromJson(jsonParam, new TypeToken<HashMap<String, String>>(){}.getType());
+            OkHttpUtils
+                    .post()
+                    .url(getAbsoluteApiUrl(partUrl))
+                    .headers(headers)
+                    .params(params)
+                    .build()
+                    .execute(callback);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void post2(String partUrl, Map<String, String> params,Map<String,String> map, CSMHttpCallback callback) {
+        try {
+//            params.put("app_type","android");
+//            params.put("app_version",BmonsterApplication.version);
+//            addHeader("post", generateSignStr(params));//
+            String jsonParam = new Gson().toJson(params);
+            params = new Gson().fromJson(jsonParam, new TypeToken<HashMap<String, String>>(){}.getType());
+            FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体
+//            formBody.add("username","zhangsan");//传递键值对参数
+            OkHttpUtils
+                    .post()
+                    .url(getAbsoluteApiUrl(partUrl))
+                    .headers(headers)
+                    .params(params)
+                    .build()
+                    .execute(callback);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void postBody(String partUrl, Map<String, String> params, MapBodyBean bean, Callback callback){
+
+        try {
+
+            Gson gson = new Gson();
+            //  转换层json字符串
+            final String s = gson.toJson(bean);
+            //  创建  RequestBody
+            String msg = generateSignStr(params);
+
+//            RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), s);
+//            Request request = new Request.Builder().url(partUrl).header("param", msg)
+//                    .post(requestBody).build();
+
+            FormBody.Builder formBody = new FormBody.Builder();//创建表单请求体
+            formBody.add("speed_list",bean.getSpeed_list());//传递键值对参数
+            formBody.add("height_list",bean.getHeight_list());//传递键值对参数
+            formBody.add("location_list",bean.getLocation_list());//传递键值对参数
+            Request request = new Request.Builder()//创建Request 对象。
+                    .url(partUrl)
+                    .header("param", msg)
+                    .post(formBody.build())//传递请求体
+                    .build();
+
+            OkHttpClient okHttpClient1 = OkHttpUtils.getInstance().getOkHttpClient();
+            okHttpClient1.newCall(request).enqueue(callback);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+
+
+    public static void post(String partUrl, Map<String, String> params, String fileParamName, File file, CSMHttpCallback callback) {
+        try {
+            OkHttpUtils
+                    .post()
+                    .url(getAbsoluteApiUrl(partUrl))
+                    .headers(headers)
+                    .params(params)
+                    .addFile(fileParamName, file.getName(), file)
+                    .build()
+                    .execute(callback);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void postJson(String partUrl, String json, CSMHttpCallback callback) {
+
+        OkHttpUtils
+                .postString()
+                .url(getAbsoluteApiUrl(partUrl))
+                .content(json)
+                .mediaType(MediaType.parse(MEDIA_TYPE_JSON))
+                .headers(headers)
+                .build()
+                .execute(callback);
+    }
+
+    public static void postJsonAsync(String partUrl, String json, BitmapCallback callback) {
+        PostStringBuilder builder = OkHttpUtils
+                .postString()
+                .url(partUrl)
+                .mediaType(MediaType.parse(MEDIA_TYPE_JSON));
+        if (json != null) {
+            builder.content(json);
+        }
+        builder.build().execute(callback);
+    }
+
+    public static Response getFormSync(String partUrl) {
+        try {
+            Response response = OkHttpUtils
+                    .get()
+                    .url(partUrl)
+                    .build()
+                    .execute();
+            return response;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    public static void getAsync(String partUrl, StringCallback callback) {
+        OkHttpUtils
+                .get()
+                .url(partUrl)
+                .build()
+                .execute(callback);
+    }
+
+    public static void addHeader(String key, String value) {
+        if (headers.containsKey(key)) {
+            headers.remove(key);
+        }
+        headers.put(key, value);
+    }
+
+    public static void addBodys(String key, String value) {
+        if (bodys.containsKey(key)) {
+            bodys.remove(key);
+        }
+        bodys.put(key, value);
+    }
+
+    private static String generateSignStr(Map<String, String> params) {
+        //1、将请求数据按照key字典序排序后的数组
+        Map<String, String> sortMap = new TreeMap((Comparator<String>) (s, t1) -> s.compareTo(t1));
+        sortMap.putAll(params);
+        //2、将所有的请求数据拼接为字符串
+        StringBuilder sb = new StringBuilder();
+        for (String value:sortMap.values()) {
+            sb.append(value);
+        }
+        //3、将 $str urlencode 加密
+        String encodeStr = URLEncoder.encode(sb.toString());
+        //4、将上面加密的字符串转化为小写
+        encodeStr = encodeStr.toLowerCase();
+        //5、转化为小写之后再进行md5加密
+        String md5Str = EncryptUtil.md5(encodeStr);
+        //生成signStr之后的请求参数数组
+        Map<String, Object> map = new HashMap();
+        map.put("params", sortMap);
+        map.put("signStr", md5Str);
+        //6、将请求数组转化为json格式
+        String json = new Gson().toJson(map);
+        //将上一步生成的json数据转化为 base64 格式数据
+        Log.d("json", json);
+        Log.d("base64", Base64.encodeToString(json.getBytes(), Base64.NO_WRAP));
+        return Base64.encodeToString(json.getBytes(), Base64.NO_WRAP);
+    }
+}
+

+ 14 - 0
app/src/main/java/com/xunao/effectdemo/net/ApiUrl.java

@@ -0,0 +1,14 @@
+package com.xunao.effectdemo.net;
+
+
+public class ApiUrl {
+
+
+    /**
+     *测试环境
+     */
+    public static final String url = "http://stuapi.kidcastle.cn/";
+
+    public static final String login = url+"Base/Login";
+
+}

+ 51 - 0
app/src/main/java/com/xunao/effectdemo/net/BaseBean.java

@@ -0,0 +1,51 @@
+package com.xunao.effectdemo.net;
+
+import com.google.gson.Gson;
+import com.xunao.effectdemo.utils.StringUtil;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+
+
+public class BaseBean implements Serializable {
+
+    public static BaseBean parse(InputStream inputStream) throws IOException {
+        String jsonStr = StringUtil.inputStream2String(inputStream, "utf-8");
+        return parse(jsonStr);
+    }
+
+    public static BaseBean parse(String jsonStr) {
+        Gson gson = new Gson();
+        BaseBean baseBean = gson.fromJson(jsonStr, BaseBean.class);
+        return baseBean;
+    }
+
+    private String retCode;
+    private String retMsgJp;
+    private String retMsgEn;
+
+    public String getRetCode() {
+        return retCode;
+    }
+
+    public void setRetCode(String retCode) {
+        this.retCode = retCode;
+    }
+
+    public String getRetMsgJp() {
+        return retMsgJp;
+    }
+
+    public void setRetMsgJp(String retMsgJp) {
+        this.retMsgJp = retMsgJp;
+    }
+
+    public String getRetMsgEn() {
+        return retMsgEn;
+    }
+
+    public void setRetMsgEn(String retMsgEn) {
+        this.retMsgEn = retMsgEn;
+    }
+}

+ 68 - 0
app/src/main/java/com/xunao/effectdemo/net/CSMHttpCallback.java

@@ -0,0 +1,68 @@
+package com.xunao.effectdemo.net;
+
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.xunao.effectdemo.utils.StringUtil;
+import com.zhy.http.okhttp.callback.Callback;
+
+import java.io.ByteArrayInputStream;
+
+import okhttp3.Call;
+import okhttp3.Response;
+
+public abstract class CSMHttpCallback extends Callback<String> {
+
+    private final static String TAG = CSMHttpCallback.class.getName();
+
+    protected abstract void onSuccess(String jsonStr);
+
+    protected abstract void onFail(String msg);
+
+    @Override
+    public boolean validateReponse(Response response, int id) {
+        return true;
+    }
+
+    @Override
+    public String parseNetworkResponse(Response response, int id) throws Exception {
+        String url = response.request().url().toString();
+        String responseStr = StringUtil.inputStream2String(new ByteArrayInputStream(response.body().bytes()), "utf-8");
+
+        switch (response.code()) {
+            case 200:
+                return responseStr;
+            case 401:
+                break;
+            default:
+        }
+        return "";
+    }
+
+    @Override
+    public void onError(Call call, Exception exception, int id) {
+        exception.printStackTrace();
+    }
+
+    @Override
+    public void onResponse(String response, int id) {
+        Log.i(TAG, "response==>" + response);
+        if (!TextUtils.isEmpty(response)) {
+            if (response.contains("retCode")){
+                BaseBean baseBean = BaseBean.parse(response);
+                if (baseBean.getRetCode().equals("1000")) {
+                    onSuccess(response);
+                }else if(baseBean.getRetCode().equals("1007")||baseBean.getRetCode().equals("1005")){
+                    onFail("1007");
+
+                } else {
+                    onFail("请求报错");
+                }
+            }else{
+                onSuccess(response);
+            }
+        } else {
+//            onFail(BmonsterApplication.resources().getString(R.string.net_error));
+        }
+    }
+}

+ 32 - 0
app/src/main/java/com/xunao/effectdemo/net/MapBodyBean.java

@@ -0,0 +1,32 @@
+package com.xunao.effectdemo.net;
+
+public class MapBodyBean {
+
+    private String speed_list;
+    private String height_list;
+    private String location_list;
+
+    public String getSpeed_list() {
+        return speed_list;
+    }
+
+    public void setSpeed_list(String speed_list) {
+        this.speed_list = speed_list;
+    }
+
+    public String getHeight_list() {
+        return height_list;
+    }
+
+    public void setHeight_list(String height_list) {
+        this.height_list = height_list;
+    }
+
+    public String getLocation_list() {
+        return location_list;
+    }
+
+    public void setLocation_list(String location_list) {
+        this.location_list = location_list;
+    }
+}

+ 0 - 9
app/src/main/java/com/xunao/effectdemo/umeng/UmInitConfig.java

@@ -1,21 +1,12 @@
 package com.xunao.effectdemo.umeng;
 
-import android.app.Notification;
-import android.app.NotificationChannel;
 import android.content.Context;
-import android.content.Intent;
-import android.os.Build;
 import android.os.Handler;
-import android.util.Log;
-import android.widget.RemoteViews;
-import android.widget.Toast;
 
 import com.umeng.analytics.MobclickAgent;
 import com.umeng.commonsdk.UMConfigure;
 import com.xunao.effectdemo.App;
 
-import static android.os.Looper.getMainLooper;
-
 
 public class UmInitConfig {
 

+ 30 - 0
app/src/main/java/com/xunao/effectdemo/utils/EncryptUtil.java

@@ -0,0 +1,30 @@
+package com.xunao.effectdemo.utils;
+
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ * Created by chris on 15/5/21.
+ */
+public class EncryptUtil {
+
+    public static String md5(String string) {
+        byte[] hash;
+        try {
+            hash = MessageDigest.getInstance("MD5").digest(string.getBytes("UTF-8"));
+        } catch (NoSuchAlgorithmException e) {
+            throw new RuntimeException("Huh, MD5 should be supported?", e);
+        } catch (UnsupportedEncodingException e) {
+            throw new RuntimeException("Huh, UTF-8 should be supported?", e);
+        }
+
+        StringBuilder hex = new StringBuilder(hash.length * 2);
+        for (byte b : hash) {
+            if ((b & 0xFF) < 0x10) hex.append("0");
+            hex.append(Integer.toHexString(b & 0xFF));
+        }
+        return hex.toString();
+    }
+
+}

+ 0 - 4
app/src/main/java/com/xunao/effectdemo/utils/FocusUtils.java

@@ -1,14 +1,10 @@
 package com.xunao.effectdemo.utils;
 
-import android.animation.Animator;
 import android.animation.AnimatorSet;
 import android.animation.ValueAnimator;
 import android.util.Log;
 import android.view.View;
-import android.view.ViewAnimationUtils;
-import android.view.ViewGroup;
 import android.view.ViewParent;
-import android.widget.ViewAnimator;
 
 /**
  * author : 程中强

+ 0 - 2
app/src/main/java/com/xunao/effectdemo/utils/MediaRecorderDemo.java

@@ -1,8 +1,6 @@
 package com.xunao.effectdemo.utils;
 
 import android.media.MediaRecorder;
-import android.os.Handler;
-import android.util.Log;
 
 import java.io.File;
 import java.io.IOException;

+ 777 - 0
app/src/main/java/com/xunao/effectdemo/utils/StringUtil.java

@@ -0,0 +1,777 @@
+package com.xunao.effectdemo.utils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.math.BigDecimal;
+import java.text.DecimalFormat;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.TimeZone;
+import java.util.regex.Pattern;
+
+public class StringUtil {
+
+    private final static String FSpliter = "##";
+    private final static String SSpliter = "||";
+
+    private final static Pattern PHONE = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$");
+
+    private final static Pattern emailer = Pattern
+            .compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
+
+    private final static Pattern IMG_URL = Pattern
+            .compile(".*?(gif|jpeg|png|jpg|bmp)");
+
+    private final static Pattern URL = Pattern
+            .compile("^(https|http)://.*?$(net|com|.com.cn|org|me|)");
+
+    private final static ThreadLocal<SimpleDateFormat> dateFormater = new ThreadLocal<SimpleDateFormat>() {
+        @Override
+        protected SimpleDateFormat initialValue() {
+            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        }
+    };
+
+    private final static ThreadLocal<SimpleDateFormat> dateFormater2 = new ThreadLocal<SimpleDateFormat>() {
+        @Override
+        protected SimpleDateFormat initialValue() {
+            return new SimpleDateFormat("yyyy-MM-dd");
+        }
+    };
+
+    /**
+     * 将字符串转位日期类型
+     *
+     * @param sdate
+     * @return
+     */
+    public static Date toDate(String sdate) {
+        return toDate(sdate, dateFormater.get());
+    }
+
+    public static Date toDate(String sdate, SimpleDateFormat dateFormater) {
+        try {
+            return dateFormater.parse(sdate);
+        } catch (ParseException e) {
+            return null;
+        }
+    }
+
+    public static String getDateString(Date date) {
+        return dateFormater.get().format(date);
+    }
+
+    /**
+     * 以友好的方式显示时间
+     *
+     * @param sdate
+     * @return
+     */
+    public static String friendly_time(String sdate) {
+        Date time = null;
+
+        if (TimeZoneUtil.isInEasternEightZones())
+            time = toDate(sdate);
+        else
+            time = TimeZoneUtil.transformTime(toDate(sdate),
+                    TimeZone.getTimeZone("GMT+08"), TimeZone.getDefault());
+
+        if (time == null) {
+            return "Unknown";
+        }
+        String ftime = "";
+        Calendar cal = Calendar.getInstance();
+
+        // 判断是否是同一天
+        String curDate = dateFormater2.get().format(cal.getTime());
+        String paramDate = dateFormater2.get().format(time);
+        if (curDate.equals(paramDate)) {
+            int hour = (int) ((cal.getTimeInMillis() - time.getTime()) / 3600000);
+            if (hour == 0)
+                ftime = Math.max(
+                        (cal.getTimeInMillis() - time.getTime()) / 60000, 1)
+                        + "分钟前";
+            else
+                ftime = hour + "小时前";
+            return ftime;
+        }
+
+        long lt = time.getTime() / 86400000;
+        long ct = cal.getTimeInMillis() / 86400000;
+        int days = (int) (ct - lt);
+        if (days == 0) {
+            int hour = (int) ((cal.getTimeInMillis() - time.getTime()) / 3600000);
+            if (hour == 0)
+                ftime = Math.max(
+                        (cal.getTimeInMillis() - time.getTime()) / 60000, 1)
+                        + "分钟前";
+            else
+                ftime = hour + "小时前";
+        } else if (days == 1) {
+            ftime = "昨天";
+        } else if (days == 2) {
+            ftime = "前天 ";
+        } else if (days > 2 && days < 31) {
+            ftime = days + "天前";
+        } else if (days >= 31 && days <= 2 * 31) {
+            ftime = "一个月前";
+        } else if (days > 2 * 31 && days <= 3 * 31) {
+            ftime = "2个月前";
+        } else if (days > 3 * 31 && days <= 4 * 31) {
+            ftime = "3个月前";
+        } else {
+            ftime = dateFormater2.get().format(time);
+        }
+        return ftime;
+    }
+
+    public static String friendly_time2(String sdate) {
+        String res = "";
+        if (isEmpty(sdate))
+            return "";
+
+        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
+        String currentData = StringUtil.getDataTime("MM-dd");
+        int currentDay = toInt(currentData.substring(3));
+        int currentMoth = toInt(currentData.substring(0, 2));
+
+        int sMoth = toInt(sdate.substring(5, 7));
+        int sDay = toInt(sdate.substring(8, 10));
+        int sYear = toInt(sdate.substring(0, 4));
+        Date dt = new Date(sYear, sMoth - 1, sDay - 1);
+
+        if (sDay == currentDay && sMoth == currentMoth) {
+            res = "今天 / " + weekDays[getWeekOfDate(new Date())];
+        } else if (sDay == currentDay + 1 && sMoth == currentMoth) {
+            res = "昨天 / " + weekDays[(getWeekOfDate(new Date()) + 6) % 7];
+        } else {
+            if (sMoth < 10) {
+                res = "0";
+            }
+            res += sMoth + "/";
+            if (sDay < 10) {
+                res += "0";
+            }
+            res += sDay + " / " + weekDays[getWeekOfDate(dt)];
+        }
+
+        return res;
+    }
+
+    /**
+     * 获取当前日期是星期几<br>
+     *
+     * @param dt
+     * @return 当前日期是星期几
+     */
+    public static int getWeekOfDate(Date dt) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(dt);
+        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
+        if (w < 0)
+            w = 0;
+        return w;
+    }
+
+    /**
+     * 判断给定字符串时间是否为今日
+     *
+     * @param sdate
+     * @return boolean
+     */
+    public static boolean isToday(String sdate) {
+        boolean b = false;
+        Date time = toDate(sdate);
+        Date today = new Date();
+        if (time != null) {
+            String nowDate = dateFormater2.get().format(today);
+            String timeDate = dateFormater2.get().format(time);
+            if (nowDate.equals(timeDate)) {
+                b = true;
+            }
+        }
+        return b;
+    }
+
+    /**
+     * 返回long类型的今天的日期
+     *
+     * @return
+     */
+    public static long getToday() {
+        Calendar cal = Calendar.getInstance();
+        String curDate = dateFormater2.get().format(cal.getTime());
+        curDate = curDate.replace("-", "");
+        return Long.parseLong(curDate);
+    }
+
+    public static String getCurTimeStr() {
+        Calendar cal = Calendar.getInstance();
+        String curDate = dateFormater.get().format(cal.getTime());
+        return curDate;
+    }
+
+    /***
+     * 计算两个时间差,返回的是的秒s
+     *
+     * @param dete1
+     * @param date2
+     * @return
+     * @author 火蚁 2015-2-9 下午4:50:06
+     */
+    public static long calDateDifferent(String dete1, String date2) {
+
+        long diff = 0;
+
+        Date d1 = null;
+        Date d2 = null;
+
+        try {
+            d1 = dateFormater.get().parse(dete1);
+            d2 = dateFormater.get().parse(date2);
+
+            // 毫秒ms
+            diff = d2.getTime() - d1.getTime();
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return diff / 1000;
+    }
+
+    public static String getChineseForNum(int num) {
+        String chineseNum = "";
+        switch (num) {
+            case 0:
+                chineseNum = "零";
+                break;
+            case 1:
+                chineseNum = "一";
+                break;
+            case 2:
+                chineseNum = "二";
+                break;
+            case 3:
+                chineseNum = "三";
+                break;
+            case 4:
+                chineseNum = "四";
+                break;
+            case 5:
+                chineseNum = "五";
+                break;
+            case 6:
+                chineseNum = "六";
+                break;
+            case 7:
+                chineseNum = "七";
+                break;
+            case 8:
+                chineseNum = "八";
+                break;
+            case 9:
+                chineseNum = "九";
+                break;
+            case 10:
+                chineseNum = "十";
+                break;
+        }
+        return chineseNum;
+    }
+
+    /**
+     * 判断给定字符串是否空白串。 空白串是指由空格、制表符、回车符、换行符组成的字符串 若输入字符串为null或空字符串,返回true
+     *
+     * @param input
+     * @return boolean
+     */
+    public static boolean isEmpty(String input) {
+        if (input == null || "".equals(input))
+            return true;
+
+        for (int i = 0; i < input.length(); i++) {
+            char c = input.charAt(i);
+            if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static boolean isPhone(String phone) {
+        if (phone == null || phone.trim().length() == 0) {
+            return false;
+        }
+        return PHONE.matcher(phone).matches();
+    }
+
+    /**
+     * 判断是不是一个合法的电子邮件地址
+     *
+     * @param email
+     * @return
+     */
+    public static boolean isEmail(String email) {
+        if (email == null || email.trim().length() == 0)
+            return false;
+        return emailer.matcher(email).matches();
+    }
+
+    /**
+     * 判断一个url是否为图片url
+     *
+     * @param url
+     * @return
+     */
+    public static boolean isImgUrl(String url) {
+        if (url == null || url.trim().length() == 0)
+            return false;
+        return IMG_URL.matcher(url).matches();
+    }
+
+    /**
+     * 判断是否为一个合法的url地址
+     *
+     * @param str
+     * @return
+     */
+    public static boolean isUrl(String str) {
+        if (str == null || str.trim().length() == 0)
+            return false;
+        return URL.matcher(str).matches();
+    }
+
+    /**
+     * 字符串转整数
+     *
+     * @param str
+     * @param defValue
+     * @return
+     */
+    public static int toInt(String str, int defValue) {
+        try {
+            return Integer.parseInt(str);
+        } catch (Exception e) {
+        }
+        return defValue;
+    }
+
+    /**
+     * 对象转整数
+     *
+     * @param obj
+     * @return 转换异常返回 0
+     */
+    public static int toInt(Object obj) {
+        if (obj == null)
+            return 0;
+        return toInt(obj.toString(), 0);
+    }
+
+    /**
+     * 对象转整数
+     *
+     * @param obj
+     * @return 转换异常返回 0
+     */
+    public static long toLong(String obj) {
+        try {
+            return Long.parseLong(obj);
+        } catch (Exception e) {
+        }
+        return 0;
+    }
+
+    /**
+     * 字符串转布尔值
+     *
+     * @param b
+     * @return 转换异常返回 false
+     */
+    public static boolean toBool(String b) {
+        try {
+            return Boolean.parseBoolean(b);
+        } catch (Exception e) {
+        }
+        return false;
+    }
+
+    public static String getString(String s) {
+        return s == null ? "" : s;
+    }
+
+    /**
+     * 将一个InputStream流转换成字符串
+     *
+     * @param is
+     * @return
+     */
+    public static String toConvertString(InputStream is) {
+        StringBuffer res = new StringBuffer();
+        InputStreamReader isr = new InputStreamReader(is);
+        BufferedReader read = new BufferedReader(isr);
+        try {
+            String line;
+            line = read.readLine();
+            while (line != null) {
+                res.append(line + "<br>");
+                line = read.readLine();
+            }
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (null != isr) {
+                    isr.close();
+                    isr.close();
+                }
+                if (null != read) {
+                    read.close();
+                    read = null;
+                }
+                if (null != is) {
+                    is.close();
+                    is = null;
+                }
+            } catch (IOException e) {
+            }
+        }
+        return res.toString();
+    }
+
+    /***
+     * 截取字符串
+     *
+     * @param start 从那里开始,0算起
+     * @param num   截取多少个
+     * @param str   截取的字符串
+     * @return
+     */
+    public static String getSubString(int start, int num, String str) {
+        if (str == null) {
+            return "";
+        }
+        int leng = str.length();
+        if (start < 0) {
+            start = 0;
+        }
+        if (start > leng) {
+            start = leng;
+        }
+        if (num < 0) {
+            num = 1;
+        }
+        int end = start + num;
+        if (end > leng) {
+            end = leng;
+        }
+        return str.substring(start, end);
+    }
+
+    /**
+     * 获取当前时间为每年第几周
+     *
+     * @return
+     */
+    public static int getWeekOfYear() {
+        return getWeekOfYear(new Date());
+    }
+
+    /**
+     * 获取当前时间为每年第几周
+     *
+     * @param date
+     * @return
+     */
+    public static int getWeekOfYear(Date date) {
+        Calendar c = Calendar.getInstance();
+        c.setFirstDayOfWeek(Calendar.MONDAY);
+        c.setTime(date);
+        int week = c.get(Calendar.WEEK_OF_YEAR) - 1;
+        week = week == 0 ? 52 : week;
+        return week > 0 ? week : 1;
+    }
+
+    public static int[] getCurrentDate() {
+        int[] dateBundle = new int[3];
+        String[] temp = getDataTime("yyyy-MM-dd").split("-");
+
+        for (int i = 0; i < 3; i++) {
+            try {
+                dateBundle[i] = Integer.parseInt(temp[i]);
+            } catch (Exception e) {
+                dateBundle[i] = 0;
+            }
+        }
+        return dateBundle;
+    }
+
+    /**
+     * 返回当前系统时间
+     */
+    public static String getDataTime(String format) {
+        SimpleDateFormat df = new SimpleDateFormat(format);
+        return df.format(new Date());
+    }
+
+    /**
+     * 将一个InputStream流转换成字符串,UTF-8
+     */
+    public static String inputStream2String(InputStream is, String code) throws IOException {
+
+        BufferedReader in = new BufferedReader(new InputStreamReader(is, code));
+
+        int i = -1;
+        char[] b = new char[1000];
+        StringBuffer sb = new StringBuffer();
+
+        while ((i = in.read(b)) != -1) {
+            sb.append(new String(b, 0, i));
+        }
+        String content = sb.toString();
+        return content;
+    }
+
+    /**
+     * 将一个替换一个字符串中的某几个字符
+     */
+    public static String replaceStringForPosition(String res, String str, int start, int end) {
+        String head = res.substring(0, start - 1);
+        String body = str;
+        String tail = res.substring(end - 1);
+        return head + body + tail;
+    }
+
+    public static String getWanMoney(double money) {
+        double tempDouble = money / 10000;
+        if (tempDouble < 1) {
+            return String.valueOf((int) money);
+        } else {
+            NumberFormat nf = new DecimalFormat("#.#");
+            String strMoney = nf.format(tempDouble) + "万";
+            return strMoney;
+        }
+    }
+
+    public static String getFormatMoney(double money) {
+        NumberFormat nf = new DecimalFormat(",###");
+        String strMoney = nf.format(money);
+        return strMoney;
+    }
+
+    public static String getFormatMoneyOnePoint(double money) {
+        DecimalFormat nf = new DecimalFormat("#.#");
+        String strMoney = nf.format(new BigDecimal(money));
+        String[] strsTmp = strMoney.split("\\.");
+        if (strsTmp.length < 2) {
+            strMoney = strMoney + ".0";
+        } else {
+            if (strsTmp[1].length() > 1) {
+                strsTmp[1] = strsTmp[1].substring(0, 1);
+            }
+            strMoney = strsTmp[0] + "." + strsTmp[1];
+        }
+
+        return strMoney;
+    }
+
+    public static String getFormatMoneyTwoPoint(double money) {
+        DecimalFormat nf = new DecimalFormat("#.##");
+        String strMoney = nf.format(new BigDecimal(money));
+
+        String[] strsTmp = strMoney.split("\\.");
+        if (strsTmp.length < 2) {
+            strMoney = strMoney + ".00";
+        } else {
+            if (strsTmp[1].length() == 1) {
+                strsTmp[1] = strsTmp[1] + "0";
+            }
+            if (strsTmp[1].length() > 2) {
+                strsTmp[1] = strsTmp[1].substring(0, 2);
+            }
+            strMoney = strsTmp[0] + "." + strsTmp[1];
+        }
+
+        return strMoney;
+    }
+
+    public static String getFormatMoneyTwoPointFen(long money) {
+        String strMoney = String.valueOf(money);
+        strMoney = strMoney.substring(0, strMoney.length() - 2) + "." + strMoney.substring(strMoney.length() - 2);
+        return strMoney;
+    }
+
+    public static String[] splitStringsWithSpace(String source) {
+        if (StringUtil.isEmpty(source)) {
+            return null;
+        }
+
+        source = source + " .";
+        String tempSource = source.replace("[", "").replace("]", "");
+        String[] tempStrs = tempSource.split(" ");
+        String[] strs = new String[tempStrs.length - 1];
+        for (int i = 0; i < strs.length; i++) {
+            strs[i] = tempStrs[i];
+        }
+        return strs;
+    }
+
+    public static int[] spliteIntWithSpace(String source) {
+        if (StringUtil.isEmpty(source)) {
+            return null;
+        }
+
+        String[] strings = splitStringsWithSpace(source);
+        int[] ints = new int[strings.length];
+        for (int i = 0; i < strings.length; i++) {
+            ints[i] = Integer.valueOf(strings[i]);
+        }
+        return ints;
+    }
+
+    /**
+     * 定义size位整数,如果位数达不到,前面用0补齐
+     * 如果超出位数,用规定位数最大数补齐
+     * */
+    public static String formatSizedNum(int num, int size) {
+        String strNum = String.valueOf(num);
+        if (strNum.length() < size) {
+            while(strNum.length() < size) {
+                strNum = "0" + strNum;
+            }
+        } else if (strNum.length() > size) {
+            strNum = "";
+            while(strNum.length() < size) {
+                strNum += "9";
+            }
+        }
+        return strNum;
+    }
+
+    /**
+     * 用##分割
+     */
+    public static String[] spliteStringWithFS(String source) {
+        if (StringUtil.isEmpty(source)) {
+            return null;
+        }
+
+        String[] strs = source.split(FSpliter);
+        return strs;
+    }
+
+    /**
+     * 用||分割
+     */
+    public static String[] spliteStringWithSS(String source) {
+        if (StringUtil.isEmpty(source)) {
+            return null;
+        }
+
+        String[] strs = source.split(SSpliter);
+        return strs;
+    }
+
+    public static boolean isSame(String source, String target) {
+        if (source == null && target != null) {
+            return false;
+        } else if (source != null && target == null) {
+            return false;
+        } else if (source == target) {
+            return true;
+        } else if (source.equals(target)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public static String encryptionPhone(String phone) {
+        StringBuilder builder = new StringBuilder(phone);
+        if (phone.length() >= 11) {
+            for (int i = 3; i < phone.length() - 4; i++) {
+                builder.setCharAt(i, '*');
+            }
+        } else {
+            for (int i = 2; i < phone.length() - 2; i++) {
+                builder.setCharAt(i, '*');
+            }
+        }
+        return builder.toString();
+    }
+
+    /**
+     * 将字符串中的Unicode编码转换成UTF-8
+     * */
+    public static String decodeUnicode(String theString) {
+        char aChar;
+        int len = theString.length();
+        StringBuffer outBuffer = new StringBuffer(len);
+        for (int x = 0; x < len;) {
+            aChar = theString.charAt(x++);
+            if (aChar == '\\') {
+                aChar = theString.charAt(x++);
+                if (aChar == 'u') {
+                    // Read the xxxx
+                    int value = 0;
+                    for (int i = 0; i < 4; i++) {
+                        aChar = theString.charAt(x++);
+                        switch (aChar) {
+                            case '0':
+                            case '1':
+                            case '2':
+                            case '3':
+                            case '4':
+                            case '5':
+                            case '6':
+                            case '7':
+                            case '8':
+                            case '9':
+                                value = (value << 4) + aChar - '0';
+                                break;
+                            case 'a':
+                            case 'b':
+                            case 'c':
+                            case 'd':
+                            case 'e':
+                            case 'f':
+                                value = (value << 4) + 10 + aChar - 'a';
+                                break;
+                            case 'A':
+                            case 'B':
+                            case 'C':
+                            case 'D':
+                            case 'E':
+                            case 'F':
+                                value = (value << 4) + 10 + aChar - 'A';
+                                break;
+                            default:
+                                throw new IllegalArgumentException(
+                                        "Malformed   \\uxxxx   encoding.");
+                        }
+
+                    }
+                    outBuffer.append((char) value);
+                } else {
+                    if (aChar == 't')
+                        aChar = '\t';
+                    else if (aChar == 'r')
+                        aChar = '\r';
+                    else if (aChar == 'n')
+                        aChar = '\n';
+                    else if (aChar == 'f')
+                        aChar = '\f';
+                    outBuffer.append(aChar);
+                }
+            } else
+                outBuffer.append(aChar);
+        }
+        return outBuffer.toString();
+    }
+}

+ 35 - 0
app/src/main/java/com/xunao/effectdemo/utils/TimeZoneUtil.java

@@ -0,0 +1,35 @@
+package com.xunao.effectdemo.utils;
+
+import java.util.Date;
+import java.util.TimeZone;
+
+public class TimeZoneUtil {
+
+	/**
+	 * 判断用户的设备时区是否为东八区(中国) 2014年7月31日
+	 * @return
+	 */
+	public static boolean isInEasternEightZones() {
+		boolean defaultVaule = true;
+		if (TimeZone.getDefault() == TimeZone.getTimeZone("GMT+08"))
+			defaultVaule = true;
+		else
+			defaultVaule = false;
+		return defaultVaule;
+	}
+
+	/**
+	 * 根据不同时区,转换时间 2014年7月31日
+	 * @param
+	 * @return
+	 */
+	public static Date transformTime(Date date, TimeZone oldZone, TimeZone newZone) {
+		Date finalDate = null;
+		if (date != null) {
+			int timeOffset = oldZone.getOffset(date.getTime())
+					- newZone.getOffset(date.getTime());
+			finalDate = new Date(date.getTime() - timeOffset);
+		}
+		return finalDate;
+	}
+}

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/view/Calculator.java

@@ -3,7 +3,6 @@ package com.xunao.effectdemo.view;
 import android.app.Activity;
 import android.os.Build;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.view.View;
 import com.xuexiang.xui.widget.guidview.FocusShape;
 

+ 0 - 2
app/src/main/java/com/xunao/effectdemo/view/FireworkView.java

@@ -2,7 +2,6 @@ package com.xunao.effectdemo.view;
 
 import android.animation.ValueAnimator;
 import android.content.Context;
-import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.util.AttributeSet;
@@ -10,7 +9,6 @@ import android.util.Log;
 import android.util.TypedValue;
 import android.view.View;
 import android.view.animation.DecelerateInterpolator;
-import android.view.animation.LinearInterpolator;
 
 import androidx.annotation.Nullable;
 

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/view/GuideImageView.java

@@ -19,7 +19,6 @@ import android.graphics.RectF;
 import android.os.Build;
 import androidx.appcompat.widget.AppCompatImageView;
 import android.util.AttributeSet;
-import android.util.Log;
 
 import com.xuexiang.xui.widget.guidview.FocusShape;
 

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/view/MaskFilterView.java

@@ -6,7 +6,6 @@ import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.Path;
-import android.graphics.RectF;
 import android.util.AttributeSet;
 import android.view.View;
 

+ 0 - 2
app/src/main/java/com/xunao/effectdemo/view/MyGuideCaseQueue.java

@@ -1,8 +1,6 @@
 package com.xunao.effectdemo.view;
 
 import com.xuexiang.xui.widget.guidview.DismissListener;
-import com.xuexiang.xui.widget.guidview.GuideCaseQueue;
-import com.xuexiang.xui.widget.guidview.GuideCaseView;
 import com.xuexiang.xui.widget.guidview.OnCompleteListener;
 
 import java.util.LinkedList;

+ 0 - 3
app/src/main/java/com/xunao/effectdemo/view/MyGuideCaseView.java

@@ -1,7 +1,6 @@
 package com.xunao.effectdemo.view;
 
 import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
 import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.Context;
@@ -10,7 +9,6 @@ import android.os.Build;
 import android.text.Spanned;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
-import android.util.Log;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
@@ -39,7 +37,6 @@ import com.xuexiang.xui.widget.guidview.FocusShape;
 import com.xuexiang.xui.widget.guidview.OnViewInflateListener;
 //import com.xuexiang.xui.widget.guidview.Utils;
 import com.xunao.effectdemo.R;
-import com.xunao.effectdemo.activity.AnimActivity;
 
 /**
  * author : 程中强

+ 0 - 2
app/src/main/java/com/xunao/effectdemo/view/MyLikeView.java

@@ -2,7 +2,6 @@ package com.xunao.effectdemo.view;
 
 import android.animation.ValueAnimator;
 import android.content.Context;
-import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
@@ -14,7 +13,6 @@ import android.view.View;
 import android.view.animation.LinearInterpolator;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
-import androidx.core.content.ContextCompat;
 
 /**
  * author : 程中强

+ 434 - 2
app/src/main/java/com/xunao/effectdemo/view/VideoPreviewPlay.java

@@ -1,17 +1,43 @@
 package com.xunao.effectdemo.view;
 
 import android.content.Context;
+import android.os.Handler;
+import android.os.Message;
+import android.text.TextUtils;
 import android.util.AttributeSet;
+import android.util.Log;
 import android.view.Gravity;
 import android.view.MotionEvent;
 import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ListView;
+import android.widget.RelativeLayout;
 import android.widget.SeekBar;
+import android.widget.TextView;
 import android.widget.Toast;
 
+import androidx.annotation.NonNull;
+
+import com.xunao.effectdemo.adapter.DeviceAdapter;
+import com.xunao.effectdemo.dlan.DLNAControlCenter;
+import com.xunao.effectdemo.dlan.IUIUpdateListener;
+import com.hpplay.sdk.source.api.INewPlayerListener;
+import com.hpplay.sdk.source.api.LelinkSourceSDK;
+import com.hpplay.sdk.source.bean.CastBean;
+import com.hpplay.sdk.source.browse.api.LelinkServiceInfo;
+import com.hpplay.sdk.source.easycast.IEasyCastListener;
+import com.hpplay.sdk.source.easycast.bean.EasyCastBean;
+import com.shuyu.gsyvideoplayer.utils.CommonUtil;
 import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer;
 import com.xunao.effectdemo.R;
 import com.xunao.effectdemo.utils.SoundPoolUtil;
 
+import java.util.ArrayList;
+import java.util.List;
+
 /**
  * author : 程中强
  * e-mail : 740479946@qq.com
@@ -24,6 +50,22 @@ public class VideoPreviewPlay extends StandardGSYVideoPlayer {
 	private boolean isFinish = false;
 	private SoundPoolUtil soundPoolUtil;
 
+	private ViewGroup mBrowseContainer;//投屏搜索列表
+	private Button btn_cast;//投屏按钮
+	private RelativeLayout rl_dlan_control;//投屏控制层
+	private ImageView dlan_start;//投屏的播放暂停
+	private TextView dlan_current,dlan_total;//投屏的时长
+	private SeekBar dlan_progress;//投屏进度条
+	private boolean isDlanPlay = false;
+	public List<LelinkServiceInfo> mDevices = new ArrayList<>();
+	public LelinkServiceInfo curTPDevice;
+
+	private DeviceAdapter mDeviceAdapter;
+	private ListView rvList;
+	private IUIUpdateListener mUIListener;
+	private INewPlayerListener mPushListener;
+	private IEasyCastListener mCastListener;
+
 	public void setIsFinish(boolean isFinish){
 		this.isFinish = isFinish;
 	}
@@ -41,14 +83,101 @@ public class VideoPreviewPlay extends StandardGSYVideoPlayer {
 
 	@Override
 	public int getLayoutId() {
-		return super.getLayoutId();
+		return R.layout.activity_my_video;
 	}
 
+	public void stopDlan(){
+		LelinkSourceSDK.getInstance().stopPlay();
+	}
+
+	private Handler handler = new Handler(){
+		@Override
+		public void handleMessage(@NonNull Message msg) {
+			super.handleMessage(msg);
+			switch (msg.what){
+				case 1001:
+					Log.e("MyTag","结果收到消息");
+//					if (mDeviceAdapter != null) {
+						mDeviceAdapter.notifyDataSetChanged();
+					rvList.setAdapter(mDeviceAdapter);
+//					}
+					break;
+			}
+		}
+	};
+
 	@Override
 	protected void init(Context context) {
 		super.init(context);
+
 		soundPoolUtil= SoundPoolUtil.getInstance(context);
-		mProgressBar = (SeekBar) findViewById(R.id.progress);
+		mProgressBar = findViewById(R.id.progress);
+		dlan_progress = findViewById(R.id.dlan_progress);
+		mBrowseContainer = findViewById(R.id.mBrowseContainer);
+		btn_cast = findViewById(R.id.btn_cast);
+		rl_dlan_control = findViewById(R.id.rl_dlan_control);
+		dlan_start = findViewById(R.id.dlan_start);
+		dlan_current = findViewById(R.id.dlan_current);
+		dlan_total = findViewById(R.id.dlan_total);
+
+		rvList = findViewById(R.id.rv_device);
+//		rvList.setLayoutManager(new LinearLayoutManager(context));
+		mDevices = new ArrayList<>();
+//		mDevices.clear();
+		mDeviceAdapter = new DeviceAdapter(context, mDevices);
+		rvList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+			@Override
+			public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
+				curTPDevice = mDevices.get(i);
+
+				DLNAControlCenter.getInstance().dlnaPlay(curTPDevice, mOriginUrl, "",0);
+
+//			new Handler().postDelayed(new Runnable() {
+//				@Override
+//				public void run() {
+//					DLNAControlCenter.getInstance().dlnaSeekToPlayPosition(curTPDevice, (int) (ijkVrVideoView.getCurrentPosition() / 1000.0f));
+//				}
+//			}, 3000);
+			}
+		});
+
+		dlan_start.setOnClickListener(v->{
+
+			if (isDlanPlay) {
+				dlan_start.setImageResource(R.drawable.video_play_normal);
+				LelinkSourceSDK.getInstance().pause();
+			} else {
+				dlan_start.setImageResource(R.drawable.video_pause_normal);
+				LelinkSourceSDK.getInstance().resume();
+			}
+		});
+
+		btn_cast.setOnClickListener(v->{
+			LelinkSourceSDK.getInstance().setEasyCastListener(mCastListener);
+			LelinkSourceSDK.getInstance().easyPush(mBrowseContainer);
+//			LelinkSourceSDK.getInstance().setNewPlayListener(mPushListener);
+//			mDevices.clear();
+			onVideoPause();
+			mBrowseContainer.setVisibility(VISIBLE);
+//			DLNAControlCenter.getInstance().startLelinkSearch();
+		});
+		dlan_progress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+			@Override
+			public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
+
+			}
+
+			@Override
+			public void onStartTrackingTouch(SeekBar seekBar) {
+
+			}
+
+			@Override
+			public void onStopTrackingTouch(SeekBar seekBar) {
+				Log.e("MyTag","拖动:"+seekBar.getProgress()*getDuration()/100/1000);
+				LelinkSourceSDK.getInstance().seekTo(seekBar.getProgress()*getDuration()/100/1000);
+			}
+		});
 
 
 		mProgressBar.setOnTouchListener(new OnTouchListener() {
@@ -64,5 +193,308 @@ public class VideoPreviewPlay extends StandardGSYVideoPlayer {
 				return false;
 			}
 		});
+
+
+
+
+		initCast();
+	}
+
+	void initCast(){
+		mUIListener = new IUIUpdateListener() {
+			@Override
+			public void onUpdateDevices(List<LelinkServiceInfo> list) {
+				for (LelinkServiceInfo lelinkServiceInfo : list) {
+					if (mDevices.contains(lelinkServiceInfo)) {
+						continue;
+					} else {
+						mDevices.add(lelinkServiceInfo);
+
+						handler.sendEmptyMessage(1001);
+					}
+				}
+			}
+
+			@Override
+			public void onConnect(LelinkServiceInfo info) {
+//			lelinkCastSuccess(true);
+			}
+
+
+			@Override
+			public void onDisconnect(LelinkServiceInfo info) {
+//			DLNAControlCenter.getInstance().uploadCastDataToPlatform(false, curTPDevice, titleId);
+			}
+
+			@Override
+			public void onNetChanged() {
+			}
+
+			@Override
+			public void onBindSuccess() {
+			}
+		};
+
+		mPushListener = new INewPlayerListener() {
+
+			/**
+			 * @param bean 投屏信息
+			 *  内容开始加载
+			 */
+			@Override
+			public void onLoading(CastBean bean) {
+				btn_cast.setVisibility(GONE);
+				rl_dlan_control.setVisibility(VISIBLE);
+				isDlanPlay = true;
+				dlan_total.setText(mTotalTimeTextView.getText());
+			}
+
+			/**
+			 * @param bean 投屏信息
+			 *  开始播放
+			 */
+			@Override
+			public void onStart(CastBean bean) {
+				dlan_start.setImageResource(R.drawable.video_pause_normal);
+				isDlanPlay = true;
+			}
+			/**
+			 * @param bean 投屏信息
+			 *  播放暂停
+			 */
+			@Override
+			public void onPause(CastBean bean) {
+				dlan_start.setImageResource(R.drawable.video_play_normal);
+				isDlanPlay = false;
+			}
+			/**
+			 * 播放完成
+			 * @param bean 投屏信息
+			 * @param type 播放类型
+			 */
+			@Override
+			public void onCompletion(CastBean bean, int type) {
+				btn_cast.setVisibility(VISIBLE);
+				rl_dlan_control.setVisibility(GONE);
+				isDlanPlay = false;
+				onVideoResume();
+//			LelinkSourceSDK.getInstance().disconnect(lelinkServiceInfo);
+			}
+
+			/**
+			 * @param bean 投屏信息
+			 *  播放停止 (主动停止或者电视端停止均会回调)
+			 */
+			@Override
+			public void onStop(CastBean bean) {
+				isDlanPlay = false;
+				btn_cast.setVisibility(VISIBLE);
+				rl_dlan_control.setVisibility(GONE);
+				onVideoResume();
+			}
+			/**
+			 * 该接口暂未有数据回调
+			 */
+			@Override
+			public void onSeekComplete(CastBean bean, int position) {
+
+			}
+
+			/**
+			 * info信息回调,播放信息和收端能力查询等回调接口
+			 */
+			@Override
+			public void onInfo(CastBean bean, int what, int extra) {
+			}
+
+			/**
+			 * (重载接口)
+			 */
+			@Override
+			public void onInfo(CastBean bean, int what, String data) {
+
+			}
+
+			/**
+			 * @param bean 投屏信息
+			 * @param what 错误类型
+			 * @param extra 额外错误码
+			 */
+			@Override
+			public void onError(CastBean bean, int what, int extra) {
+				String text = "未知异常";
+				switch (extra) {
+					case EXTRA_ERROR_AUTH:
+					case EXTRA_ERROR_AUTH_TIME_DONE:
+						text = "SDK认证失败";
+						break;
+					case EXTRA_NEED_SCREEN_CODE:
+						text = "请输入密码";
+//					getActivity().runOnUiThread(new Runnable() {
+//						@Override
+//						public void run() {
+//							showPWDDialog();
+//						}
+//					});
+						break;
+					case EXTRA_DEVICE_OFFLINE:
+						text = "接收端不在线";
+						break;
+					case EXTRA_ERROR_PUSH_IO:
+						text = "网络通讯异常";
+						break;
+				}
+				if (TextUtils.isEmpty(text)) {
+					text = "推送 onError " + what + "/" + extra;
+				}
+			}
+
+			/**
+			 *
+			 * 该接口暂未有数据回调
+			 */
+			@Override
+			public void onVolumeChanged(CastBean bean, float percent) {
+
+			}
+
+			/**
+			 * 进度更新回调
+			 * @param bean 投屏信息
+			 * @param duration 最大进度 (单位秒)
+			 * @param position 当前进度 (单位秒)
+			 */
+			@Override
+			public void onPositionUpdate(CastBean bean, long duration, long position) {
+				if(duration!=0)
+					dlan_progress.setProgress((int) (position*100/duration));
+				dlan_current.setText(CommonUtil.stringForTime((int) position*1000));
+			}
+		};
+
+//		DLNAControlCenter.getInstance().setUIListener(mUIListener);
+//		CastManager.getInstance().addPlayerListener(mPushListener);
+
+		mCastListener = new IEasyCastListener() {
+
+			/**
+			 * 如果没有触发此回调,则表示此次未搜索到设备或用户未投屏
+			 * @param lelinkServiceInfo
+			 * @return
+			 */
+			@Override
+			public EasyCastBean onCast(LelinkServiceInfo lelinkServiceInfo) {
+				EasyCastBean bean = new EasyCastBean();
+				bean.url = mOriginUrl; //实际需要投屏的url
+				return bean;
+			}
+
+			/**
+			 * 如果投屏失败,在搜索页面关闭的时候,会触发回调
+			 * @param lelinkServiceInfo
+			 * @param easyCastBean
+			 * @param what
+			 * @param extra
+			 */
+			@Override
+			public void onCastError(LelinkServiceInfo lelinkServiceInfo, EasyCastBean easyCastBean, int what, int extra) {
+				Log.e("MyTag","推送失败"+what+"   "+extra);
+				btn_cast.setVisibility(VISIBLE);
+				mBrowseContainer.setVisibility(GONE);
+				rl_dlan_control.setVisibility(GONE);
+				isDlanPlay = false;
+				onVideoResume();
+			}
+
+			/**
+			 * 推送成功
+			 * @param lelinkServiceInfo
+			 * @param easyCastBean
+			 */
+			@Override
+			public void onCastLoading(LelinkServiceInfo lelinkServiceInfo, EasyCastBean easyCastBean) {
+				Log.e("MyTag","推送成功");
+				btn_cast.setVisibility(GONE);
+				mBrowseContainer.setVisibility(GONE);
+				rl_dlan_control.setVisibility(VISIBLE);
+				isDlanPlay = true;
+				dlan_total.setText(mTotalTimeTextView.getText());
+			}
+
+			/**
+			 * 暂停
+			 * @param lelinkServiceInfo
+			 * @param easyCastBean
+			 */
+			@Override
+			public void onCastPause(LelinkServiceInfo lelinkServiceInfo, EasyCastBean easyCastBean) {
+				dlan_start.setImageResource(R.drawable.video_play_normal);
+				isDlanPlay = false;
+			}
+
+			/**
+			 * 起播 或 收端暂停之后恢复播放
+			 * @param lelinkServiceInfo
+			 * @param easyCastBean
+			 */
+			@Override
+			public void onCastStart(LelinkServiceInfo lelinkServiceInfo, EasyCastBean easyCastBean) {
+				dlan_start.setImageResource(R.drawable.video_pause_normal);
+				isDlanPlay = true;
+			}
+
+			@Override
+			public void onCastPositionUpdate(LelinkServiceInfo lelinkServiceInfo, EasyCastBean easyCastBean, long duration, long position) {
+				Log.e("MyTag","当前:"+position);
+				if(duration!=0)dlan_progress.setProgress((int) (position*100/duration));
+				dlan_current.setText(CommonUtil.stringForTime((int) position*1000));
+			}
+
+			/**
+			 * 收端播放结束,如果需要实现下一集,可在之后的onCast回调中提供播放信息
+			 * @param lelinkServiceInfo
+			 * @param easyCastBean
+			 */
+			@Override
+			public void onCastCompletion(LelinkServiceInfo lelinkServiceInfo, EasyCastBean easyCastBean) {
+				btn_cast.setVisibility(VISIBLE);
+				rl_dlan_control.setVisibility(GONE);
+				mBrowseContainer.setVisibility(GONE);
+				isDlanPlay = false;
+				onVideoResume();
+//				LelinkSourceSDK.getInstance().disconnect(lelinkServiceInfo);
+			}
+
+			/**
+			 * 搜索退出播放,不同于 onCastCompletion,此时需要恢复APP视频播放
+			 * @param lelinkServiceInfo
+			 * @param easyCastBean
+			 */
+			@Override
+			public void onCastStop(LelinkServiceInfo lelinkServiceInfo, EasyCastBean easyCastBean) {
+				isDlanPlay = false;
+				btn_cast.setVisibility(VISIBLE);
+				rl_dlan_control.setVisibility(GONE);
+				mBrowseContainer.setVisibility(GONE);
+				onVideoResume();
+//				LelinkSourceSDK.getInstance().disconnect(lelinkServiceInfo);
+			}
+
+			@Override
+			public void onDismiss() {
+				btn_cast.setVisibility(VISIBLE);
+				rl_dlan_control.setVisibility(GONE);
+				mBrowseContainer.setVisibility(GONE);
+				isDlanPlay = false;
+				onVideoResume();
+//			LelinkSourceSDK.getInstance().stopPlay();
+			}
+		};
 	}
+
+
+
+
+
+
 }

+ 0 - 1
app/src/main/java/com/xunao/effectdemo/view/circleprogress/DialProgress.java

@@ -2,7 +2,6 @@ package com.xunao.effectdemo.view.circleprogress;
 
 import android.animation.ValueAnimator;
 import android.content.Context;
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
 import android.graphics.Color;

+ 37 - 0
app/src/main/res/layout/activity_audio.xml

@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center"
+    android:orientation="vertical"
+    tools:context=".activity.VideoDemandActivity">
+  <LinearLayout
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:gravity="center">
+    <ImageView
+        android:id="@+id/iv_audio_previous"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:src="@drawable/previous_icon"/>
+    <androidx.viewpager.widget.ViewPager
+        android:id="@+id/view_pager_audio"
+        android:layout_width="0dp"
+        android:layout_height="300dp"
+        android:layout_weight="1"/>
+    <ImageView
+        android:id="@+id/iv_audio_next"
+        android:layout_width="64dp"
+        android:layout_height="64dp"
+        android:src="@drawable/next_icon"/>
+  </LinearLayout>
+
+  <TextView
+      android:id="@+id/tv_num_audio"
+      android:layout_width="wrap_content"
+      android:layout_height="wrap_content"
+      android:textSize="30sp"
+      android:layout_marginTop="40dp"/>
+</LinearLayout>

+ 1 - 0
app/src/main/res/layout/activity_gsxy_video.xml

@@ -16,4 +16,5 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"/>
 
+
 </RelativeLayout>

+ 269 - 0
app/src/main/res/layout/activity_my_video.xml

@@ -0,0 +1,269 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@android:color/black">
+    <RelativeLayout
+        android:id="@+id/surface_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center">
+
+    </RelativeLayout>
+
+    <RelativeLayout
+        android:id="@+id/thumb"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_alignParentStart="true"
+        android:layout_alignParentLeft="true"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentEnd="true"
+        android:layout_alignParentRight="true"
+        android:layout_alignParentBottom="true"
+        android:background="#000000"
+        android:scaleType="fitCenter" />
+
+    <LinearLayout
+        android:id="@+id/layout_bottom"
+        android:layout_width="match_parent"
+        android:layout_height="40dp"
+        android:layout_alignParentBottom="true"
+        android:background="#99000000"
+        android:gravity="center_vertical"
+        android:orientation="horizontal"
+        android:visibility="invisible">
+
+        <TextView
+            android:id="@+id/current"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginLeft="16dp"
+            android:text="00:00"
+            android:textColor="#ffffff" />
+
+        <SeekBar
+            android:id="@+id/progress"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_vertical"
+            android:layout_weight="1.0"
+            android:background="@null"
+            android:max="100"
+            android:maxHeight="4dp"
+            android:minHeight="4dp"
+            android:paddingTop="8dp"
+            android:paddingBottom="8dp"
+            android:progressDrawable="@drawable/video_seek_progress"
+            android:thumb="@drawable/video_seek_thumb" />
+
+        <TextView
+            android:id="@+id/total"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginRight="16dp"
+            android:text="00:00"
+            android:textColor="#ffffff" />
+
+        <ImageView
+            android:id="@+id/fullscreen"
+            android:layout_width="wrap_content"
+            android:layout_height="fill_parent"
+            android:paddingRight="16dp"
+            android:scaleType="center"
+            android:src="@drawable/video_enlarge" />
+    </LinearLayout>
+
+    <ProgressBar
+        android:id="@+id/bottom_progressbar"
+        style="?android:attr/progressBarStyleHorizontal"
+        android:layout_width="match_parent"
+        android:layout_height="1.5dp"
+        android:layout_alignParentBottom="true"
+        android:max="100"
+        android:progressDrawable="@drawable/video_progress" />
+
+    <ImageView
+        android:id="@+id/back_tiny"
+        android:layout_width="24dp"
+        android:layout_height="24dp"
+        android:layout_marginLeft="6dp"
+        android:layout_marginTop="6dp"
+        android:visibility="gone" />
+
+
+    <ProgressBar
+        android:id="@+id/loading"
+        style="?android:attr/progressBarStyleLarge"
+        android:layout_width="28dp"
+        android:layout_height="28dp"
+        android:layout_centerHorizontal="true"
+        android:layout_centerVertical="true"
+        android:visibility="invisible" />
+
+
+    <ImageView
+        android:id="@+id/start"
+        android:layout_width="60dp"
+        android:layout_height="60dp"
+        android:layout_centerInParent="true"
+        android:layout_gravity="center_vertical"
+        android:src="@drawable/video_click_play_selector" />
+
+
+    <ImageView
+        android:id="@+id/small_close"
+        android:layout_width="30dp"
+        android:layout_height="30dp"
+        android:paddingLeft="10dp"
+        android:paddingTop="10dp"
+        android:scaleType="centerInside"
+        android:src="@drawable/video_small_close"
+        android:visibility="gone" />
+
+    <ImageView
+        android:id="@+id/lock_screen"
+        android:layout_width="30dp"
+        android:layout_height="30dp"
+        android:layout_alignParentRight="true"
+        android:layout_centerVertical="true"
+        android:layout_marginRight="50dp"
+        android:scaleType="centerInside"
+        android:src="@drawable/unlock"
+        android:visibility="gone" />
+
+    <LinearLayout
+        android:id="@+id/layout_top"
+        android:layout_width="match_parent"
+        android:layout_height="48dp"
+        android:layout_alignParentTop="true"
+        android:layout_toEndOf="@+id/back_tiny"
+        android:layout_toRightOf="@+id/back_tiny"
+        android:background="@drawable/video_title_bg"
+        android:gravity="center_vertical">
+
+        <ImageView
+            android:id="@+id/back"
+            android:layout_width="48dp"
+            android:layout_height="48dp"
+            android:paddingLeft="10dp"
+            android:scaleType="centerInside"
+            android:src="@drawable/video_back" />
+
+        <TextView
+            android:id="@+id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:paddingLeft="10dp"
+            android:textColor="@android:color/white"
+            android:textSize="18sp" />
+    </LinearLayout>
+
+
+
+    <RelativeLayout
+        android:id="@+id/preview_layout"
+        android:layout_width="@dimen/seek_bar_image"
+        android:layout_height="100dp"
+        android:layout_above="@+id/layout_bottom"
+        android:layout_alignParentBottom="true"
+        android:layout_marginBottom="30dp"
+        android:visibility="gone">
+
+        <ImageView
+            android:id="@+id/preview_image"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:background="#000000" />
+    </RelativeLayout>
+
+
+    <Button
+        android:id="@+id/btn_cast"
+        android:text="投屏"
+        android:visibility="visible"
+        android:layout_marginRight="100dp"
+        android:layout_alignParentRight="true"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"/>
+
+    <RelativeLayout
+        android:id="@+id/mBrowseContainer"
+        android:visibility="gone"
+        android:background="#000000"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent">
+        <ListView
+            android:id="@+id/rv_device"
+            android:visibility="gone"
+            android:background="#FFF"
+            android:layout_marginTop="100dp"
+            android:layout_centerHorizontal="true"
+            android:layout_width="300dp"
+            android:layout_height="match_parent"/>
+    </RelativeLayout>
+
+    <RelativeLayout
+        android:id="@+id/rl_dlan_control"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@android:color/black"
+        android:visibility="gone">
+
+        <ImageView
+            android:id="@+id/dlan_start"
+            android:layout_width="60dp"
+            android:layout_height="60dp"
+            android:layout_centerInParent="true"
+            android:layout_gravity="center_vertical"
+            android:src="@drawable/video_pause_normal" />
+
+        <LinearLayout
+            android:id="@+id/dlan_layout_bottom"
+            android:layout_width="match_parent"
+            android:layout_height="40dp"
+            android:layout_alignParentBottom="true"
+            android:background="#99000000"
+            android:gravity="center_vertical"
+            android:orientation="horizontal"
+            android:visibility="visible">
+
+            <TextView
+                android:id="@+id/dlan_current"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginLeft="16dp"
+                android:text="00:00"
+                android:textColor="#ffffff" />
+
+            <SeekBar
+                android:id="@+id/dlan_progress"
+                android:layout_width="0dp"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                android:layout_weight="1.0"
+                android:background="@null"
+                android:max="100"
+                android:maxHeight="4dp"
+                android:minHeight="4dp"
+                android:paddingTop="8dp"
+                android:paddingBottom="8dp"
+                android:progressDrawable="@drawable/video_seek_progress"
+                android:thumb="@drawable/video_seek_thumb" />
+
+            <TextView
+                android:id="@+id/dlan_total"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_marginRight="16dp"
+                android:text="00:00"
+                android:textColor="#ffffff" />
+
+        </LinearLayout>
+
+    </RelativeLayout>
+
+</RelativeLayout>

+ 8 - 0
app/src/main/res/layout/activity_video_demand.xml

@@ -23,4 +23,12 @@
         android:src="@drawable/next_icon"
         android:layout_centerVertical="true"
         android:layout_alignParentRight="true"/>
+    <TextView
+        android:id="@+id/tv_num"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_alignParentBottom="true"
+        android:layout_centerHorizontal="true"
+        android:layout_marginBottom="20dp"
+        android:textSize="30sp"/>
 </RelativeLayout>

+ 5 - 0
app/src/main/res/layout/fragment_audio_demand.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.recyclerview.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/rv_audio"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"/>

+ 1 - 2
app/src/main/res/layout/fragment_first.xml

@@ -3,8 +3,7 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".FirstFragment">
+    android:layout_height="match_parent">
 
     <TextView
         android:id="@+id/textview_first"

+ 1 - 2
app/src/main/res/layout/fragment_second.xml

@@ -3,8 +3,7 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    tools:context=".SecondFragment">
+    android:layout_height="match_parent">
 
     <TextView
         android:id="@+id/textview_second"

+ 1 - 0
app/src/main/res/layout/view_video_demand.xml → app/src/main/res/layout/fragment_video_demand.xml

@@ -14,5 +14,6 @@
         android:background="@color/colorGrayDark"
         android:gravity="center"
         android:textSize="28sp"
+        android:textColor="@color/exo_white"
         android:text="背面"/>
 </RelativeLayout>

+ 25 - 0
app/src/main/res/layout/item_audio_demand.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/rl_container"
+    android:layout_width="230dp"
+    android:layout_height="300dp"
+    android:layout_marginHorizontal="22dp">
+    <TextView
+        android:id="@+id/tv_previous_audio"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/colorGrayDark"
+        android:gravity="center"
+        android:textSize="28sp"
+        android:textColor="@color/exo_white"
+        android:text="正面"/>
+    <TextView
+        android:id="@+id/tv_back_audio"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="@color/colorGrayDark"
+        android:gravity="center"
+        android:textSize="28sp"
+        android:textColor="@color/exo_white"
+        android:text="背面"/>
+</RelativeLayout>

+ 14 - 0
app/src/main/res/layout/item_device.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+    <TextView
+        android:id="@+id/tv_name_item"
+        android:text="sheb"
+        android:layout_centerInParent="true"
+        android:textSize="20sp"
+        android:gravity="center"
+        android:layout_width="200dp"
+        android:padding="30dp"
+        android:layout_height="wrap_content"/>
+</RelativeLayout>