Commit b6ec78b84c550d765cfdfb794d1ce3fd208b70d3

Authored by 吴奎庆
0 parents

云测bug修改

Showing 63 changed files with 4803 additions and 0 deletions

Too many changes to show.

To preserve performance only 63 of 254 files are displayed.

.gitignore 0 → 100644
  1 +++ a/.gitignore
  1 +*.iml
  2 +.gradle
  3 +/local.properties
  4 +/.idea/caches
  5 +/.idea/libraries
  6 +/.idea/modules.xml
  7 +/.idea/workspace.xml
  8 +/.idea/navEditor.xml
  9 +/.idea/assetWizardSettings.xml
  10 +.DS_Store
  11 +/build
  12 +/captures
  13 +.externalNativeBuild
  14 +.cxx
  15 +/gradlew
  16 +/gradle.properties
  17 +/gradlew.bat
  18 +/.idea/
... ...
app/.gitignore 0 → 100644
  1 +++ a/app/.gitignore
  1 +/build
0 2 \ No newline at end of file
... ...
app/build.gradle 0 → 100644
  1 +++ a/app/build.gradle
  1 +apply plugin: 'com.android.application'
  2 +
  3 +android {
  4 + compileSdkVersion 29
  5 +
  6 + defaultConfig {
  7 + applicationId "com.cnlive.demo"
  8 + minSdkVersion 19
  9 + targetSdkVersion 29
  10 + versionCode 1
  11 + versionName "1.0"
  12 + multiDexEnabled true
  13 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  14 + ndk {
  15 + abiFilters 'armeabi-v7a'
  16 + }
  17 + }
  18 +
  19 + buildTypes {
  20 + release {
  21 + minifyEnabled false
  22 + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  23 + }
  24 + }
  25 + dataBinding {
  26 + enabled true
  27 + }
  28 +
  29 + compileOptions {
  30 + sourceCompatibility JavaVersion.VERSION_1_8
  31 + targetCompatibility JavaVersion.VERSION_1_8
  32 + }
  33 +}
  34 +
  35 +dependencies {
  36 + implementation fileTree(dir: "libs", include: ["*.jar"])
  37 + implementation 'androidx.appcompat:appcompat:1.2.0'
  38 + implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
  39 +// implementation project(path: ':lib_media')
  40 + //ARouter
  41 +// implementation "com.alibaba:arouter-api:$rootProject.arouterApiVersion"
  42 +// annotationProcessor "com.alibaba:arouter-compiler:$rootProject.arouterCompilerVersion"
  43 + implementation 'androidx.multidex:multidex:2.0.0'
  44 + implementation project(path: ':lib_media')
  45 +
  46 +}
0 47 \ No newline at end of file
... ...
app/proguard-rules.pro 0 → 100644
  1 +++ a/app/proguard-rules.pro
  1 +# Add project specific ProGuard rules here.
  2 +# You can control the set of applied configuration files using the
  3 +# proguardFiles setting in build.gradle.
  4 +#
  5 +# For more details, see
  6 +# http://developer.android.com/guide/developing/tools/proguard.html
  7 +
  8 +# If your project uses WebView with JS, uncomment the following
  9 +# and specify the fully qualified class name to the JavaScript interface
  10 +# class:
  11 +#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
  12 +# public *;
  13 +#}
  14 +
  15 +# Uncomment this to preserve the line number information for
  16 +# debugging stack traces.
  17 +#-keepattributes SourceFile,LineNumberTable
  18 +
  19 +# If you keep the line number information, uncomment this to
  20 +# hide the original source file name.
  21 +#-renamesourcefileattribute SourceFile
0 22 \ No newline at end of file
... ...
app/src/main/AndroidManifest.xml 0 → 100644
  1 +++ a/app/src/main/AndroidManifest.xml
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3 + package="com.cnlive.demo">
  4 +
  5 + <application
  6 +
  7 + android:allowBackup="true"
  8 + android:name="com.cnlive.demo.MediaApplication"
  9 + android:icon="@mipmap/ic_launcher"
  10 + android:label="@string/app_name"
  11 + android:roundIcon="@mipmap/ic_launcher_round"
  12 + android:supportsRtl="true"
  13 + android:theme="@style/AppTheme">
  14 + <meta-data android:name="android.max_aspect"
  15 + android:value="ratio_float"/>
  16 + <activity android:name="com.cnlive.demo.MainActivity">
  17 + <intent-filter>
  18 + <action android:name="android.intent.action.MAIN" />
  19 +
  20 + <category android:name="android.intent.category.LAUNCHER" />
  21 + </intent-filter>
  22 + </activity>
  23 + </application>
  24 +
  25 +</manifest>
0 26 \ No newline at end of file
... ...
app/src/main/java/com/cnlive/demo/MainActivity.java 0 → 100644
  1 +++ a/app/src/main/java/com/cnlive/demo/MainActivity.java
  1 +package com.cnlive.demo;
  2 +
  3 +import androidx.annotation.Nullable;
  4 +import androidx.appcompat.app.AppCompatActivity;
  5 +import androidx.databinding.DataBindingUtil;
  6 +
  7 +import android.content.Intent;
  8 +import android.os.Build;
  9 +import android.os.Bundle;
  10 +import android.os.Environment;
  11 +import android.view.View;
  12 +
  13 +import com.cnlive.demo.databinding.ActivityMainBinding;
  14 +import com.cnlive.media.ImagePicker;
  15 +import com.cnlive.media.PickerConfig;
  16 +import com.cnlive.media.meidia.entity.Media;
  17 +import com.cnlive.media.utlis.GlideCacheUtil;
  18 +
  19 +import java.util.ArrayList;
  20 +
  21 +
  22 +public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  23 +
  24 + private ActivityMainBinding mainBinding;
  25 + private ArrayList<Media> select;
  26 +
  27 + @Override
  28 + protected void onCreate(Bundle savedInstanceState) {
  29 + super.onCreate(savedInstanceState);
  30 + mainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main);
  31 + mainBinding.setOnClick(this);
  32 + }
  33 +
  34 + @Override
  35 + public void onClick(View view) {
  36 + switch (view.getId()) {
  37 + case R.id.tv_camera:
  38 + //打开相机
  39 + new ImagePicker
  40 + .Builder()
  41 + .setJumpCameraMode(PickerConfig.CAMERA_MODE_ALL)
  42 + .builder()
  43 + .startCamera(this, select, PickerConfig.PICKER_IMAGE, PickerConfig.DEFAULT_RESULT_CODE);
  44 + break;
  45 + case R.id.bt_preview:
  46 + //打开预览
  47 + new ImagePicker.Builder()
  48 + .builder()
  49 + .startPreview(this, 0, select, PickerConfig.PICKER_IMAGE, PickerConfig.DEFAULT_RESULT_CODE);
  50 + break;
  51 + case R.id.tv_media:
  52 + //打开相册
  53 + new ImagePicker.Builder()
  54 + .setSelectGif(false)
  55 + .needCamera(false)
  56 + .maxNum(9)
  57 + .selectMode(PickerConfig.PICKER_IMAGE_VIDEO)
  58 + .maxVideoSize(100 * 1024 * 1024)
  59 + .maxImageSize(1 * 1024 * 1024)
  60 + .defaultSelectList(select)
  61 + .doCrop(1, 1, 900, 900)
  62 + .builder()
  63 + .start(this, PickerConfig.PICKER_IMAGE, PickerConfig.DEFAULT_RESULT_CODE);
  64 + break;
  65 + }
  66 + }
  67 +
  68 + @Override
  69 + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
  70 + super.onActivityResult(requestCode, resultCode, data);
  71 + if (resultCode == PickerConfig.DEFAULT_RESULT_CODE) {
  72 + select = data.getParcelableArrayListExtra(PickerConfig.EXTRA_RESULT);
  73 + GlideCacheUtil.intoItemImage(this, select.get(0), mainBinding.ivPre, null);
  74 + }
  75 +
  76 + }
  77 +}
0 78 \ No newline at end of file
... ...
app/src/main/java/com/cnlive/demo/MediaApplication.java 0 → 100644
  1 +++ a/app/src/main/java/com/cnlive/demo/MediaApplication.java
  1 +package com.cnlive.demo;
  2 +
  3 +import android.app.Application;
  4 +
  5 +import androidx.multidex.MultiDex;
  6 +
  7 +
  8 +//import com.alibaba.android.arouter.launcher.ARouter;
  9 +
  10 +
  11 +public class MediaApplication extends Application {
  12 + @Override
  13 + public void onCreate() {
  14 + super.onCreate();
  15 +// ARouter.init(this);
  16 + MultiDex.install(this);
  17 +// PLShortVideoEnv.init(this);
  18 + }
  19 +}
... ...
app/src/main/res/drawable-v24/ic_launcher_foreground.xml 0 → 100644
  1 +++ a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml
  1 +<vector xmlns:android="http://schemas.android.com/apk/res/android"
  2 + xmlns:aapt="http://schemas.android.com/aapt"
  3 + android:width="108dp"
  4 + android:height="108dp"
  5 + android:viewportWidth="108"
  6 + android:viewportHeight="108">
  7 + <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
  8 + <aapt:attr name="android:fillColor">
  9 + <gradient
  10 + android:endX="85.84757"
  11 + android:endY="92.4963"
  12 + android:startX="42.9492"
  13 + android:startY="49.59793"
  14 + android:type="linear">
  15 + <item
  16 + android:color="#44000000"
  17 + android:offset="0.0" />
  18 + <item
  19 + android:color="#00000000"
  20 + android:offset="1.0" />
  21 + </gradient>
  22 + </aapt:attr>
  23 + </path>
  24 + <path
  25 + android:fillColor="#FFFFFF"
  26 + android:fillType="nonZero"
  27 + android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
  28 + android:strokeWidth="1"
  29 + android:strokeColor="#00000000" />
  30 +</vector>
0 31 \ No newline at end of file
... ...
app/src/main/res/drawable/ic_launcher_background.xml 0 → 100644
  1 +++ a/app/src/main/res/drawable/ic_launcher_background.xml
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<vector xmlns:android="http://schemas.android.com/apk/res/android"
  3 + android:width="108dp"
  4 + android:height="108dp"
  5 + android:viewportWidth="108"
  6 + android:viewportHeight="108">
  7 + <path
  8 + android:fillColor="#3DDC84"
  9 + android:pathData="M0,0h108v108h-108z" />
  10 + <path
  11 + android:fillColor="#00000000"
  12 + android:pathData="M9,0L9,108"
  13 + android:strokeWidth="0.8"
  14 + android:strokeColor="#33FFFFFF" />
  15 + <path
  16 + android:fillColor="#00000000"
  17 + android:pathData="M19,0L19,108"
  18 + android:strokeWidth="0.8"
  19 + android:strokeColor="#33FFFFFF" />
  20 + <path
  21 + android:fillColor="#00000000"
  22 + android:pathData="M29,0L29,108"
  23 + android:strokeWidth="0.8"
  24 + android:strokeColor="#33FFFFFF" />
  25 + <path
  26 + android:fillColor="#00000000"
  27 + android:pathData="M39,0L39,108"
  28 + android:strokeWidth="0.8"
  29 + android:strokeColor="#33FFFFFF" />
  30 + <path
  31 + android:fillColor="#00000000"
  32 + android:pathData="M49,0L49,108"
  33 + android:strokeWidth="0.8"
  34 + android:strokeColor="#33FFFFFF" />
  35 + <path
  36 + android:fillColor="#00000000"
  37 + android:pathData="M59,0L59,108"
  38 + android:strokeWidth="0.8"
  39 + android:strokeColor="#33FFFFFF" />
  40 + <path
  41 + android:fillColor="#00000000"
  42 + android:pathData="M69,0L69,108"
  43 + android:strokeWidth="0.8"
  44 + android:strokeColor="#33FFFFFF" />
  45 + <path
  46 + android:fillColor="#00000000"
  47 + android:pathData="M79,0L79,108"
  48 + android:strokeWidth="0.8"
  49 + android:strokeColor="#33FFFFFF" />
  50 + <path
  51 + android:fillColor="#00000000"
  52 + android:pathData="M89,0L89,108"
  53 + android:strokeWidth="0.8"
  54 + android:strokeColor="#33FFFFFF" />
  55 + <path
  56 + android:fillColor="#00000000"
  57 + android:pathData="M99,0L99,108"
  58 + android:strokeWidth="0.8"
  59 + android:strokeColor="#33FFFFFF" />
  60 + <path
  61 + android:fillColor="#00000000"
  62 + android:pathData="M0,9L108,9"
  63 + android:strokeWidth="0.8"
  64 + android:strokeColor="#33FFFFFF" />
  65 + <path
  66 + android:fillColor="#00000000"
  67 + android:pathData="M0,19L108,19"
  68 + android:strokeWidth="0.8"
  69 + android:strokeColor="#33FFFFFF" />
  70 + <path
  71 + android:fillColor="#00000000"
  72 + android:pathData="M0,29L108,29"
  73 + android:strokeWidth="0.8"
  74 + android:strokeColor="#33FFFFFF" />
  75 + <path
  76 + android:fillColor="#00000000"
  77 + android:pathData="M0,39L108,39"
  78 + android:strokeWidth="0.8"
  79 + android:strokeColor="#33FFFFFF" />
  80 + <path
  81 + android:fillColor="#00000000"
  82 + android:pathData="M0,49L108,49"
  83 + android:strokeWidth="0.8"
  84 + android:strokeColor="#33FFFFFF" />
  85 + <path
  86 + android:fillColor="#00000000"
  87 + android:pathData="M0,59L108,59"
  88 + android:strokeWidth="0.8"
  89 + android:strokeColor="#33FFFFFF" />
  90 + <path
  91 + android:fillColor="#00000000"
  92 + android:pathData="M0,69L108,69"
  93 + android:strokeWidth="0.8"
  94 + android:strokeColor="#33FFFFFF" />
  95 + <path
  96 + android:fillColor="#00000000"
  97 + android:pathData="M0,79L108,79"
  98 + android:strokeWidth="0.8"
  99 + android:strokeColor="#33FFFFFF" />
  100 + <path
  101 + android:fillColor="#00000000"
  102 + android:pathData="M0,89L108,89"
  103 + android:strokeWidth="0.8"
  104 + android:strokeColor="#33FFFFFF" />
  105 + <path
  106 + android:fillColor="#00000000"
  107 + android:pathData="M0,99L108,99"
  108 + android:strokeWidth="0.8"
  109 + android:strokeColor="#33FFFFFF" />
  110 + <path
  111 + android:fillColor="#00000000"
  112 + android:pathData="M19,29L89,29"
  113 + android:strokeWidth="0.8"
  114 + android:strokeColor="#33FFFFFF" />
  115 + <path
  116 + android:fillColor="#00000000"
  117 + android:pathData="M19,39L89,39"
  118 + android:strokeWidth="0.8"
  119 + android:strokeColor="#33FFFFFF" />
  120 + <path
  121 + android:fillColor="#00000000"
  122 + android:pathData="M19,49L89,49"
  123 + android:strokeWidth="0.8"
  124 + android:strokeColor="#33FFFFFF" />
  125 + <path
  126 + android:fillColor="#00000000"
  127 + android:pathData="M19,59L89,59"
  128 + android:strokeWidth="0.8"
  129 + android:strokeColor="#33FFFFFF" />
  130 + <path
  131 + android:fillColor="#00000000"
  132 + android:pathData="M19,69L89,69"
  133 + android:strokeWidth="0.8"
  134 + android:strokeColor="#33FFFFFF" />
  135 + <path
  136 + android:fillColor="#00000000"
  137 + android:pathData="M19,79L89,79"
  138 + android:strokeWidth="0.8"
  139 + android:strokeColor="#33FFFFFF" />
  140 + <path
  141 + android:fillColor="#00000000"
  142 + android:pathData="M29,19L29,89"
  143 + android:strokeWidth="0.8"
  144 + android:strokeColor="#33FFFFFF" />
  145 + <path
  146 + android:fillColor="#00000000"
  147 + android:pathData="M39,19L39,89"
  148 + android:strokeWidth="0.8"
  149 + android:strokeColor="#33FFFFFF" />
  150 + <path
  151 + android:fillColor="#00000000"
  152 + android:pathData="M49,19L49,89"
  153 + android:strokeWidth="0.8"
  154 + android:strokeColor="#33FFFFFF" />
  155 + <path
  156 + android:fillColor="#00000000"
  157 + android:pathData="M59,19L59,89"
  158 + android:strokeWidth="0.8"
  159 + android:strokeColor="#33FFFFFF" />
  160 + <path
  161 + android:fillColor="#00000000"
  162 + android:pathData="M69,19L69,89"
  163 + android:strokeWidth="0.8"
  164 + android:strokeColor="#33FFFFFF" />
  165 + <path
  166 + android:fillColor="#00000000"
  167 + android:pathData="M79,19L79,89"
  168 + android:strokeWidth="0.8"
  169 + android:strokeColor="#33FFFFFF" />
  170 +</vector>
... ...
app/src/main/res/layout/activity_main.xml 0 → 100644
  1 +++ a/app/src/main/res/layout/activity_main.xml
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<layout>
  3 +
  4 + <data>
  5 +
  6 + <import type="android.view.View.OnClickListener" />
  7 +
  8 + <variable
  9 + name="onClick"
  10 + type="OnClickListener" />
  11 + </data>
  12 +
  13 + <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  14 + xmlns:app="http://schemas.android.com/apk/res-auto"
  15 + xmlns:tools="http://schemas.android.com/tools"
  16 + android:layout_width="match_parent"
  17 + android:layout_height="match_parent"
  18 + android:orientation="vertical">
  19 +
  20 + <Button
  21 + android:id="@+id/tv_media"
  22 + android:layout_width="wrap_content"
  23 + android:layout_height="wrap_content"
  24 + android:layout_marginTop="30dp"
  25 + android:onClick="@{onClick}"
  26 + android:text="打开相册" />
  27 +
  28 + <Button
  29 + android:id="@+id/tv_camera"
  30 + android:layout_width="wrap_content"
  31 + android:layout_height="wrap_content"
  32 + android:layout_marginTop="30dp"
  33 + android:onClick="@{onClick}"
  34 + android:text="打开相机" />
  35 + <Button
  36 + android:id="@+id/bt_preview"
  37 + android:layout_width="wrap_content"
  38 + android:layout_height="wrap_content"
  39 + android:layout_marginTop="30dp"
  40 + android:onClick="@{onClick}"
  41 + android:text="打开预览" />
  42 +
  43 + <ImageView
  44 + android:id="@+id/iv_pre"
  45 + android:layout_width="wrap_content"
  46 + android:layout_height="wrap_content"/>
  47 +
  48 +
  49 + </LinearLayout>
  50 +
  51 +</layout>
0 52 \ No newline at end of file
... ...
app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml 0 → 100644
  1 +++ a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <background android:drawable="@drawable/ic_launcher_background" />
  4 + <foreground android:drawable="@drawable/ic_launcher_foreground" />
  5 +</adaptive-icon>
0 6 \ No newline at end of file
... ...
app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml 0 → 100644
  1 +++ a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
  3 + <background android:drawable="@drawable/ic_launcher_background" />
  4 + <foreground android:drawable="@drawable/ic_launcher_foreground" />
  5 +</adaptive-icon>
0 6 \ No newline at end of file
... ...
app/src/main/res/mipmap-hdpi/ic_launcher.png 0 → 100644

3.51 KB

app/src/main/res/mipmap-hdpi/ic_launcher_round.png 0 → 100644

5.21 KB

app/src/main/res/mipmap-mdpi/ic_launcher.png 0 → 100644

2.57 KB

app/src/main/res/mipmap-mdpi/ic_launcher_round.png 0 → 100644

3.31 KB

app/src/main/res/mipmap-xhdpi/ic_launcher.png 0 → 100644

4.81 KB

app/src/main/res/mipmap-xhdpi/ic_launcher_round.png 0 → 100644

7.3 KB

app/src/main/res/mipmap-xxhdpi/ic_launcher.png 0 → 100644

7.72 KB

app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png 0 → 100644

11.6 KB

app/src/main/res/mipmap-xxxhdpi/ic_launcher.png 0 → 100644

10.4 KB

app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png 0 → 100644

16.2 KB

app/src/main/res/values/colors.xml 0 → 100644
  1 +++ a/app/src/main/res/values/colors.xml
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <color name="colorPrimary">#6200EE</color>
  4 + <color name="colorPrimaryDark">#3700B3</color>
  5 + <color name="colorAccent">#03DAC5</color>
  6 +</resources>
0 7 \ No newline at end of file
... ...
app/src/main/res/values/strings.xml 0 → 100644
  1 +++ a/app/src/main/res/values/strings.xml
  1 +<resources>
  2 + <string name="app_name">Media Picker</string>
  3 +</resources>
0 4 \ No newline at end of file
... ...
app/src/main/res/values/styles.xml 0 → 100644
  1 +++ a/app/src/main/res/values/styles.xml
  1 +<resources>
  2 + <!-- Base application theme. -->
  3 + <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  4 + <!-- Customize your theme here. -->
  5 + <item name="colorPrimary">@color/colorPrimary</item>
  6 + <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
  7 + <item name="colorAccent">@color/colorAccent</item>
  8 + </style>
  9 +
  10 +</resources>
0 11 \ No newline at end of file
... ...
app/src/main/res/xml/file_paths.xml 0 → 100644
  1 +++ a/app/src/main/res/xml/file_paths.xml
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <paths>
  4 + <external-path path="" name="camera_photos" />
  5 + </paths>
  6 +</resources>
0 7 \ No newline at end of file
... ...
build.gradle 0 → 100644
  1 +++ a/build.gradle
  1 +// Top-level build file where you can add configuration options common to all sub-projects/modules.
  2 +apply from: "config.gradle"
  3 +buildscript {
  4 + repositories {
  5 + google()
  6 + jcenter()
  7 + maven { url 'https://dl.bintray.com/umsdk/release' }
  8 + }
  9 + dependencies {
  10 + classpath 'com.android.tools.build:gradle:3.5.0'
  11 +
  12 + // NOTE: Do not place your application dependencies here; they belong
  13 + // in the individual module build.gradle files
  14 + }
  15 +}
  16 +
  17 +allprojects {
  18 + repositories {
  19 + google()
  20 + jcenter()
  21 + //------------------ 资源库配置 ------------------
  22 + maven {
  23 + url maven.mavenMixedUrl
  24 + credentials { username = nexusId;password = nexusPw }
  25 + }
  26 + //------------------ 资源库配置 END------------------
  27 + maven {
  28 + url "https://jitpack.io"
  29 + }
  30 + maven {
  31 + url 'https://dl.bintray.com/granzon/cnlive'
  32 + }
  33 + maven {
  34 + url 'https://dl.bintray.com/granzon/cnliveLibs'
  35 + }
  36 + maven { url 'https://dl.bintray.com/umsdk/release' }
  37 + }
  38 +}
  39 +
  40 +task clean(type: Delete) {
  41 + delete rootProject.buildDir
  42 +}
  43 +
  44 +ext {
  45 + //androidX
  46 +
  47 + androidXAppcompat = '1.2.0'
  48 + androidXRecyclerview = '1.0.0'
  49 + androidXConstraintlayout = '1.1.3'
  50 +
  51 + androidX_legacy_support_v4 = '1.0.0'
  52 +
  53 + glide = '4.11.0'
  54 + glideTransformations = '4.1.0'
  55 + compiler = '4.11.0'
  56 +
  57 + easypermissions = '3.0.0'
  58 + rotatephotoview = '1.0.5'
  59 +
  60 + libCnUtil = '3.1.0'
  61 + libCnVideo = '3.2.3'
  62 +
  63 + qmui = '1.1.5'
  64 +
  65 + libLargeImage = '1.0.4-androidx'
  66 + libBase = '1.9.3.2-androidx'
  67 + libVideoQiniu = '1.0.7.2'
  68 +
  69 + //阿里路由框架
  70 + arouterApiVersion = '1.5.0'
  71 + arouterCompilerVersion = '1.2.1'
  72 +
  73 + libCnUtil = '3.1.5'
  74 + libCnVideo = '3.3.24'
  75 + libCnencipher = '1.1.1'
  76 +
  77 +
  78 + //视频库
  79 + libVideoQiniu = '1.0.7-androidx'
  80 + qiniuAndroidSdk = '7.4.3'
  81 +}
0 82 \ No newline at end of file
... ...
config.gradle 0 → 100644
  1 +++ a/config.gradle
  1 +ext {
  2 + //Nexus 访问账号
  3 + nexusId = "developer"
  4 + nexusPw = "android_2019"
  5 +
  6 + //Nexus 发布配置
  7 + maven = [
  8 + //发布版地址(暂未使用)
  9 + mavenUrl : "http://android.nexus.cnlive.com/repository/cnlive/",
  10 + //快照版地址(暂未使用)
  11 + mavenDevUrl : "http://android.nexus.cnlive.com/repository/cnlive-snapshot/",
  12 + //混合版地址
  13 + mavenMixedUrl : "http://android.nexus.cnlive.com/repository/cnlive-mixed/",
  14 + //发布账号(单独分配)
  15 + mavenUserName: "developer",
  16 + mavenPwd : "android_2019"
  17 + ]
  18 +
  19 + //Maven Base库配置
  20 + lib_mediapicker = [
  21 + //编译方式
  22 + debug : false,
  23 + //版本号
  24 + version: "1.0.1.5",
  25 + //Lib库前缀
  26 + packeg : "com.cnlive.media",
  27 + //Lib库名称
  28 + name : "NewMediaPicker"
  29 + ]
  30 +}
0 31 \ No newline at end of file
... ...
lib_media/.gitignore 0 → 100644
  1 +++ a/lib_media/.gitignore
  1 +/build
0 2 \ No newline at end of file
... ...
lib_media/build.gradle 0 → 100644
  1 +++ a/lib_media/build.gradle
  1 +apply plugin: 'com.android.library'
  2 +apply from: './maven_push.gradle'
  3 +//
  4 +android {
  5 + compileSdkVersion 29
  6 +
  7 + defaultConfig {
  8 + minSdkVersion 19
  9 + targetSdkVersion 29
  10 + versionCode 1
  11 + versionName "1.0"
  12 + multiDexEnabled true
  13 +// ndk {
  14 +// abiFilters 'armeabi-v7a'
  15 +// }
  16 +
  17 + javaCompileOptions {
  18 + annotationProcessorOptions {
  19 + arguments = [AROUTER_MODULE_NAME: project.getName(), AROUTER_GENERATE_DOC: "enable"]
  20 + }
  21 + }
  22 + }
  23 +
  24 + compileOptions {
  25 + sourceCompatibility JavaVersion.VERSION_1_8
  26 + targetCompatibility JavaVersion.VERSION_1_8
  27 + }
  28 +
  29 + dataBinding {
  30 + enabled true
  31 + }
  32 + dexOptions {
  33 + javaMaxHeapSize '4g'
  34 + }
  35 +}
  36 +
  37 +dependencies {
  38 + implementation fileTree(dir: "libs", include: ["*.jar"])
  39 + //androidX
  40 + implementation "androidx.legacy:legacy-support-v4:$rootProject.androidX_legacy_support_v4"
  41 + implementation "androidx.appcompat:appcompat:$rootProject.androidXAppcompat"
  42 + implementation "androidx.recyclerview:recyclerview:$rootProject.androidXRecyclerview"
  43 + implementation "androidx.constraintlayout:constraintlayout:$rootProject.androidXConstraintlayout"
  44 + implementation 'androidx.viewpager2:viewpager2:1.0.0'
  45 + //glide
  46 + implementation "com.github.bumptech.glide:glide:$rootProject.glide"
  47 + implementation "jp.wasabeef:glide-transformations:$rootProject.glideTransformations"
  48 + annotationProcessor "com.github.bumptech.glide:compiler:$rootProject.compiler"
  49 +
  50 + //视讯云SDK
  51 + implementation "com.qmuiteam:qmui:$rootProject.qmui"
  52 +
  53 + implementation "com.cnlive.libs:base:$rootProject.libBase"
  54 + implementation 'com.github.chrisbanes:PhotoView:2.1.4'
  55 +
  56 + //ARouter
  57 + implementation "com.alibaba:arouter-api:$rootProject.arouterApiVersion"
  58 + annotationProcessor "com.alibaba:arouter-compiler:$rootProject.arouterCompilerVersion"
  59 + //七牛录制视频
  60 + implementation "com.cnlive.libs:video_qiniu:$rootProject.libVideoQiniu"
  61 + implementation "com.qiniu:qiniu-android-sdk:$rootProject.qiniuAndroidSdk"
  62 +
  63 + implementation "com.cnlive:lib_cnutil:$rootProject.libCnUtil"
  64 + implementation "com.cnlive:lib_cnvideo2.0:$rootProject.libCnVideo"
  65 +
  66 + implementation "com.umeng.umsdk:analytics:8.0.0"
  67 + implementation "com.umeng.umsdk:common:2.0.0"
  68 +
  69 +}
0 70 \ No newline at end of file
... ...
lib_media/consumer-rules.pro 0 → 100644
  1 +++ a/lib_media/consumer-rules.pro
... ...
lib_media/maven_push.gradle 0 → 100644
  1 +++ a/lib_media/maven_push.gradle
  1 +apply plugin: 'maven'
  2 +
  3 +uploadArchives() {
  4 + repositories {
  5 + mavenDeployer {
  6 + def lib = lib_mediapicker
  7 + //发布环境(正式/测试)
  8 + android.defaultPublishConfig lib.debug ? "debug" : "release"
  9 + //发布渠道(地址/账号)
  10 + repository(url: maven.mavenMixedUrl) {
  11 + authentication(userName: maven.mavenUserName, password: maven.mavenPwd)
  12 + }
  13 + //发布信息(包名/别名/版本)
  14 + pom.project {
  15 + groupId lib.packeg
  16 + artifactId lib.name
  17 + version = lib.debug ? lib.version.concat("-SNAPSHOT") : lib.version
  18 + }
  19 + pom.whenConfigured { pom ->
  20 + //TODO POM文件目前无法区分 compile 和 implementation
  21 + List list = new ArrayList()
  22 + //手动增加过滤项
  23 + pom.dependencies.findAll {
  24 + dep -> dep.groupId == "pub.devrel" || dep.groupId == "com.chensl.rotatephotoview"
  25 + }.collect { dep -> list.add(dep) }
  26 + //移除支持库
  27 + pom.dependencies.clear()
  28 + pom.dependencies.addAll(list)
  29 + }
  30 +
  31 + }
  32 + }
  33 +}
0 34 \ No newline at end of file
... ...
lib_media/proguard-rules.pro 0 → 100644
  1 +++ a/lib_media/proguard-rules.pro
  1 +# Add project specific ProGuard rules here.
  2 +# You can control the set of applied configuration files using the
  3 +# proguardFiles setting in build.gradle.
  4 +#
  5 +# For more details, see
  6 +# http://developer.android.com/guide/developing/tools/proguard.html
  7 +
  8 +# If your project uses WebView with JS, uncomment the following
  9 +# and specify the fully qualified class name to the JavaScript interface
  10 +# class:
  11 +#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
  12 +# public *;
  13 +#}
  14 +
  15 +# Uncomment this to preserve the line number information for
  16 +# debugging stack traces.
  17 +#-keepattributes SourceFile,LineNumberTable
  18 +
  19 +# If you keep the line number information, uncomment this to
  20 +# hide the original source file name.
  21 +#-renamesourcefileattribute SourceFile
0 22 \ No newline at end of file
... ...
lib_media/src/main/AndroidManifest.xml 0 → 100644
  1 +++ a/lib_media/src/main/AndroidManifest.xml
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + package="com.cnlive.meidia">
  3 +
  4 + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  5 + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  6 + <uses-permission android:name="android.permission.RECORD_AUDIO" />
  7 + <uses-permission android:name="android.permission.CAMERA" />
  8 + <uses-permission android:name="android.permission.FLASHLIGHT" />
  9 + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  10 + <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
  11 + <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />
  12 + <uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
  13 + <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />
  14 +
  15 + <uses-feature android:name="android.hardware.camera" />
  16 + <uses-feature android:name="android.hardware.camera.autofocus" />
  17 + <application
  18 + android:resizeableActivity="true"
  19 + android:largeHeap="true">
  20 + <activity
  21 + android:name="com.cnlive.media.ui.activity.MediaActivity"
  22 + android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
  23 + android:launchMode="singleTop"
  24 + android:screenOrientation="portrait"
  25 + android:theme="@style/Theme.AppCompat.NoActionBar"
  26 + android:windowSoftInputMode="stateAlwaysHidden" />
  27 + <activity
  28 + android:name="com.cnlive.media.ui.activity.RecordActivity"
  29 + android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
  30 + android:launchMode="singleTop"
  31 + android:screenOrientation="portrait"
  32 + android:theme="@style/FullActivityThemeStyle"
  33 + android:windowSoftInputMode="stateAlwaysHidden" />
  34 + <activity
  35 + android:name="com.cnlive.media.ui.activity.ImageCropActivity"
  36 + android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
  37 + android:launchMode="singleTop"
  38 + android:screenOrientation="portrait"
  39 + android:theme="@style/FullActivityThemeStyle"
  40 + android:windowSoftInputMode="stateAlwaysHidden" />
  41 +
  42 + <activity
  43 + android:name="com.cnlive.media.ui.activity.VideoPlayerActivity"
  44 + android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
  45 + android:launchMode="singleTop"
  46 + android:screenOrientation="portrait"
  47 + android:theme="@style/FullActivityThemeStyle"
  48 + android:windowSoftInputMode="stateAlwaysHidden" />
  49 + <activity
  50 + android:name="com.cnlive.media.ui.activity.MediaPreviewActivity"
  51 + android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout"
  52 + android:launchMode="singleTop"
  53 + android:screenOrientation="portrait"
  54 + android:theme="@style/Theme.AppCompat.NoActionBar"
  55 + android:windowSoftInputMode="stateAlwaysHidden" />
  56 +
  57 + </application>
  58 +</manifest>
0 59 \ No newline at end of file
... ...
lib_media/src/main/java/com/cnlive/media/ImagePicker.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/ImagePicker.java
  1 +package com.cnlive.media;
  2 +
  3 +import android.app.Activity;
  4 +import android.app.Fragment;
  5 +import android.content.Context;
  6 +import android.content.Intent;
  7 +
  8 +import com.cnlive.media.model.ImagePickerCropParams;
  9 +import com.cnlive.media.model.ImagePickerOptions;
  10 +import com.cnlive.media.meidia.entity.Media;
  11 +import com.cnlive.media.ui.activity.MediaActivity;
  12 +import com.cnlive.media.ui.activity.MediaPreviewActivity;
  13 +import com.cnlive.media.ui.activity.RecordActivity;
  14 +
  15 +import java.util.ArrayList;
  16 +import java.util.List;
  17 +
  18 +/**
  19 + *
  20 + */
  21 +
  22 +public class ImagePicker {
  23 +
  24 + /**
  25 + * 作 者 : wkq
  26 + * <p>
  27 + * 时 间 : 2020/9/15 11:26
  28 + * <p>
  29 + * 名 字 : ImagePicker
  30 + * <p>
  31 + * 简 介 : 媒体选择的启动器
  32 + */
  33 + public static final int DEF_RESULT_CODE = 136;
  34 +
  35 + private ImagePickerOptions mOptions;
  36 +
  37 + public ImagePickerOptions getOptions() {
  38 + return mOptions;
  39 + }
  40 +
  41 + private ImagePicker() {
  42 +
  43 + }
  44 +
  45 + private ImagePicker(ImagePickerOptions options) {
  46 + this.mOptions = options;
  47 + }
  48 +
  49 + /**
  50 + * 图片选择
  51 + *
  52 + * @param activity
  53 + * @param requestCode 请求码
  54 + * @param resultCode 结果码
  55 + */
  56 + public void start(Activity activity, int requestCode, int resultCode) {
  57 + Intent intent = new Intent(activity, MediaActivity.class);
  58 + intent.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions);
  59 + intent.putParcelableArrayListExtra(PickerConfig.DEFAULT_SELECTED_LIST, mOptions.selects);
  60 + intent.putExtra(PickerConfig.RESULT_CODE, resultCode);
  61 + activity.startActivityForResult(intent, requestCode);
  62 + }
  63 +
  64 +
  65 + /**
  66 + * 图片选择
  67 + *
  68 + * @param activity
  69 + * @param requestCode 请求码
  70 + * @param resultCode 结果码
  71 + */
  72 + public void startCamera(Activity activity, int requestCode, int resultCode) {
  73 + Intent intent = new Intent(activity, RecordActivity.class);
  74 + intent.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions);
  75 + intent.putExtra(PickerConfig.RESULT_CODE, resultCode);
  76 + intent.putExtra(PickerConfig.WHERE_JUMP_CAMERA, true);
  77 + activity.startActivityForResult(intent, requestCode);
  78 + }
  79 +
  80 + /**
  81 + * 图片选择
  82 + *
  83 + * @param activity
  84 + * @param requestCode 请求码
  85 + * @param resultCode 结果码
  86 + */
  87 + public void startCamera(Activity activity, ArrayList<Media> selectMedia,int requestCode, int resultCode) {
  88 + if (selectMedia==null)selectMedia=new ArrayList<>();
  89 + Intent intent = new Intent(activity, RecordActivity.class);
  90 + intent.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions);
  91 + intent.putExtra(PickerConfig.RESULT_CODE, resultCode);
  92 + intent.putExtra(PickerConfig.WHERE_JUMP_CAMERA, true);
  93 + intent.putParcelableArrayListExtra(PickerConfig.WHERE_JUMP_CAMERA_SELECTS, selectMedia);
  94 + activity.startActivityForResult(intent, requestCode);
  95 + }
  96 +
  97 + /**
  98 + * 图片选择
  99 + *
  100 + * @param fragment
  101 + * @param requestCode 请求码
  102 + * @param resultCode 结果码
  103 + */
  104 + public void start(Fragment fragment, int requestCode, int resultCode) {
  105 + Intent intent = new Intent(fragment.getActivity(), MediaActivity.class);
  106 + intent.putExtra(PickerConfig.INTENT_KEY_OPTIONS, mOptions);
  107 + intent.putParcelableArrayListExtra(PickerConfig.DEFAULT_SELECTED_LIST, mOptions.selects); // (Optional)
  108 + intent.putExtra(PickerConfig.RESULT_CODE, resultCode);
  109 + fragment.getActivity().startActivityForResult(intent, requestCode);
  110 + }
  111 +
  112 + public void startPreview(Activity activity, int position, ArrayList<Media> selects, int requestCode, int resultCode) {
  113 +
  114 + Intent intent = new Intent(activity, MediaPreviewActivity.class);
  115 + intent.putParcelableArrayListExtra(PickerConfig.SELECTED_LIST, selects);
  116 + intent.putExtra(PickerConfig.CURRENT_POSITION, position);
  117 + intent.putExtra(PickerConfig.RESULT_CODE, resultCode);
  118 + activity.startActivityForResult(intent, requestCode);
  119 + }
  120 +
  121 + public static final class Builder {
  122 + private ImagePickerOptions mOptions;
  123 +
  124 + public Builder() {
  125 + mOptions = new ImagePickerOptions();
  126 + }
  127 +
  128 + public Builder selectMode(int selectMode) {
  129 + mOptions.setSelectMode(selectMode);
  130 + return this;
  131 + }
  132 +
  133 + public Builder isReturnUri(boolean isReturnUri) {
  134 + mOptions.setReturnUri(isReturnUri);
  135 + return this;
  136 + }
  137 +
  138 + public Builder maxVideoSize(int maxSize) {
  139 + mOptions.setMaxVideoSize(maxSize);
  140 + return this;
  141 + }
  142 +
  143 + public Builder maxImageSize(int maxImageSize) {
  144 + mOptions.setMaxImageSize(maxImageSize);
  145 + return this;
  146 + }
  147 +
  148 + public Builder showTime(boolean showTime) {
  149 + mOptions.setShowTime(showTime);
  150 + return this;
  151 + }
  152 +
  153 + public Builder setSelectGif(boolean selectGif) {
  154 + mOptions.setSelectGif(selectGif);
  155 + return this;
  156 + }
  157 +
  158 + public Builder setJumpCameraMode(int cameraMode) {
  159 + mOptions.setJumpCameraMode(cameraMode);
  160 + return this;
  161 + }
  162 +
  163 + public Builder maxTime(int maxTime) {
  164 + mOptions.setMaxTime(maxTime);
  165 + return this;
  166 + }
  167 +
  168 + public Builder maxNum(int maxNum) {
  169 + mOptions.setMaxNum(maxNum);
  170 + return this;
  171 + }
  172 +
  173 + public Builder needCamera(boolean needCamera) {
  174 + mOptions.setNeedCamera(needCamera);
  175 + return this;
  176 + }
  177 +
  178 + public Builder defaultSelectList(ArrayList<Media> select) {
  179 + mOptions.setSelects(select);
  180 + return this;
  181 + }
  182 +
  183 + public Builder cachePath(String cachePath) {
  184 + mOptions.setCachePath(cachePath);
  185 + return this;
  186 + }
  187 +
  188 +// public Builder videoTrimPath(String videoTrimPath) {
  189 +// mOptions.setVideoTrimPath(videoTrimPath);
  190 +// return this;
  191 +// }
  192 +
  193 + public Builder isFriendCircle(boolean isFriendCircle) {
  194 + mOptions.setFriendCircle(isFriendCircle);
  195 + return this;
  196 + }
  197 +
  198 + public Builder doCrop(ImagePickerCropParams cropParams) {
  199 + mOptions.setNeedCrop(cropParams != null);
  200 + mOptions.setCropParams(cropParams);
  201 + return this;
  202 + }
  203 +
  204 + public Builder doCrop(int aspectX, int aspectY, int outputX, int outputY) {
  205 + mOptions.setNeedCrop(true);
  206 + mOptions.setCropParams(new ImagePickerCropParams(aspectX, aspectY, outputX, outputY));
  207 + return this;
  208 + }
  209 +
  210 + public Builder isSinglePick(boolean isSinglePick) {
  211 + mOptions.setSinglePick(isSinglePick);
  212 + return this;
  213 + }
  214 +
  215 + public ImagePicker builder() {
  216 + return new ImagePicker(mOptions);
  217 + }
  218 + }
  219 +}
... ...
lib_media/src/main/java/com/cnlive/media/PickerConfig.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/PickerConfig.java
  1 +package com.cnlive.media;
  2 +
  3 +/**
  4 + * Created by dmcBig on 2017/6/9.
  5 + */
  6 +
  7 +public class PickerConfig {
  8 +
  9 +
  10 + //视频文件最大时长
  11 + public static final String MAX_TIME = "max_time";
  12 + // 默认视频时长
  13 + public static final int DEFAULT_MAX_TIME = 60 * 1000;
  14 +
  15 + // 默认视频时长
  16 + public static final int DEFAULT_MAX_VIDEO_TIME = 600 * 1000;
  17 + //界面跳转options的键值
  18 + public static final String INTENT_KEY_OPTIONS = "options";
  19 + //图片选择模式,默认选视频和图片
  20 + public static final String SELECT_MODE = "select_mode";
  21 + //选择结果,返回为 ArrayList&lt;String&gt; 图片路径集合
  22 + public static final String EXTRA_RESULT = "select_result";
  23 + //默认选择集
  24 + public static final String DEFAULT_SELECTED_LIST = "default_list";
  25 + public static final String MEDIA_TYPE = "mediaType";
  26 + //已选择的媒体预览集
  27 + public static final String SELECTED_LIST = "selected_list";
  28 + //跳转到预览页面指定的viewpager页面
  29 + public static final String CURRENT_POSITION = "current_position";
  30 + //传递待裁剪图片路径的key
  31 + public static final String INTENT_KEY_ORIGIN_PATH = "originPath";
  32 + //结果的Code
  33 + public static final String RESULT_CODE = "result_code";
  34 + public static final int DEFAULT_RESULT_CODE = 19901026;
  35 + //图片类型
  36 + public static final int PICKER_IMAGE = 100;
  37 + //视频类型
  38 + public static final int PICKER_VIDEO = 102;
  39 + //图片视频类型
  40 + public static final int PICKER_IMAGE_VIDEO = 101;
  41 + //只能选择一种类型
  42 + public static final int PICKER_ONLY_ONE_TYPE = 103;
  43 + //展示图片的列数行数
  44 + public static int GridSpanCount = 3;
  45 + public static int GridSpace = 4;
  46 +
  47 + //裁剪请求码
  48 + public static final int REQUEST_CODE_CROP = 113;
  49 + //打开相机的权限请求有吗
  50 + public static final int REQUEST_CODE_PERMISSION_CAMERA = 111;
  51 + public static final int REQUEST_CODE_PERMISSION_READ = 112;
  52 + public static final int REQUEST_CODE_PERMISSION_CROP = 113;
  53 + //相机类型 图片视频
  54 + public static final int CAMERA_MODE_ALL = 0;
  55 + //相机类型 只拍图片
  56 + public static final int CAMERA_MODE_PIC = 1;
  57 + //相机类型 只拍视频
  58 + public static final int CAMERA_MODE_VIDEO = 2;
  59 +
  60 + //裁剪后图片名字前缀
  61 + public static final String CROP_NAME_PREFIX = "CROP_";
  62 + //图片文件名后缀
  63 + public static final String IMG_NAME_POSTFIX = ".jpg";
  64 +
  65 + public static String WHERE_JUMP_CAMERA = "jump_camera";
  66 + public static String WHERE_JUMP_CAMERA_SELECTS = "jump_camera_selects";
  67 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/presenter/ImageCropPrsenter.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/presenter/ImageCropPrsenter.java
  1 +package com.cnlive.media.frame.presenter;
  2 +
  3 +import android.text.TextUtils;
  4 +
  5 +import com.cnlive.media.frame.view.ImageCropView;
  6 +import com.cnlive.media.ui.activity.ImageCropActivity;
  7 +import com.cnlive.meidia.R;
  8 +import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter;
  9 +
  10 +import java.io.File;
  11 +
  12 +/**
  13 + * 作 者 : wkq
  14 + * <p>
  15 + * 时 间 : 2020/9/29 15:45
  16 + * <p>
  17 + * 名 字 : ImageCropPrsenter
  18 + * <p>
  19 + * 简 介 :
  20 + */
  21 +public class ImageCropPrsenter extends MvpBasePresenter<ImageCropView> {
  22 +
  23 + public void initData(ImageCropActivity mActibity) {
  24 + if (mActibity.mOptions == null) {
  25 + getView().showMessage(mActibity.getResources().getString(R.string.error_imagepicker_lack_params));
  26 + mActibity.setResult(mActibity.RESULT_CANCELED);
  27 + mActibity.finish();
  28 + return;
  29 + }
  30 + if (TextUtils.isEmpty(mActibity.mOriginPath) || mActibity.mOriginPath.length() == 0) {
  31 + getView().showMessage(mActibity.getResources().getString(R.string.imagepicker_crop_decode_fail));
  32 + mActibity.setResult(mActibity.RESULT_CANCELED);
  33 + mActibity.finish();
  34 + return;
  35 + }
  36 +
  37 + File file = new File(mActibity.mOriginPath);
  38 + if (!file.exists()) {
  39 + getView().showMessage(mActibity.getResources().getString(R.string.imagepicker_crop_decode_fail));
  40 + mActibity.finish();
  41 + return;
  42 + }
  43 +
  44 + mActibity.cacheFile = new File(mActibity.mOptions.cachePath);
  45 + if (!mActibity.cacheFile.exists())
  46 + mActibity.cacheFile.mkdirs();
  47 +
  48 + mActibity.mCropParams = mActibity.mOptions.getCropParams();
  49 + mActibity.binding.cvCrop.load(mActibity.mOriginPath)
  50 + .setAspect(mActibity.mCropParams.getAspectX(), mActibity.mCropParams.getAspectY())
  51 + .setOutputSize(mActibity.mCropParams.getOutputX(), mActibity.mCropParams.getOutputY())
  52 + .start(mActibity);
  53 + }
  54 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/presenter/MediaFPresenter.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/presenter/MediaFPresenter.java
  1 +package com.cnlive.media.frame.presenter;
  2 +
  3 +import com.cnlive.media.frame.view.MediaFView;
  4 +import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter;
  5 +
  6 +/**
  7 + * 作 者 : wkq
  8 + * <p>
  9 + * 时 间 : 2020/9/17 16:18
  10 + * <p>
  11 + * 名 字 : MediaFPresenter
  12 + * <p>
  13 + * 简 介 :
  14 + */
  15 +public class MediaFPresenter extends MvpBasePresenter<MediaFView> {
  16 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/presenter/MediaPickerFragmentPresenter.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/presenter/MediaPickerFragmentPresenter.java
  1 +package com.cnlive.media.frame.presenter;
  2 +
  3 +import android.os.Environment;
  4 +import android.text.TextUtils;
  5 +
  6 +import com.cnlive.media.PickerConfig;
  7 +import com.cnlive.media.frame.view.MediaPickerFragmentView;
  8 +import com.cnlive.media.ui.activity.MediaActivity;
  9 +import com.cnlive.media.utlis.AndroidQUtil;
  10 +import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter;
  11 +
  12 +import java.io.File;
  13 +import java.util.ArrayList;
  14 +
  15 +/**
  16 + * 作 者 : wkq
  17 + * <p>
  18 + * 时 间 : 2020/9/15 11:30
  19 + * <p>
  20 + * 名 字 : MediaPickerPresenter
  21 + * <p>
  22 + * 简 介 :
  23 + */
  24 +public class MediaPickerFragmentPresenter extends MvpBasePresenter<MediaPickerFragmentView> {
  25 +
  26 + public void initIntentData(MediaActivity mediaPickerActivity) {
  27 + //获取配置的
  28 + mediaPickerActivity.mOptions = mediaPickerActivity.getIntent().getParcelableExtra(PickerConfig.INTENT_KEY_OPTIONS);
  29 + mediaPickerActivity.cachePath = mediaPickerActivity.mOptions .getCachePath();
  30 + if (TextUtils.isEmpty(mediaPickerActivity.cachePath)) {
  31 + if (AndroidQUtil.isAndroidQ()) {
  32 + mediaPickerActivity.cachePath = mediaPickerActivity.getExternalFilesDir("").getPath() + File.separator + "MediaPickerPic";
  33 + } else {
  34 + mediaPickerActivity.cachePath = Environment.getExternalStorageDirectory().getPath() + File.separator + "MediaPickerPic";
  35 + }
  36 +
  37 + } else {
  38 + if (AndroidQUtil.isAndroidQ()) {
  39 + mediaPickerActivity.cachePath = mediaPickerActivity.getExternalFilesDir("") + mediaPickerActivity.cachePath;
  40 + }
  41 + }
  42 +
  43 + mediaPickerActivity.videoTrimPath = mediaPickerActivity.mOptions .getVideoTrimPath();
  44 + if (TextUtils.isEmpty(mediaPickerActivity.videoTrimPath)) {
  45 + if (AndroidQUtil.isAndroidQ()) {
  46 + mediaPickerActivity.videoTrimPath = mediaPickerActivity.getExternalFilesDir("").getPath() + File.separator + "MediaPickerVideo";
  47 + } else {
  48 + mediaPickerActivity.videoTrimPath = Environment.getExternalStorageDirectory().getPath() + File.separator + "MediaPickerVideo";
  49 + }
  50 +
  51 + } else {
  52 + if (AndroidQUtil.isAndroidQ()) {
  53 + mediaPickerActivity.videoTrimPath = mediaPickerActivity.getExternalFilesDir("") + mediaPickerActivity.videoTrimPath;
  54 + }
  55 + }
  56 +
  57 + mediaPickerActivity.cropParams = mediaPickerActivity.mOptions .getCropParams();
  58 + mediaPickerActivity.maxImageSize = mediaPickerActivity.mOptions .getMaxImageSize();
  59 + mediaPickerActivity.maxNum = mediaPickerActivity.mOptions .getMaxNum();
  60 + mediaPickerActivity.maxVideoSize = mediaPickerActivity.mOptions .getMaxVideoSize();
  61 + mediaPickerActivity.selectMode = mediaPickerActivity.mOptions .getSelectMode();
  62 + mediaPickerActivity.maxTime = mediaPickerActivity.mOptions .getMaxTime();
  63 + mediaPickerActivity.isReturnUri = mediaPickerActivity.mOptions .isReturnUri();
  64 + mediaPickerActivity.isFrendCircle = mediaPickerActivity.mOptions .isFriendCircle();
  65 + mediaPickerActivity.needCrop = mediaPickerActivity.mOptions .isNeedCrop();
  66 + mediaPickerActivity.needCamera = mediaPickerActivity.mOptions .isNeedCamera();
  67 + mediaPickerActivity.showTime = mediaPickerActivity.mOptions .isShowTime();
  68 + mediaPickerActivity.selectGift = mediaPickerActivity.mOptions .isSelectGift();
  69 + mediaPickerActivity.singlePick = mediaPickerActivity.mOptions .isSinglePick();
  70 + mediaPickerActivity.selects = mediaPickerActivity.mOptions .getSelects();
  71 + if (mediaPickerActivity.selects==null)mediaPickerActivity.selects=new ArrayList<>();
  72 + }
  73 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/presenter/MediaPresenter.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/presenter/MediaPresenter.java
  1 +package com.cnlive.media.frame.presenter;
  2 +
  3 +import android.app.Activity;
  4 +import android.content.pm.PackageManager;
  5 +import android.os.Build;
  6 +import android.os.Environment;
  7 +import android.text.TextUtils;
  8 +
  9 +import androidx.core.app.ActivityCompat;
  10 +
  11 +import com.cnlive.media.PickerConfig;
  12 +import com.cnlive.media.frame.view.MediaView;
  13 +import com.cnlive.media.ui.activity.MediaActivity;
  14 +import com.cnlive.media.ui.activity.RecordActivity;
  15 +import com.cnlive.media.utlis.AndroidQUtil;
  16 +import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter;
  17 +
  18 +import java.io.File;
  19 +import java.util.ArrayList;
  20 +import java.util.List;
  21 +
  22 +/**
  23 + * 作 者 : wkq
  24 + * <p>
  25 + * 时 间 : 2020/9/15 11:30
  26 + * <p>
  27 + * 名 字 : MediaPickerPresenter
  28 + * <p>
  29 + * 简 介 :
  30 + */
  31 +public class MediaPresenter extends MvpBasePresenter<MediaView> {
  32 +
  33 + public void initIntentData(MediaActivity mediaPickerActivity) {
  34 + //获取配置的
  35 + mediaPickerActivity.mOptions = mediaPickerActivity.getIntent().getParcelableExtra(PickerConfig.INTENT_KEY_OPTIONS);
  36 + mediaPickerActivity.cachePath = mediaPickerActivity.mOptions.getCachePath();
  37 + if (TextUtils.isEmpty(mediaPickerActivity.cachePath)) {
  38 + if (AndroidQUtil.isAndroidQ()) {
  39 + mediaPickerActivity.cachePath = mediaPickerActivity.getExternalFilesDir("").getPath() + File.separator + "MediaPickerPic";
  40 +
  41 + } else {
  42 + mediaPickerActivity.cachePath = Environment.getExternalStorageDirectory().getPath() + File.separator + "MediaPickerPic";
  43 + }
  44 + mediaPickerActivity.mOptions.setCachePath(mediaPickerActivity.cachePath);
  45 + } else {
  46 + if (AndroidQUtil.isAndroidQ()) {
  47 + mediaPickerActivity.cachePath = mediaPickerActivity.getExternalFilesDir("") + mediaPickerActivity.cachePath;
  48 + mediaPickerActivity.mOptions.setCachePath(mediaPickerActivity.cachePath);
  49 + }
  50 + }
  51 +
  52 + mediaPickerActivity.videoTrimPath = mediaPickerActivity.mOptions.getVideoTrimPath();
  53 + if (TextUtils.isEmpty(mediaPickerActivity.videoTrimPath)) {
  54 + if (AndroidQUtil.isAndroidQ()) {
  55 + mediaPickerActivity.videoTrimPath = mediaPickerActivity.getExternalFilesDir("").getPath() + File.separator + "MediaPickerVideo";
  56 +
  57 + } else {
  58 + mediaPickerActivity.videoTrimPath = Environment.getExternalStorageDirectory().getPath() + File.separator + "MediaPickerVideo";
  59 + }
  60 + mediaPickerActivity.mOptions.setVideoTrimPath(mediaPickerActivity.videoTrimPath);
  61 +
  62 + } else {
  63 + if (AndroidQUtil.isAndroidQ()) {
  64 + mediaPickerActivity.videoTrimPath = mediaPickerActivity.getExternalFilesDir("") + mediaPickerActivity.videoTrimPath;
  65 + mediaPickerActivity.mOptions.setVideoTrimPath(mediaPickerActivity.videoTrimPath);
  66 + }
  67 + }
  68 +
  69 + mediaPickerActivity.cropParams = mediaPickerActivity.mOptions.getCropParams();
  70 + mediaPickerActivity.maxImageSize = mediaPickerActivity.mOptions.getMaxImageSize();
  71 + mediaPickerActivity.maxNum = mediaPickerActivity.mOptions.getMaxNum();
  72 + mediaPickerActivity.maxVideoSize = mediaPickerActivity.mOptions.getMaxVideoSize();
  73 + mediaPickerActivity.selectMode = mediaPickerActivity.mOptions.getSelectMode();
  74 + mediaPickerActivity.maxTime = mediaPickerActivity.mOptions.getMaxTime();
  75 + mediaPickerActivity.isReturnUri = mediaPickerActivity.mOptions.isReturnUri();
  76 + mediaPickerActivity.isFrendCircle = mediaPickerActivity.mOptions.isFriendCircle();
  77 + mediaPickerActivity.needCrop = mediaPickerActivity.mOptions.isNeedCrop();
  78 + mediaPickerActivity.needCamera = mediaPickerActivity.mOptions.isNeedCamera();
  79 + mediaPickerActivity.showTime = mediaPickerActivity.mOptions.isShowTime();
  80 + mediaPickerActivity.selectGift = mediaPickerActivity.mOptions.isSelectGift();
  81 + mediaPickerActivity.singlePick = mediaPickerActivity.mOptions.isSinglePick();
  82 + mediaPickerActivity.selects = mediaPickerActivity.mOptions.getSelects();
  83 + mediaPickerActivity.resultCode = mediaPickerActivity.getIntent().getIntExtra(PickerConfig.RESULT_CODE, 0);
  84 + if (mediaPickerActivity.selects == null) mediaPickerActivity.selects = new ArrayList<>();
  85 + }
  86 +
  87 + public boolean checkPermissions(Activity activity, String[] permissions, int requestCode, String showMessage, boolean isFinish) {
  88 + //Android6.0以下默认有权限
  89 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
  90 + return true;
  91 + List<String> needList = new ArrayList<>();
  92 + boolean needShowRationale = false;
  93 +
  94 + for (String permisson : permissions) {
  95 + if (TextUtils.isEmpty(permisson)) continue;
  96 + if (ActivityCompat.checkSelfPermission(activity, permisson)
  97 + != PackageManager.PERMISSION_GRANTED) {
  98 + needList.add(permisson);
  99 + if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permisson))
  100 + needShowRationale = true;
  101 + }
  102 + }
  103 +
  104 + if (needList.size() != 0) {
  105 + final int count = needList.size();
  106 + String[] needArray = needList.toArray(new String[count]);
  107 + if (needShowRationale) {
  108 + getView().showPermission(needArray, requestCode, showMessage, isFinish);
  109 + } else {
  110 + ActivityCompat.requestPermissions(activity, needArray, requestCode);
  111 + }
  112 + return false;
  113 + } else {
  114 + return true;
  115 + }
  116 + }
  117 +
  118 + public boolean[] onRequestPermissionsResult(Activity recordActivity, int requestCode, String[] permissions, int[] grantResults) {
  119 +
  120 + boolean result = true;
  121 + boolean isNeverAsk = false;
  122 +
  123 + int length = grantResults.length;
  124 + for (int i = 0; i < length; i++) {
  125 + String permission = permissions[i];
  126 + int grandResult = grantResults[i];
  127 + if (grandResult == PackageManager.PERMISSION_DENIED) {
  128 + result = false;
  129 + if (!ActivityCompat.shouldShowRequestPermissionRationale(recordActivity, permission))
  130 + isNeverAsk = true;
  131 + }
  132 + }
  133 +
  134 + return new boolean[]{result, isNeverAsk};
  135 + }
  136 +
  137 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/presenter/MediaPreviewPresenter.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/presenter/MediaPreviewPresenter.java
  1 +package com.cnlive.media.frame.presenter;
  2 +
  3 +import com.cnlive.media.frame.view.MediaPreviewView;
  4 +import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter;
  5 +
  6 +/**
  7 + * 作 者 : wkq
  8 + * <p>
  9 + * 时 间 : 2020/9/17 14:31
  10 + * <p>
  11 + * 名 字 : MediaPreviewPresenter
  12 + * <p>
  13 + * 简 介 :
  14 + */
  15 +public class MediaPreviewPresenter extends MvpBasePresenter<MediaPreviewView> {
  16 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/presenter/MediaPreviewViewPresenter.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/presenter/MediaPreviewViewPresenter.java
  1 +package com.cnlive.media.frame.presenter;
  2 +
  3 +import com.cnlive.media.frame.view.MediaPreviewViewView;
  4 +import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter;
  5 +
  6 +/**
  7 + * 作 者 : wkq
  8 + * <p>
  9 + * 时 间 : 2020/10/23 9:49
  10 + * <p>
  11 + * 名 字 : MediaPreviewViewPresenter
  12 + * <p>
  13 + * 简 介 :
  14 + */
  15 +public class MediaPreviewViewPresenter extends MvpBasePresenter<MediaPreviewViewView> {
  16 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/presenter/RecordPresenter.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/presenter/RecordPresenter.java
  1 +package com.cnlive.media.frame.presenter;
  2 +
  3 +import android.app.Activity;
  4 +import android.content.pm.PackageManager;
  5 +import android.os.Build;
  6 +import android.text.TextUtils;
  7 +
  8 +import androidx.core.app.ActivityCompat;
  9 +
  10 +import com.cnlive.media.frame.view.RecordView;
  11 +import com.cnlive.media.ui.activity.RecordActivity;
  12 +import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter;
  13 +
  14 +import java.util.ArrayList;
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * 作 者 : wkq
  19 + * <p>
  20 + * 时 间 : 2020/9/22 13:33
  21 + * <p>
  22 + * 名 字 : RecordPresenter
  23 + * <p>
  24 + * 简 介 :
  25 + */
  26 +public class RecordPresenter extends MvpBasePresenter<RecordView> {
  27 +
  28 + public boolean checkPermissions(Activity activity, String[] permissions, int requestCode, boolean request) {
  29 + //Android6.0以下默认有权限
  30 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
  31 + return true;
  32 +
  33 + List<String> needList = new ArrayList<>();
  34 + boolean needShowRationale = false;
  35 +
  36 + for (String permisson : permissions) {
  37 + if (TextUtils.isEmpty(permisson)) continue;
  38 + if (ActivityCompat.checkSelfPermission(activity, permisson)
  39 + != PackageManager.PERMISSION_GRANTED) {
  40 + needList.add(permisson);
  41 + if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permisson))
  42 + needShowRationale = true;
  43 + }
  44 + }
  45 +
  46 + if (needList.size() != 0) {
  47 + final int count = needList.size();
  48 + String[] needArray = needList.toArray(new String[count]);
  49 + if (needShowRationale) {
  50 + getView().showPermission(needArray, requestCode);
  51 + } else if (request) {
  52 + ActivityCompat.requestPermissions(activity, needArray, requestCode);
  53 + }
  54 + return false;
  55 + } else {
  56 + return true;
  57 + }
  58 + }
  59 +
  60 + public boolean[] onRequestPermissionsResult(RecordActivity recordActivity, int requestCode, String[] permissions, int[] grantResults) {
  61 +
  62 + boolean result = true;
  63 + boolean isNeverAsk = false;
  64 +
  65 + int length = grantResults.length;
  66 + for (int i = 0; i < length; i++) {
  67 + String permission = permissions[i];
  68 + int grandResult = grantResults[i];
  69 + if (grandResult == PackageManager.PERMISSION_DENIED) {
  70 + result = false;
  71 + if (!ActivityCompat.shouldShowRequestPermissionRationale(recordActivity, permission))
  72 + isNeverAsk = true;
  73 + }
  74 + }
  75 +
  76 + return new boolean[]{result, isNeverAsk};
  77 + }
  78 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/presenter/RecordPreviewPresenter.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/presenter/RecordPreviewPresenter.java
  1 +package com.cnlive.media.frame.presenter;
  2 +
  3 +import com.cnlive.media.frame.view.RecordPreviewView;
  4 +import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter;
  5 +
  6 +/**
  7 + * 作 者 : wkq
  8 + * <p>
  9 + * 时 间 : 2020/9/28 9:36
  10 + * <p>
  11 + * 名 字 : RecordPreviewPresenter
  12 + * <p>
  13 + * 简 介 :
  14 + */
  15 +public class RecordPreviewPresenter extends MvpBasePresenter<RecordPreviewView> {
  16 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/presenter/VideoPlayerPresenter.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/presenter/VideoPlayerPresenter.java
  1 +package com.cnlive.media.frame.presenter;
  2 +
  3 +import com.cnlive.media.frame.view.VideoPlayerView;
  4 +import com.hannesdorfmann.mosby3.mvp.MvpBasePresenter;
  5 +
  6 +/**
  7 + * 作 者 : wkq
  8 + * <p>
  9 + * 时 间 : 2020/10/15 11:14
  10 + * <p>
  11 + * 名 字 : VideoPlayerPresenter
  12 + * <p>
  13 + * 简 介 :
  14 + */
  15 +public class VideoPlayerPresenter extends MvpBasePresenter<VideoPlayerView> {
  16 +
  17 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/view/ImageCropView.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/view/ImageCropView.java
  1 +package com.cnlive.media.frame.view;
  2 +
  3 +import android.app.ProgressDialog;
  4 +import android.content.pm.ActivityInfo;
  5 +import android.graphics.Bitmap;
  6 +import android.net.Uri;
  7 +import android.os.Build;
  8 +import android.text.TextUtils;
  9 +
  10 +import com.cnlive.libs.base.util.AlertUtil;
  11 +import com.cnlive.libs.base.util.FileUtils;
  12 +import com.cnlive.media.meidia.entity.Media;
  13 +import com.cnlive.media.ui.activity.ImageCropActivity;
  14 +import com.cnlive.media.utlis.AndroidQUtil;
  15 +import com.cnlive.media.utlis.observable.MeidaResultObservable;
  16 +import com.cnlive.meidia.R;
  17 +import com.hannesdorfmann.mosby3.mvp.MvpView;
  18 +
  19 +import java.io.File;
  20 +
  21 +import io.reactivex.Observable;
  22 +import io.reactivex.ObservableEmitter;
  23 +import io.reactivex.ObservableOnSubscribe;
  24 +import io.reactivex.Observer;
  25 +import io.reactivex.android.schedulers.AndroidSchedulers;
  26 +import io.reactivex.disposables.Disposable;
  27 +import io.reactivex.schedulers.Schedulers;
  28 +
  29 +/**
  30 + * 作 者 : wkq
  31 + * <p>
  32 + * 时 间 : 2020/9/29 15:44
  33 + * <p>
  34 + * 名 字 : ImageCropView
  35 + * <p>
  36 + * 简 介 :
  37 + */
  38 +public class ImageCropView implements MvpView {
  39 + ImageCropActivity mActivity;
  40 + private ProgressDialog mDialog;
  41 +
  42 + public ImageCropView(ImageCropActivity mActivity) {
  43 + this.mActivity = mActivity;
  44 + }
  45 +
  46 + public void initView() {
  47 + if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
  48 + mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  49 + }
  50 + mActivity.binding.setOnClick(mActivity);
  51 + }
  52 +
  53 + public void returnCropedImage() {
  54 +
  55 + showDialog();
  56 + Observable.create(new ObservableOnSubscribe<String>() {
  57 + @Override
  58 + public void subscribe(ObservableEmitter<String> emitter) throws Exception {
  59 + Bitmap bitmap = mActivity.binding.cvCrop.getOutput();
  60 + if (bitmap == null || bitmap.getWidth() == 0 || bitmap.getHeight() == 0 || bitmap.getByteCount() <= 0) {
  61 + emitter.onError(new Throwable("图片裁剪异常"));
  62 + } else {
  63 + String filePath = AndroidQUtil.saveSignImageBox(mActivity, System.currentTimeMillis() + ".png", bitmap);
  64 + if (!TextUtils.isEmpty(filePath) && FileUtils.isFileExists(filePath)) {
  65 + emitter.onNext(filePath);
  66 + } else {
  67 + emitter.onError(new Throwable("图片裁剪异常"));
  68 + }
  69 + }
  70 +
  71 + }
  72 + }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<String>() {
  73 + @Override
  74 + public void onSubscribe(Disposable d) {
  75 +
  76 + }
  77 +
  78 + @Override
  79 + public void onNext(String path) {
  80 + dismissDialog();
  81 + processPath(path);
  82 + }
  83 +
  84 + @Override
  85 + public void onError(Throwable e) {
  86 + dismissDialog();
  87 + showMessage("文件格式不支持");
  88 + }
  89 +
  90 + @Override
  91 + public void onComplete() {
  92 +
  93 + }
  94 + });
  95 + }
  96 +
  97 + //
  98 + private void processPath(String path) {
  99 + File file = new File(path);
  100 + if (file != null && file.exists() && file.canRead() && file.canWrite()) {
  101 + Media media = new Media(path, file.getName(), System.currentTimeMillis(), 1, file.length(), (int) System.currentTimeMillis(), file.getParent(), Uri.fromFile(file).toString());
  102 + media.setSelect(false);
  103 + media.setReturnUri(mActivity.mOptions.isReturnUri());
  104 +// if (mActivity.preBitmap != null && mActivity.preBitmap.getHeight() > 0 && mActivity.preBitmap.getWidth() > 0) {
  105 +// media.setImgHeight(mActivity.preBitmap.getHeight());
  106 +// media.setImgWidth(mActivity.preBitmap.getWidth());
  107 +// media.setLongImg(MediaUtils.isLongImg(mActivity.preBitmap.getWidth(), mActivity.preBitmap.getHeight()));
  108 +// }
  109 +
  110 + MeidaResultObservable.getInstance().finishMedia(true, media);
  111 + mActivity.finish();
  112 + }
  113 + }
  114 +
  115 + public void showDialog() {
  116 + if (mDialog == null) mDialog = new ProgressDialog(mActivity);
  117 + mDialog.setCancelable(false);
  118 + mDialog.setCanceledOnTouchOutside(false);
  119 + mDialog.setMessage(mActivity.getResources().getString(R.string.imagepicker_crop_dialog));
  120 + mDialog.show();
  121 + }
  122 +
  123 + public void dismissDialog() {
  124 + if (mDialog != null && mDialog.isShowing()) mDialog.dismiss();
  125 + }
  126 +
  127 + public void showMessage(String message) {
  128 + if (TextUtils.isEmpty(message) || mActivity.isFinishing()) return;
  129 + AlertUtil.showDeftToast(mActivity, message);
  130 + }
  131 +
  132 + public void showSucessMessage(String message) {
  133 + if (TextUtils.isEmpty(message) || mActivity.isFinishing()) return;
  134 + AlertUtil.showSuccessToast(mActivity, message);
  135 + }
  136 +
  137 +
  138 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/view/MediaFView.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/view/MediaFView.java
  1 +package com.cnlive.media.frame.view;
  2 +
  3 +import android.text.TextUtils;
  4 +import android.view.View;
  5 +
  6 +import com.cnlive.libs.base.util.AlertUtil;
  7 +import com.cnlive.media.meidia.entity.Media;
  8 +import com.cnlive.media.ui.activity.VideoPlayerActivity;
  9 +import com.cnlive.media.ui.fragment.MediaFragment;
  10 +import com.cnlive.media.ui.widget.large.ImageSource;
  11 +import com.cnlive.media.ui.widget.large.SubsamplingScaleImageView;
  12 +import com.cnlive.media.utlis.AndroidQUtil;
  13 +import com.cnlive.media.utlis.FileTypeUtil;
  14 +import com.cnlive.media.utlis.GlideCacheUtil;
  15 +import com.hannesdorfmann.mosby3.mvp.MvpView;
  16 +
  17 +/**
  18 + * 作 者 : wkq
  19 + * <p>
  20 + * 时 间 : 2020/9/17 16:16
  21 + * <p>
  22 + * 名 字 : MediaFView
  23 + * <p>
  24 + * 简 介 :
  25 + */
  26 +public class MediaFView implements MvpView {
  27 + MediaFragment mFragment;
  28 +
  29 + public MediaFView(MediaFragment mFragment) {
  30 + this.mFragment = mFragment;
  31 + }
  32 +
  33 + public void initView() {
  34 + //是视频
  35 + mFragment.binding.lvLoading.setVisibility(View.VISIBLE);
  36 + if (mFragment.mMedia.mediaType == 3) {
  37 + mFragment.binding.playView.setVisibility(View.VISIBLE);
  38 + mFragment.binding.photoview.setVisibility(View.GONE);
  39 + mFragment.binding.largePhoto.setVisibility(View.GONE);
  40 + mFragment.binding.gifView.setVisibility(View.VISIBLE);
  41 + GlideCacheUtil.intoItemImage(mFragment.getActivity(), mFragment.mMedia, mFragment.binding.gifView, mFragment.binding.lvLoading);
  42 +
  43 + mFragment.binding.playView.setOnClickListener(v -> {
  44 + VideoPlayerActivity.newInstance(mFragment.getActivity(), mFragment.mMedia.fileUri);
  45 + });
  46 + } else {
  47 + if (FileTypeUtil.isGif(mFragment.mMedia.path)) {
  48 + mFragment.binding.largePhoto.setVisibility(View.GONE);
  49 + mFragment.binding.photoview.setVisibility(View.GONE);
  50 + //填充图片
  51 + GlideCacheUtil.intoItemImage(mFragment.getActivity(), mFragment.mMedia, mFragment.binding.gifView, mFragment.binding.lvLoading);
  52 + }
  53 + if (FileTypeUtil.isNoSupport(mFragment.mMedia.path)) {
  54 + mFragment.binding.largePhoto.setZoomEnabled(false);
  55 + mFragment.binding.largePhoto.setVisibility(View.GONE);
  56 + mFragment.binding.photoview.setVisibility(View.VISIBLE);
  57 + //填充图片
  58 + GlideCacheUtil.intoItemImageOther(mFragment.getActivity(), mFragment.mMedia, mFragment.binding.gifView, mFragment.binding.lvLoading);
  59 + } else {
  60 + mFragment.binding.largePhoto.setVisibility(View.GONE);
  61 + mFragment.binding.photoview.setVisibility(View.VISIBLE);
  62 + showPicView(mFragment.mMedia);
  63 + }
  64 + }
  65 + }
  66 +
  67 + private void showPicView(Media media) {
  68 + if (null == mFragment.getActivity() || null == mFragment.getContext()) {
  69 + return;
  70 + }
  71 + //先判断是不是超长图
  72 + if (!media.isLongImg && media.getImgHeight() != 0 && media.getImgWidth() != 0) {
  73 + //填充图片
  74 + GlideCacheUtil.intoItemImageOther(mFragment.getActivity(), media, mFragment.binding.photoview, mFragment.binding.lvLoading);
  75 + return;
  76 + }
  77 + mFragment.binding.largePhoto.setMinimumScaleType(SubsamplingScaleImageView.SCALE_TYPE_CUSTOM);
  78 + mFragment.binding.largePhoto.setMaxScale(10.0F);//最大显示比例(太大了图片显示会失真,因为一般微博长图的宽度不会太宽)
  79 + mFragment.binding.largePhoto.setZoomEnabled(false);
  80 + mFragment.binding.largePhoto.setVisibility(View.VISIBLE);
  81 +
  82 + if (AndroidQUtil.isAndroidQ()) {
  83 + mFragment.binding.largePhoto.setImage(ImageSource.uri(media.fileUri));
  84 + } else {
  85 + mFragment.binding.largePhoto.setImage(ImageSource.uri(media.path));
  86 + }
  87 +
  88 + mFragment.binding.largePhoto.setOnImageEventListener(new SubsamplingScaleImageView.OnImageEventListener() {
  89 + @Override
  90 + public void onReady() {
  91 + mFragment.binding.lvLoading.setVisibility(View.GONE);
  92 + if (mFragment.binding.largePhoto != null)
  93 + mFragment.binding.largePhoto.setZoomEnabled(false);
  94 + }
  95 +
  96 + @Override
  97 + public void onImageLoaded() {
  98 + mFragment.binding.lvLoading.setVisibility(View.GONE);
  99 + if (mFragment.binding.largePhoto != null)
  100 + mFragment.binding.largePhoto.setZoomEnabled(true);
  101 + }
  102 +
  103 + @Override
  104 + public void onPreviewLoadError(Exception e) {
  105 + mFragment.binding.lvLoading.setVisibility(View.GONE);
  106 + if (mFragment.binding.largePhoto != null)
  107 + mFragment.binding.largePhoto.setZoomEnabled(false);
  108 + }
  109 +
  110 + @Override
  111 + public void onImageLoadError(Exception e) {
  112 + if (mFragment.getActivity() == null && mFragment.getContext() == null) return;
  113 + mFragment.binding.lvLoading.setVisibility(View.GONE);
  114 + if (mFragment.binding.largePhoto != null)
  115 + mFragment.binding.largePhoto.setZoomEnabled(false);
  116 + if (mFragment.binding.largePhoto != null)
  117 + mFragment.binding.largePhoto.setVisibility(View.GONE);
  118 + mFragment.binding.photoview.setVisibility(View.VISIBLE);
  119 + //填充图片
  120 + GlideCacheUtil.intoItemImageOther(mFragment.getContext(), media, mFragment.binding.photoview, mFragment.binding.lvLoading);
  121 + }
  122 +
  123 + @Override
  124 + public void onTileLoadError(Exception e) {
  125 + mFragment.binding.lvLoading.setVisibility(View.GONE);
  126 + if (mFragment.binding.largePhoto != null)
  127 + mFragment.binding.largePhoto.setZoomEnabled(false);
  128 + }
  129 +
  130 + @Override
  131 + public void onPreviewReleased() {
  132 + }
  133 + });
  134 + }
  135 +
  136 +
  137 + public void showMessage(String message) {
  138 + if (mFragment == null || mFragment.getActivity() == null || TextUtils.isEmpty(message))
  139 + return;
  140 + AlertUtil.showDeftToast(mFragment.getActivity(), message);
  141 + }
  142 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/view/MediaPickerFragmentView.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/view/MediaPickerFragmentView.java
  1 +package com.cnlive.media.frame.view;
  2 +
  3 +import android.Manifest;
  4 +import android.net.Uri;
  5 +import android.os.Build;
  6 +import android.text.TextUtils;
  7 +
  8 +import androidx.annotation.RequiresApi;
  9 +import androidx.recyclerview.widget.GridLayoutManager;
  10 +import androidx.recyclerview.widget.RecyclerView;
  11 +
  12 +import com.bumptech.glide.Glide;
  13 +import com.cnlive.libs.base.util.AlertUtil;
  14 +import com.cnlive.libs.base.util.DoublePressed;
  15 +import com.cnlive.libs.base.util.FileUtils;
  16 +import com.cnlive.media.PickerConfig;
  17 +import com.cnlive.media.meidia.entity.Folder;
  18 +import com.cnlive.media.meidia.entity.Media;
  19 +import com.cnlive.media.ui.activity.ImageCropActivity;
  20 +import com.cnlive.media.ui.activity.MediaActivity;
  21 +import com.cnlive.media.ui.activity.RecordActivity;
  22 +import com.cnlive.media.ui.fragment.MediaPickerFragment;
  23 +import com.cnlive.media.ui.adapter.MediaAdapter;
  24 +import com.cnlive.media.ui.adapter.OnItemClickListener;
  25 +import com.cnlive.media.ui.widget.SpacingDecoration;
  26 +import com.cnlive.media.utlis.AndroidQUtil;
  27 +import com.cnlive.media.utlis.FileTypeUtil;
  28 +import com.cnlive.media.utlis.MediaStringUtils;
  29 +import com.cnlive.media.utlis.PermissionChecker;
  30 +import com.cnlive.media.utlis.observable.MediaOpenActivityObservable;
  31 +import com.cnlive.media.utlis.observable.MediaOpenInfo;
  32 +import com.cnlive.media.utlis.observable.MediaSelectStateObservable;
  33 +import com.cnlive.media.utlis.observable.MeidaResultObservable;
  34 +import com.cnlive.meidia.R;
  35 +import com.hannesdorfmann.mosby3.mvp.MvpView;
  36 +
  37 +import java.util.ArrayList;
  38 +import java.util.List;
  39 +
  40 +
  41 +/**
  42 + * 作 者 : wkq
  43 + * <p>
  44 + * 时 间 : 2020/9/15 11:29
  45 + * <p>
  46 + * 名 字 : MediaPickerView
  47 + * <p>
  48 + * 简 介 :
  49 + */
  50 +public class MediaPickerFragmentView implements MvpView {
  51 + MediaPickerFragment mFragment;
  52 +
  53 +
  54 + public MediaPickerFragmentView(MediaPickerFragment mFragment) {
  55 + this.mFragment = mFragment;
  56 + }
  57 +
  58 + public void initView(MediaActivity mActivity) {
  59 + initMedia(mActivity);
  60 + }
  61 +
  62 +
  63 + private void initMedia(MediaActivity mActivity) {
  64 +
  65 + GridLayoutManager mLayoutManager = new GridLayoutManager(mFragment.getActivity(), PickerConfig.GridSpanCount);
  66 + mFragment.binding.rv.setLayoutManager(mLayoutManager);
  67 + mFragment.binding.rv.addItemDecoration(new SpacingDecoration(PickerConfig.GridSpanCount, PickerConfig.GridSpace));
  68 + //如果可以确定每个item的高度是固定的,设置这个选项可以提高性能
  69 + mFragment.binding.rv.setHasFixedSize(true);
  70 +
  71 + mFragment.binding.rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
  72 + @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
  73 + @Override
  74 + public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
  75 + super.onScrollStateChanged(recyclerView, newState);
  76 + if (RecyclerView.SCROLL_STATE_IDLE == newState) {
  77 + Glide.with(recyclerView).resumeRequests();
  78 + } else {
  79 + Glide.with(recyclerView).pauseRequests();
  80 + }
  81 + }
  82 + });
  83 + mFragment.mMediaAdapter = new MediaAdapter(mFragment.getActivity(), mActivity.showTime, mActivity.mOptions);
  84 + mFragment.binding.rv.setAdapter(mFragment.mMediaAdapter);
  85 +
  86 + mFragment.mMediaAdapter.setOnItemClickListener(new OnItemClickListener() {
  87 + @Override
  88 + public void itemClick(Media media) {
  89 + if (DoublePressed.onDoublePressed()) return;
  90 + if (mActivity.mOptions.isSinglePick() || mActivity.mOptions.maxNum == 1) {
  91 +
  92 + if (mActivity.mOptions.isNeedCrop()) {
  93 + if (media.mediaType != 1) {
  94 + showMessage("请选择图片");
  95 + } else {
  96 + MediaOpenActivityObservable.getInstance().openActivity(new MediaOpenInfo(2, media));
  97 + }
  98 + } else {
  99 + MeidaResultObservable.getInstance().finishMedia(true, media);
  100 + }
  101 + } else {
  102 + if (isCheckMediaSupport(mActivity, media)) {
  103 + if (mActivity.mOptions.isNeedCrop()) {
  104 + if (media.mediaType != 1) {
  105 + showMessage("请选择图片");
  106 + } else {
  107 + MediaOpenActivityObservable.getInstance().openActivity(new MediaOpenInfo(2, media));
  108 + }
  109 + } else {
  110 + mActivity.addPrePreviewFragment(media, false);
  111 + }
  112 + }
  113 + }
  114 + }
  115 +
  116 + @Override
  117 + public void itemSelect(boolean isSelect, Media media, int position) {
  118 + processSelectMedias(mActivity, isSelect, media, position);
  119 + }
  120 +
  121 + @Override
  122 + public void itemCameraClick(Media media) {
  123 + processRecord(media);
  124 + }
  125 + });
  126 + }
  127 +
  128 + private void processRecord(Media media) {
  129 + MediaOpenActivityObservable.getInstance().openActivity(new MediaOpenInfo(1, null));
  130 + }
  131 +
  132 + //处理数据选中的状态
  133 + private void processSelectMedias(MediaActivity mActivity, boolean isSelect, Media media, int position) {
  134 + if (isCheckMediaSupport(mActivity, media)) {
  135 + MediaSelectStateObservable.getInstance().selectStateUpdateMedia(media);
  136 + media.setSelect(!isSelect);
  137 + mFragment.mMediaAdapter.notifyItemChanged(position, media);
  138 + }
  139 + }
  140 +
  141 + //判断 文件是否支持外部配置 1.文件从存在不存在 2.文件大小 3.文件格式 4. 特殊需求 5.是否支持gif 6.文件大小 7.单选 选择数量
  142 + public boolean isCheckMediaSupport(MediaActivity mActivity, Media media) {
  143 + if (mActivity.selects.size() >= mActivity.maxNum && !media.isSelect()) {
  144 + showMessage(mActivity.getResources().getString(R.string.msg_amount_limit));
  145 + return false;
  146 + }
  147 +
  148 + //文件是否存在
  149 + if (media.size <= 0) {
  150 + showMessage(mFragment.getResources().getString(R.string.string_file_err));
  151 + return false;
  152 + }
  153 + //文件大小判断 1 图片 3 视频
  154 + if (media.mediaType == 1 && mActivity.maxImageSize < media.size) {
  155 + String size = com.cnlive.media.utlis.FileUtils.fileSize(mActivity.maxImageSize);
  156 + showMessage(mActivity.getResources().getString(R.string.media_msg_size_limit) + size);
  157 + return false;
  158 + }
  159 + if (media.mediaType == 3 && mActivity.maxVideoSize < media.size) {
  160 + String size = com.cnlive.media.utlis.FileUtils.fileSize(mActivity.maxVideoSize);
  161 + showMessage(mFragment.getResources().getString(R.string.media_msg_size_limit) + size);
  162 + return false;
  163 + }
  164 + //文件格式
  165 + if (media.mediaType == 3 && FileTypeUtil.checkVideoType(media.path)) {
  166 + showMessage(mFragment.getResources().getString(R.string.media_msg_video_limit));
  167 + return false;
  168 + }
  169 + //视频时长限制
  170 + if (media.mediaType == 3 && media.duration > mActivity.maxTime) {
  171 + showMessage(mFragment.getResources().getString(R.string.media_msg_time_limit) + (MediaStringUtils.gennerMinSec(mActivity.maxVideoTime / 1000)));
  172 + return false;
  173 + }
  174 + //判断是否支持gif
  175 + if (!mActivity.selectGift && FileTypeUtil.isGif(media.path)) {
  176 + showMessage(mFragment.getResources().getString(R.string.msg_gif_limit));
  177 + return false;
  178 + }
  179 +
  180 + if (mActivity.selectMode == PickerConfig.PICKER_ONLY_ONE_TYPE && mActivity.selects != null && mActivity.selects.size() > 0 && mActivity.selects.get(0).mediaType != media.mediaType) {
  181 + showMessage(mFragment.getResources().getString(R.string.msg_type_limit));
  182 + return false;
  183 + }
  184 + return true;
  185 + }
  186 +
  187 +
  188 + public void showMessage(String message) {
  189 + if (mFragment == null || mFragment.getActivity() == null || TextUtils.isEmpty(message)) {
  190 + return;
  191 + }
  192 + AlertUtil.showDeftToast(mFragment.getActivity(), message);
  193 + }
  194 +
  195 + public void initMediaData(MediaActivity mediaActivity, ArrayList<Folder> medias) {
  196 + if (medias == null) {
  197 + showMessage("数据异常");
  198 + return;
  199 + }
  200 + mediaActivity.allMedias.addAll(medias.get(0).getMedias());
  201 + for (Media select : mediaActivity.selects) {
  202 + if (mediaActivity.allMedias.contains(select)) {
  203 + mediaActivity.allMedias.get(mediaActivity.allMedias.indexOf(select)).setSelect(true);
  204 + }
  205 + }
  206 + List<Media> listMedias = medias.get(0).getMedias();
  207 + if (mediaActivity.needCamera && medias.get(0) != null && medias.get(0).getMedias() != null
  208 + && medias.get(0).getMedias().get(0) != null && medias.get(0).getMedias().get(0).mediaType != 0) {
  209 + listMedias.add(0, new Media(0));
  210 + }
  211 + if (mFragment.mMediaAdapter == null)
  212 + mFragment.mMediaAdapter = new MediaAdapter(mFragment.getActivity(), mediaActivity.showTime, mediaActivity.mOptions);
  213 + mFragment.mMediaAdapter.updateItems(listMedias);
  214 + }
  215 +
  216 + public void showPrew(MediaActivity mActivity) {
  217 + if (mActivity.selects.size() <= 0) {
  218 + showMessage(mFragment.getResources().getString(R.string.select_null));
  219 + } else {
  220 + mActivity.addPrePreviewFragment(mActivity.selects.get(0), true);
  221 + }
  222 + }
  223 +
  224 + public void selectDateUpdate(MediaActivity mActivity, Media isUpdateMedia) {
  225 +
  226 + if (isUpdateMedia != null) {
  227 +// int index = mActivity.allMedias.indexOf(isUpdateMedia);
  228 + mFragment.mMediaAdapter.notifyDataSetChanged();
  229 + }
  230 +
  231 + }
  232 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/view/MediaPreviewView.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/view/MediaPreviewView.java
  1 +package com.cnlive.media.frame.view;
  2 +
  3 +import android.text.TextUtils;
  4 +
  5 +import androidx.activity.OnBackPressedCallback;
  6 +import androidx.viewpager2.widget.ViewPager2;
  7 +
  8 +import com.cnlive.libs.base.util.AlertUtil;
  9 +import com.cnlive.media.ui.activity.MediaActivity;
  10 +import com.cnlive.media.ui.adapter.MediaPreviewAdapter;
  11 +import com.cnlive.media.ui.fragment.MediaPreviewFragment;
  12 +import com.cnlive.media.utlis.observable.MediaPageSelectStateObservable;
  13 +import com.hannesdorfmann.mosby3.mvp.MvpView;
  14 +
  15 +/**
  16 + * 作 者 : wkq
  17 + * <p>
  18 + * 时 间 : 2020/9/17 14:30
  19 + * <p>
  20 + * 名 字 : MediaPreviewview
  21 + * <p>
  22 + * 简 介 :
  23 + */
  24 +public class MediaPreviewView implements MvpView {
  25 + MediaPreviewFragment mFragment;
  26 +
  27 + private int currentPosition = 0;
  28 +
  29 + public MediaPreviewView(MediaPreviewFragment mFragment) {
  30 + this.mFragment = mFragment;
  31 + }
  32 +
  33 + public void initView(MediaActivity mActivity) {
  34 + if (mFragment.isPre) {
  35 + mFragment. mediaPreviewAdapter = new MediaPreviewAdapter(mActivity, mActivity.selects);
  36 + mFragment.binding.viewpager.setAdapter(mFragment.mediaPreviewAdapter);
  37 + mFragment.binding.viewpager.setCurrentItem(0, false);
  38 + mFragment.preMedias = mActivity.selects;
  39 + } else {
  40 + mFragment.preMedias = mActivity.allMedias;
  41 + mFragment.mediaPreviewAdapter = new MediaPreviewAdapter(mActivity, mFragment.preMedias);
  42 + if (mFragment.mMedia == null) {
  43 + currentPosition = 0;
  44 + } else {
  45 + currentPosition = mFragment.preMedias.indexOf(mFragment.mMedia);
  46 +
  47 + mFragment.binding.viewpager.setAdapter(mFragment.mediaPreviewAdapter);
  48 + mFragment.binding.viewpager.setCurrentItem(currentPosition, false);
  49 + }
  50 + }
  51 +
  52 + mFragment.binding.viewpager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
  53 + @Override
  54 + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
  55 + super.onPageScrolled(position, positionOffset, positionOffsetPixels);
  56 + }
  57 +
  58 + @Override
  59 + public void onPageScrollStateChanged(int state) {
  60 + super.onPageScrollStateChanged(state);
  61 + }
  62 +
  63 + @Override
  64 + public void onPageSelected(int position) {
  65 + super.onPageSelected(position);
  66 + mFragment.mMedia = mFragment.preMedias.get(position);
  67 + MediaPageSelectStateObservable.getInstance().pageSelectState(mFragment.mMedia);
  68 + }
  69 + });
  70 + }
  71 +
  72 + /**
  73 + * 处理 fragment 返回的逻辑
  74 + */
  75 + public void initBack(MediaActivity mActivity) {
  76 + mFragment.mback = mFragment.requireActivity().getOnBackPressedDispatcher();
  77 + mFragment.callback = new OnBackPressedCallback(true) {
  78 + @Override
  79 + public void handleOnBackPressed() {
  80 + mFragment.callback.setEnabled(false);
  81 + mFragment.mback.onBackPressed();
  82 + }
  83 + };
  84 + mFragment.mback.addCallback(mFragment, mFragment.callback);
  85 + }
  86 +
  87 +
  88 + public void showMessage(String message) {
  89 + if (mFragment == null || mFragment.getActivity() == null || TextUtils.isEmpty(message))
  90 + return;
  91 + AlertUtil.showDeftToast(mFragment.getActivity(), message);
  92 + }
  93 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/view/MediaPreviewViewView.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/view/MediaPreviewViewView.java
  1 +package com.cnlive.media.frame.view;
  2 +
  3 +import android.content.Intent;
  4 +import android.text.TextUtils;
  5 +import android.view.View;
  6 +import android.widget.ImageView;
  7 +import android.widget.TextView;
  8 +
  9 +import androidx.viewpager2.widget.ViewPager2;
  10 +
  11 +import com.cnlive.libs.base.util.AlertUtil;
  12 +import com.cnlive.libs.base.util.StatusBarUtil2;
  13 +import com.cnlive.media.PickerConfig;
  14 +import com.cnlive.media.meidia.entity.Media;
  15 +import com.cnlive.media.ui.activity.MediaPreviewActivity;
  16 +import com.cnlive.media.ui.adapter.MediaPreviewAdapter;
  17 +import com.cnlive.meidia.R;
  18 +import com.hannesdorfmann.mosby3.mvp.MvpView;
  19 +
  20 +import java.util.ArrayList;
  21 +
  22 +/**
  23 + * 作 者 : wkq
  24 + * <p>
  25 + * 时 间 : 2020/10/23 9:28
  26 + * <p>
  27 + * 名 字 : MediaPreviewViewView
  28 + * <p>
  29 + * 简 介 :
  30 + */
  31 +public class MediaPreviewViewView implements MvpView {
  32 + MediaPreviewActivity mActivity;
  33 +
  34 + public MediaPreviewViewView(MediaPreviewActivity mediaPreviewActivity) {
  35 + mActivity = mediaPreviewActivity;
  36 + }
  37 +
  38 + /**
  39 + * 完成
  40 + */
  41 + public void finishMedia() {
  42 +
  43 + Intent intent = new Intent();
  44 + intent.putParcelableArrayListExtra(PickerConfig.EXTRA_RESULT, mActivity.currentArray);
  45 + mActivity.setResult(mActivity.resultCode, intent);
  46 + mActivity.finish();
  47 + }
  48 +
  49 + public void initView() {
  50 + StatusBarUtil2.setColor(mActivity, mActivity.getResources().getColor(R.color.status_bar_color), 0);
  51 +
  52 + mActivity.binding.preTop.findViewById(R.id.btn_back).setOnClickListener(v -> {
  53 + mActivity.finish();
  54 + });
  55 + mActivity.currentMedia = mActivity.selectLists.get(mActivity.position);
  56 + if (mActivity.currentMedia.isSelect()) {
  57 + ((ImageView) mActivity.binding.preTop.findViewById(R.id.check_image_top)).setImageResource(R.drawable.xc_xuanzhong);
  58 + } else {
  59 + ((ImageView) mActivity.binding.preTop.findViewById(R.id.check_image_top)).setImageResource(R.drawable.xc_weixuan);
  60 + }
  61 + mActivity.currentArray.addAll(mActivity.selectLists);
  62 + mActivity.binding.preTop.findViewById(R.id.check_layout_top).setOnClickListener(v -> {
  63 + if (mActivity.currentMedia != null) {
  64 + int pos = mActivity.selectLists.indexOf(mActivity.currentMedia);
  65 + if (mActivity.currentMedia.isSelect()) {
  66 + if (mActivity.currentArray.contains(mActivity.currentMedia)) {
  67 + mActivity.currentArray.remove(mActivity.currentMedia);
  68 + }
  69 + mActivity.currentMedia.setSelect(false);
  70 + if (mActivity.currentArray.contains(mActivity.currentMedia))
  71 + mActivity.selectLists.get(pos).setSelect(false);
  72 + } else {
  73 + mActivity.currentMedia.setSelect(true);
  74 + mActivity.selectLists.get(pos).setSelect(true);
  75 + if (!mActivity.currentArray.contains(mActivity.currentMedia)) {
  76 + mActivity.currentArray.add(mActivity.currentMedia);
  77 + }
  78 +
  79 + }
  80 + if (mActivity.currentMedia.isSelect()) {
  81 + ((ImageView) mActivity.binding.preTop.findViewById(R.id.check_image_top)).setImageResource(R.drawable.xc_xuanzhong);
  82 + } else {
  83 + ((ImageView) mActivity.binding.preTop.findViewById(R.id.check_image_top)).setImageResource(R.drawable.xc_weixuan);
  84 + }
  85 + }
  86 + });
  87 + mActivity.binding.preTop.findViewById(R.id.done).setVisibility(View.VISIBLE);
  88 + mActivity.binding.preTop.findViewById(R.id.done).setOnClickListener(v -> {
  89 + //返回
  90 + finishMedia();
  91 + });
  92 + mActivity.mediaPreviewAdapter = new MediaPreviewAdapter(mActivity, mActivity.selectLists);
  93 + mActivity.binding.vpPreview.setAdapter(mActivity.mediaPreviewAdapter);
  94 + mActivity.binding.vpPreview.setCurrentItem(mActivity.position, false);
  95 + String barTitleText = String.format(mActivity.getResources().getString(R.string.btn_bar_title), mActivity.position + 1, mActivity.selectLists.size());
  96 + ((TextView) mActivity.binding.preTop.findViewById(R.id.bar_title)).setText(barTitleText);
  97 +
  98 + mActivity.binding.preTop.findViewById(R.id.check_layout_top).setVisibility(View.VISIBLE);
  99 +
  100 + mActivity.binding.vpPreview.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
  101 + @Override
  102 + public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
  103 + super.onPageScrolled(position, positionOffset, positionOffsetPixels);
  104 + }
  105 +
  106 + @Override
  107 + public void onPageScrollStateChanged(int state) {
  108 + super.onPageScrollStateChanged(state);
  109 + }
  110 +
  111 + @Override
  112 + public void onPageSelected(int position) {
  113 + super.onPageSelected(position);
  114 + Media media = mActivity.selectLists.get(position);
  115 + mActivity.currentMedia = media;
  116 + showSelectPrew(media);
  117 + }
  118 + });
  119 +
  120 + }
  121 +
  122 +
  123 + public void showSelectPrew(Media media) {
  124 + String barTitleText = String.format(mActivity.getResources().getString(R.string.btn_bar_title), mActivity.selectLists.indexOf(media) + 1, mActivity.selectLists.size());
  125 + ((TextView) mActivity.binding.preTop.findViewById(R.id.bar_title)).setText(barTitleText);
  126 + mActivity.binding.preTop.findViewById(R.id.check_layout_top).setVisibility(View.VISIBLE);
  127 +
  128 + if (media.isSelect()) {
  129 + ((ImageView) mActivity.binding.preTop.findViewById(R.id.check_image_top)).setImageResource(R.drawable.xc_xuanzhong);
  130 + } else {
  131 + ((ImageView) mActivity.binding.preTop.findViewById(R.id.check_image_top)).setImageResource(R.drawable.xc_weixuan);
  132 + }
  133 +
  134 + }
  135 +
  136 + public void showMessage(String message) {
  137 + if (mActivity == null || TextUtils.isEmpty(message)) {
  138 + return;
  139 + }
  140 + AlertUtil.showDeftToast(mActivity, message);
  141 + }
  142 +
  143 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/view/MediaView.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/view/MediaView.java
  1 +package com.cnlive.media.frame.view;
  2 +
  3 +import android.Manifest;
  4 +import android.app.Dialog;
  5 +import android.graphics.Color;
  6 +import android.graphics.drawable.ColorDrawable;
  7 +import android.media.ExifInterface;
  8 +import android.net.Uri;
  9 +import android.text.TextUtils;
  10 +import android.view.View;
  11 +import android.widget.AdapterView;
  12 +import android.widget.Button;
  13 +import android.widget.ImageView;
  14 +import android.widget.LinearLayout;
  15 +import android.widget.ListPopupWindow;
  16 +import android.widget.TextView;
  17 +
  18 +import androidx.activity.OnBackPressedCallback;
  19 +import androidx.core.app.ActivityCompat;
  20 +import androidx.fragment.app.Fragment;
  21 +import androidx.recyclerview.widget.LinearLayoutManager;
  22 +import androidx.recyclerview.widget.RecyclerView;
  23 +
  24 +import com.cnlive.libs.base.util.AlertUtil;
  25 +import com.cnlive.libs.base.util.FileUtils;
  26 +import com.cnlive.libs.base.util.StatusBarUtil2;
  27 +import com.cnlive.media.PickerConfig;
  28 +import com.cnlive.media.meidia.entity.Folder;
  29 +import com.cnlive.media.meidia.entity.Media;
  30 +import com.cnlive.media.ui.activity.ImageCropActivity;
  31 +import com.cnlive.media.ui.activity.MediaActivity;
  32 +import com.cnlive.media.ui.activity.RecordActivity;
  33 +import com.cnlive.media.ui.adapter.FolderAdapter;
  34 +import com.cnlive.media.ui.adapter.PreviewBottomMediaAdapter;
  35 +import com.cnlive.media.ui.fragment.MediaPickerFragment;
  36 +import com.cnlive.media.ui.fragment.MediaPreviewFragment;
  37 +import com.cnlive.media.utlis.AlertDialogUtils;
  38 +import com.cnlive.media.utlis.AndroidQUtil;
  39 +import com.cnlive.media.utlis.FileTypeUtil;
  40 +import com.cnlive.media.utlis.MediaStringUtils;
  41 +import com.cnlive.media.utlis.PermissionChecker;
  42 +import com.cnlive.media.utlis.ScreenUtils;
  43 +import com.cnlive.media.utlis.observable.MediaAddObservable;
  44 +import com.cnlive.media.utlis.observable.MediaOpenActivityObservable;
  45 +import com.cnlive.media.utlis.observable.MediaPageSelectStateObservable;
  46 +import com.cnlive.media.utlis.observable.MediaSelectStateObservable;
  47 +import com.cnlive.media.utlis.observable.MeidaResultObservable;
  48 +import com.cnlive.media.utlis.observable.SelectStateUpdateObservable;
  49 +import com.cnlive.meidia.R;
  50 +import com.hannesdorfmann.mosby3.mvp.MvpView;
  51 +import com.qiniu.pili.droid.shortvideo.PLShortVideoEnv;
  52 +
  53 +import java.util.ArrayList;
  54 +
  55 +import static com.cnlive.media.PickerConfig.REQUEST_CODE_PERMISSION_CAMERA;
  56 +import static com.cnlive.media.PickerConfig.REQUEST_CODE_PERMISSION_READ;
  57 +
  58 +
  59 +/**
  60 + * 作 者 : wkq
  61 + * <p>
  62 + * 时 间 : 2020/9/15 11:29
  63 + * <p>
  64 + * 名 字 : MediaPickerView
  65 + * <p>
  66 + * 简 介 :
  67 + */
  68 +public class MediaView implements MvpView {
  69 + MediaActivity mActivity;
  70 + Button bDone;
  71 + Button preview;
  72 + TextView barTitle;
  73 + public LinearLayout checkLayout;
  74 + public ImageView checkImage;
  75 + public RecyclerView bottomRv;
  76 + private PreviewBottomMediaAdapter previewBottomAdapter;
  77 +
  78 + public MediaView(MediaActivity mActivity) {
  79 + this.mActivity = mActivity;
  80 + }
  81 +
  82 + public void initView() {
  83 +
  84 + mActivity.binding.top.findViewById(R.id.btn_back).setOnClickListener(mActivity);
  85 + bDone = mActivity.binding.top.findViewById(R.id.done);
  86 + preview = mActivity.binding.footer.findViewById(R.id.preview);
  87 + barTitle = mActivity.binding.top.findViewById(R.id.bar_title);
  88 + checkLayout = mActivity.binding.top.findViewById(R.id.check_layout_top);
  89 + checkImage = mActivity.binding.top.findViewById(R.id.check_image_top);
  90 + bottomRv = mActivity.binding.bottom.findViewById(R.id.bottom_recycler_view);
  91 + checkImage.setOnClickListener(mActivity);
  92 + bDone.setOnClickListener(mActivity);
  93 +
  94 + initState();
  95 + setSelectText(null);
  96 + setTitleBar();
  97 + initFolder();
  98 + if (mActivity.needCrop) {
  99 + preview.setVisibility(View.GONE);
  100 + } else {
  101 + preview.setVisibility(View.VISIBLE);
  102 + }
  103 + }
  104 +
  105 + private void initState() {
  106 + StatusBarUtil2.setColor(mActivity, mActivity.getResources().getColor(R.color.status_bar_color), 0);
  107 + //初始化七牛录制
  108 + PLShortVideoEnv.init(mActivity.getApplicationContext());
  109 + MediaAddObservable.getInstance().addObserver(mActivity);
  110 + MeidaResultObservable.getInstance().addObserver(mActivity);
  111 + MediaSelectStateObservable.getInstance().addObserver(mActivity);
  112 + MediaPageSelectStateObservable.getInstance().addObserver(mActivity);
  113 + MediaOpenActivityObservable.getInstance().addObserver(mActivity);
  114 + //处理fragment 回调
  115 + mActivity.getOnBackPressedDispatcher().addCallback(mActivity, new OnBackPressedCallback(true) {
  116 + @Override
  117 + public void handleOnBackPressed() {
  118 + Fragment currentFragment = mActivity.getSupportFragmentManager().findFragmentById(R.id.frame);
  119 + if (currentFragment instanceof MediaPickerFragment) {
  120 + mActivity.finish();
  121 + } else {
  122 + mActivity.getSupportFragmentManager().popBackStack();
  123 + }
  124 + }
  125 + });
  126 + }
  127 +
  128 + /**
  129 + * 扎实顶部文字
  130 + */
  131 + private void setTitleBar() {
  132 + int type = mActivity.selectMode;
  133 +
  134 + if (type == PickerConfig.PICKER_IMAGE_VIDEO) {
  135 + barTitle.setText(mActivity.getResources().getString(R.string.select_title));
  136 + } else if (type == PickerConfig.PICKER_ONLY_ONE_TYPE) {
  137 + barTitle.setText(mActivity.getResources().getString(R.string.select_title));
  138 + } else if (type == PickerConfig.PICKER_IMAGE) {
  139 + barTitle.setText(mActivity.getResources().getString(R.string.select_image_title));
  140 + } else if (type == PickerConfig.PICKER_VIDEO) {
  141 + barTitle.setText(mActivity.getResources().getString(R.string.select_video_title));
  142 + }
  143 +
  144 +
  145 + }
  146 +
  147 + /**
  148 + * 初始化文件夹
  149 + */
  150 + private void initFolder() {
  151 + ArrayList<Folder> folders = new ArrayList<>();
  152 + mActivity.binding.footer.findViewById(R.id.category_btn).setOnClickListener(mActivity);
  153 + mActivity.mFolderAdapter = new FolderAdapter(folders, mActivity);
  154 + mActivity.mFolderPopupWindow = new ListPopupWindow(mActivity);
  155 + mActivity.mFolderPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
  156 + mActivity.mFolderPopupWindow.setAdapter(mActivity.mFolderAdapter);
  157 + mActivity.mFolderPopupWindow.setHeight((int) (ScreenUtils.getScreenHeight(mActivity) * 0.6));
  158 + mActivity.mFolderPopupWindow.setAnchorView(mActivity.binding.footer);
  159 + mActivity.mFolderPopupWindow.setModal(true);
  160 + mActivity.mFolderPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
  161 + @Override
  162 + public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  163 + mActivity.mFolderAdapter.setSelectIndex(position);
  164 + ((TextView) mActivity.binding.footer.findViewById(R.id.category_btn)).setText(mActivity.mFolderAdapter.getItem(position).name);
  165 + Fragment currentFragment = mActivity.getSupportFragmentManager().findFragmentById(R.id.frame);
  166 + if (currentFragment instanceof MediaPickerFragment) {
  167 + MediaPickerFragment mediaPickerFragment = (MediaPickerFragment) currentFragment;
  168 + mediaPickerFragment.mMediaAdapter.updateItems(mActivity.mFolderAdapter.getSelectMedias());
  169 + }
  170 + mActivity.mFolderPopupWindow.dismiss();
  171 + mActivity.allMedias.clear();
  172 + mActivity.allMedias.addAll(mActivity.mFolderAdapter.getSelectMedias());
  173 +
  174 + }
  175 + });
  176 + }
  177 +
  178 + public boolean hasPermission() {
  179 + return PermissionChecker.checkPermissions(mActivity
  180 + , new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}
  181 + , REQUEST_CODE_PERMISSION_CAMERA, R.string.dialog_imagepicker_permission_sdcard_message);
  182 + }
  183 +
  184 +
  185 + public void showMessage(String message) {
  186 + if (mActivity == null || mActivity.isFinishing() || TextUtils.isEmpty(message))
  187 + return;
  188 + AlertUtil.showDeftToast(mActivity, message);
  189 + }
  190 +
  191 + /**
  192 + * 处理选中的数据
  193 + *
  194 + * @param media
  195 + */
  196 + public void progressSelectMedia(Media media) {
  197 + if (media == null) return;
  198 +
  199 + if (isCheckMediaSupport(media)) {
  200 + if (media.isSelect() && mActivity.selects.contains(media)) {
  201 + media.setSelect(!media.isSelect());
  202 + mActivity.selects.remove(media);
  203 + } else {
  204 + if (!mActivity.selects.contains(media)) {
  205 + media.setSelect(!media.isSelect());
  206 + mActivity.selects.add(media);
  207 + }
  208 + }
  209 + setSelectText(media);
  210 + }
  211 + }
  212 +
  213 + /**
  214 + * 展示选中状态
  215 + *
  216 + * @param media
  217 + */
  218 + public void showPrew(Media media) {
  219 +
  220 + if (mActivity.isPre) {
  221 + String barTitleText = String.format(mActivity.getResources().getString(R.string.btn_bar_title), mActivity.selects.indexOf(media) + 1, mActivity.selects.size());
  222 + barTitle.setText(barTitleText);
  223 + checkLayout.setVisibility(View.GONE);
  224 + } else {
  225 + String barTitleText = String.format(mActivity.getResources().getString(R.string.btn_bar_title), mActivity.allMedias.indexOf(media) + 1, mActivity.allMedias.size());
  226 + barTitle.setText(barTitleText);
  227 + checkLayout.setVisibility(View.VISIBLE);
  228 + }
  229 +
  230 + if (media.isSelect()) {
  231 + checkImage.setImageResource(R.drawable.xc_xuanzhong);
  232 + } else {
  233 + checkImage.setImageResource(R.drawable.xc_weixuan);
  234 + }
  235 + if (previewBottomAdapter != null) {
  236 + previewBottomAdapter.updateBgState(mActivity.selects.indexOf(media));
  237 + }
  238 + }
  239 +
  240 + /**
  241 + * 展示底部预览
  242 + *
  243 + * @param mMedia
  244 + */
  245 + public void showPrewBottom(Media mMedia) {
  246 + mActivity.binding.footer.setVisibility(View.GONE);
  247 + bottomRv.setLayoutManager(new LinearLayoutManager(mActivity, LinearLayoutManager.HORIZONTAL, false));
  248 + if (mActivity.selects.indexOf(mMedia) < 0) {
  249 + previewBottomAdapter = new PreviewBottomMediaAdapter(mActivity, 0, mActivity.isPre);
  250 + } else {
  251 + previewBottomAdapter = new PreviewBottomMediaAdapter(mActivity, mActivity.selects.indexOf(mMedia), mActivity.isPre);
  252 + }
  253 + bottomRv.setAdapter(previewBottomAdapter);
  254 + if (mActivity.selects != null && mActivity.selects.size() > 0) {
  255 + bottomRv.setItemAnimator(null);
  256 + if (mActivity.selects.size() > 0) {
  257 + mActivity.binding.bottom.setVisibility(View.VISIBLE);
  258 + previewBottomAdapter.addItems(mActivity.selects);
  259 + } else {
  260 + mActivity.binding.bottom.setVisibility(View.GONE);
  261 + }
  262 + }
  263 +
  264 + previewBottomAdapter.setOnItemClickListener(new PreviewBottomMediaAdapter.OnBottomItemClickListener() {
  265 + @Override
  266 + public void onItemClick(int position, Media media) {
  267 + Fragment currentFragment = mActivity.getSupportFragmentManager().findFragmentById(R.id.frame);
  268 + if (currentFragment instanceof MediaPreviewFragment) {
  269 + ((MediaPreviewFragment) currentFragment).showMediaPosition(media);
  270 + previewBottomAdapter.updateBgState(position);
  271 + }
  272 + }
  273 + });
  274 + }
  275 +
  276 + /**
  277 + * 选中文字
  278 + *
  279 + * @param media
  280 + */
  281 + public void setSelectText(Media media) {
  282 + if (mActivity.selects.size() > 0) {
  283 + String finishText = String.format(mActivity.getResources().getString(R.string.btn_imagepicker_ok), mActivity.selects.size(), mActivity.maxNum);
  284 + bDone.setText(finishText);
  285 + bDone.setVisibility(View.VISIBLE);
  286 + } else {
  287 + bDone.setText("");
  288 + bDone.setVisibility(View.GONE);
  289 + }
  290 + setBottomPreSize(mActivity.selects.size());
  291 + }
  292 +
  293 + public void setBottomPreSize(int size) {
  294 + preview.setOnClickListener(mActivity);
  295 + if (mActivity.needCrop) {
  296 + preview.setVisibility(View.GONE);
  297 + } else {
  298 + preview.setVisibility(View.VISIBLE);
  299 + if (size <= 0) {
  300 + preview.setText("预览");
  301 + } else {
  302 + String preText = String.format(mActivity.getResources().getString(R.string.btn_imagepicker_prev), size);
  303 + preview.setText(preText);
  304 + }
  305 + }
  306 +
  307 +
  308 + }
  309 +
  310 + public void processShowBack() {
  311 + checkLayout.setVisibility(View.GONE);
  312 + mActivity.binding.bottom.setVisibility(View.GONE);
  313 + mActivity.binding.footer.setVisibility(View.VISIBLE);
  314 + setTitleBar();
  315 + }
  316 +
  317 +
  318 + //判断 文件是否支持外部配置 1.文件从存在不存在 2.文件大小 3.文件格式 4. 特殊需求 5.是否支持gif 6.文件大小 7.单选 选择数量
  319 + public boolean isCheckMediaSupport(Media media) {
  320 +
  321 + if (mActivity.selects.size() >= mActivity.maxNum && !media.isSelect()) {
  322 + showMessage(mActivity.getResources().getString(R.string.msg_amount_limit));
  323 + return false;
  324 + }
  325 + //文件是否存在
  326 + //文件是否存在
  327 + if (media.size <= 0) {
  328 + showMessage(mActivity.getResources().getString(R.string.string_file_err));
  329 + return false;
  330 + }
  331 + //文件大小判断 1 图片 3 视频
  332 + if (media.mediaType == 1 && mActivity.maxImageSize < media.size) {
  333 + String size = com.cnlive.media.utlis.FileUtils.fileSize(mActivity.maxImageSize);
  334 + showMessage(mActivity.getResources().getString(R.string.media_msg_size_limit) + size);
  335 + return false;
  336 + }
  337 + if (media.mediaType == 3 && mActivity.maxVideoSize < media.size) {
  338 + String size = com.cnlive.media.utlis.FileUtils.fileSize(mActivity.maxVideoSize);
  339 + showMessage(mActivity.getResources().getString(R.string.media_msg_size_limit) + size);
  340 + return false;
  341 + }
  342 + //文件格式
  343 + if (media.mediaType == 3 && FileTypeUtil.checkVideoType(media.path)) {
  344 + showMessage(mActivity.getResources().getString(R.string.media_msg_video_limit));
  345 + return false;
  346 + }
  347 + //视频时长限制
  348 + if (media.mediaType == 3 && media.duration > mActivity.maxTime) {
  349 + showMessage(mActivity.getResources().getString(R.string.media_msg_time_limit) + (MediaStringUtils.gennerMinSec(mActivity.maxTime / 1000)));
  350 + return false;
  351 + }
  352 + //判断是否支持gif
  353 + if (!mActivity.selectGift && FileTypeUtil.isGif(media.path)) {
  354 + showMessage(mActivity.getResources().getString(R.string.msg_gif_limit));
  355 + return false;
  356 + }
  357 +
  358 + if (mActivity.selectMode == PickerConfig.PICKER_ONLY_ONE_TYPE && mActivity.selects != null && mActivity.selects.size() > 0 && mActivity.selects.get(0).mediaType != media.mediaType) {
  359 + showMessage(mActivity.getResources().getString(R.string.msg_type_limit));
  360 + return false;
  361 + }
  362 + return true;
  363 + }
  364 +
  365 + /**
  366 + * 处理选中和取消选中状态的逻辑
  367 + */
  368 + public void processCheckMeida() {
  369 + Fragment currentFragment = mActivity.getSupportFragmentManager().findFragmentById(R.id.frame);
  370 + if (currentFragment instanceof MediaPreviewFragment) {
  371 + MediaPreviewFragment curF = (MediaPreviewFragment) currentFragment;
  372 + Media curM = curF.getCurrentMedia();
  373 + processCheckMeidaState(curM);
  374 + progressCheckSelectMedia(curF, curM);
  375 + SelectStateUpdateObservable.getInstance().stateUpdate(curM);
  376 + if (mActivity.selects.size() > 0) {
  377 + mActivity.binding.bottom.setVisibility(View.VISIBLE);
  378 + } else {
  379 + mActivity.binding.bottom.setVisibility(View.GONE);
  380 + }
  381 + if (previewBottomAdapter != null) previewBottomAdapter.notifyDataSetChanged();
  382 + }
  383 +
  384 +
  385 + }
  386 +
  387 + /**
  388 + * 处理预览页面选中后数据的更新问题
  389 + *
  390 + * @param curF
  391 + * @param curM
  392 + */
  393 + private void progressCheckSelectMedia(MediaPreviewFragment curF, Media curM) {
  394 +
  395 + if (curM == null || !isCheckMediaSupport(curM)) return;
  396 + boolean isContains = mActivity.selects.contains(curM);
  397 + if (curM.isSelect() && isContains) {
  398 + int index = mActivity.selects.indexOf(curM);
  399 + mActivity.selects.remove(curM);
  400 + if (previewBottomAdapter != null && index >= 0) {
  401 + previewBottomAdapter.removeItem(index);
  402 + previewBottomAdapter.notifyItemRemoved(index);
  403 + }
  404 + curM.setSelect(!curM.isSelect());
  405 + } else {
  406 + if (!isContains) {
  407 + curM.setSelect(!curM.isSelect());
  408 + mActivity.selects.add(curM);
  409 + if (previewBottomAdapter != null) previewBottomAdapter.addItem(curM);
  410 + }
  411 + }
  412 + setSelectText(curM);
  413 + curF.setMediaSelect(curM.isSelect());
  414 + }
  415 +
  416 +
  417 + public void processCheckMeidaState(Media media) {
  418 + if (isCheckMediaSupport(media)) {
  419 + if (!media.isSelect()) {
  420 + checkImage.setImageResource(R.drawable.xc_xuanzhong);
  421 + } else {
  422 + checkImage.setImageResource(R.drawable.xc_weixuan);
  423 + }
  424 + }
  425 +
  426 + }
  427 +
  428 + /**
  429 + * 预览页面滑动
  430 + *
  431 + * @param media
  432 + */
  433 + public void showSelectPrew(Media media) {
  434 + if (mActivity.isPre) {
  435 + String barTitleText = String.format(mActivity.getResources().getString(R.string.btn_bar_title), mActivity.selects.indexOf(media) + 1, mActivity.selects.size());
  436 + barTitle.setText(barTitleText);
  437 + checkLayout.setVisibility(View.GONE);
  438 + } else {
  439 + String barTitleText = String.format(mActivity.getResources().getString(R.string.btn_bar_title), mActivity.allMedias.indexOf(media) + 1, mActivity.allMedias.size());
  440 + barTitle.setText(barTitleText);
  441 + checkLayout.setVisibility(View.VISIBLE);
  442 + }
  443 +
  444 + if (media.isSelect()) {
  445 + checkImage.setImageResource(R.drawable.xc_xuanzhong);
  446 + } else {
  447 + checkImage.setImageResource(R.drawable.xc_weixuan);
  448 + }
  449 +
  450 + if (previewBottomAdapter != null) {
  451 + previewBottomAdapter.updateBgState(mActivity.selects.indexOf(media));
  452 + }
  453 + }
  454 +
  455 + //打开 录制页面
  456 + public void openRecord() {
  457 + boolean hasPermissions = mActivity.getPresenter()
  458 + .checkPermissions(mActivity, mActivity.permissionsRecord, REQUEST_CODE_PERMISSION_CAMERA, mActivity.getResources().getString(R.string.dialog_imagepicker_permission_camera_nerver_ask_message), false);
  459 + if (hasPermissions) {
  460 + RecordActivity.newInstance(mActivity, mActivity.mOptions);
  461 + }
  462 + }
  463 +
  464 + //打开 裁剪页面
  465 + public void openCrop(Media media) {
  466 + boolean hasPermissions = mActivity.getPresenter()
  467 + .checkPermissions(mActivity, mActivity.permissionsRead, REQUEST_CODE_PERMISSION_READ, mActivity.getResources().getString(R.string.dialog_imagepicker_permission_sdcard_nerver_ask_message), false);
  468 + if (hasPermissions) {
  469 + if (AndroidQUtil.isAndroidQ()) {
  470 + //获取源数据的照片信息
  471 + ExifInterface oldExif = AndroidQUtil.getExifInterface(mActivity, Uri.parse(media.fileUri));
  472 + String filePath = AndroidQUtil.saveSignImageBox(mActivity, "tempCrop.png", AndroidQUtil.getBitmapFromUri(mActivity, Uri.parse(media.fileUri)));
  473 + if (null != oldExif && !TextUtils.isEmpty(filePath)) {
  474 + try {
  475 + //将源数据的exif信息复制一份给新的
  476 + AndroidQUtil.saveExif(oldExif, filePath);
  477 + } catch (Exception e) {
  478 + e.printStackTrace();
  479 + }
  480 + }
  481 + ImageCropActivity.start(mActivity, filePath, mActivity.mOptions);
  482 + } else {
  483 + ImageCropActivity.start(mActivity, media.path, mActivity.mOptions);
  484 + }
  485 +
  486 +
  487 + }
  488 +
  489 +
  490 + }
  491 +
  492 + /**
  493 + * 弹出拒绝后的弹框
  494 + *
  495 + * @param needList 权限列表
  496 + * @param requestCode 请求吗
  497 + * @param message 展示信息
  498 + * @param isFinish 是否需要关闭页面
  499 + */
  500 + public void showPermission(String[] needList, int requestCode, String message, boolean isFinish) {
  501 + if (mActivity.dialog != null) mActivity.dialog.dismiss();
  502 + mActivity.dialog = AlertDialogUtils.showTwoButtonDialog(
  503 + mActivity,
  504 + mActivity.getString(R.string.dialog_imagepicker_permission_nerver_ask_cancel),
  505 + mActivity.getString(R.string.dialog_imagepicker_permission_confirm),
  506 + message,
  507 + R.color.color_dialog_btn, R.color.color_ffa300, new AlertDialogUtils.DialogTwoListener() {
  508 + @Override
  509 + public void onClickLeft(Dialog dialog) {
  510 + dialog.dismiss();
  511 + showMessage(message);
  512 + if (isFinish) mActivity.finish();
  513 + }
  514 +
  515 + @Override
  516 + public void onClickRight(Dialog dialog) {
  517 + dialog.dismiss();
  518 + ActivityCompat.requestPermissions(mActivity, needList, requestCode);
  519 + }
  520 + });
  521 + }
  522 +
  523 + /**
  524 + * 权限拒绝后展示
  525 + *
  526 + * @param requestCode 请求吗
  527 + * @param message
  528 + * @param isFinish 是否销毁页面
  529 + */
  530 + public void showPermissionPerpetual(int requestCode, String message, boolean isFinish) {
  531 +
  532 + if (mActivity.dialog != null) mActivity.dialog.dismiss();
  533 + mActivity.dialog = AlertDialogUtils.showTwoButtonDialog(
  534 + mActivity,
  535 + mActivity.getString(R.string.dialog_imagepicker_permission_nerver_ask_cancel),
  536 + mActivity.getString(R.string.dialog_imagepicker_permission_confirm),
  537 + message,
  538 + R.color.color_dialog_btn, R.color.color_ffa300, new AlertDialogUtils.DialogTwoListener() {
  539 + @Override
  540 + public void onClickLeft(Dialog dialog) {
  541 + dialog.dismiss();
  542 + showMessage(message);
  543 + if (isFinish)
  544 + mActivity.finish();
  545 + }
  546 +
  547 + @Override
  548 + public void onClickRight(Dialog dialog) {
  549 + dialog.dismiss();
  550 + PermissionChecker.settingPermissionActivity(mActivity, requestCode);
  551 + mActivity.isNeverAsk = true;
  552 + }
  553 + });
  554 + }
  555 +
  556 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/view/RecordPreviewView.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/view/RecordPreviewView.java
  1 +package com.cnlive.media.frame.view;
  2 +
  3 +import android.animation.AnimatorSet;
  4 +import android.animation.ObjectAnimator;
  5 +import android.content.Intent;
  6 +import android.net.Uri;
  7 +import android.text.TextUtils;
  8 +import android.view.View;
  9 +import android.view.ViewGroup;
  10 +import android.view.animation.OvershootInterpolator;
  11 +import android.widget.FrameLayout;
  12 +import android.widget.RelativeLayout;
  13 +
  14 +import com.cnlive.libs.base.util.AlertUtil;
  15 +import com.cnlive.media.PickerConfig;
  16 +import com.cnlive.media.meidia.entity.Media;
  17 +import com.cnlive.media.ui.activity.ImageCropActivity;
  18 +import com.cnlive.media.ui.activity.RecordActivity;
  19 +import com.cnlive.media.ui.fragment.RecordPreviewFragment;
  20 +import com.cnlive.media.utlis.AndroidQUtil;
  21 +import com.cnlive.media.utlis.GlideCacheUtil;
  22 +import com.cnlive.media.utlis.MediaUtils;
  23 +import com.cnlive.media.utlis.album.AlbumProcessUtil;
  24 +import com.cnlive.media.utlis.album.OnSaveCallback;
  25 +import com.cnlive.media.utlis.observable.MediaAddObservable;
  26 +import com.cnlive.media.utlis.observable.MeidaResultObservable;
  27 +import com.hannesdorfmann.mosby3.mvp.MvpView;
  28 +import com.qiniu.pili.droid.shortvideo.PLDisplayMode;
  29 +import com.qiniu.pili.droid.shortvideo.PLMediaFile;
  30 +import com.qiniu.pili.droid.shortvideo.PLShortVideoEditor;
  31 +import com.qiniu.pili.droid.shortvideo.PLShortVideoTrimmer;
  32 +import com.qiniu.pili.droid.shortvideo.PLVideoEditSetting;
  33 +
  34 +import java.io.File;
  35 +import java.util.ArrayList;
  36 +
  37 +/**
  38 + * 作 者 : wkq
  39 + * <p>
  40 + * 时 间 : 2020/9/28 9:35
  41 + * <p>
  42 + * 名 字 : RecordPreviewView
  43 + * <p>
  44 + * 简 介 :
  45 + */
  46 +public class RecordPreviewView implements MvpView {
  47 + RecordPreviewFragment mFragment;
  48 + private PLMediaFile mMediaFile;
  49 +
  50 + public RecordPreviewView(RecordPreviewFragment mFragment) {
  51 + this.mFragment = mFragment;
  52 + }
  53 +
  54 + public void initView(RecordActivity mActivity) {
  55 +
  56 + if (mFragment.type == 0) {
  57 + mFragment.binding.ivPre.setVisibility(View.VISIBLE);
  58 + mFragment.binding.flVideo.setVisibility(View.GONE);
  59 + GlideCacheUtil.intoItemImageBitmap(mActivity, mActivity.preBitmap, mFragment.binding.ivPre);
  60 + } else if (mFragment.type == 1) {
  61 + mFragment.binding.ivPre.setVisibility(View.GONE);
  62 + mFragment.binding.flVideo.setVisibility(View.VISIBLE);
  63 + }
  64 +
  65 + ObjectAnimator animator_cancel = ObjectAnimator.ofFloat(mFragment.binding.tbOk, "translationX", 200, 0);
  66 + ObjectAnimator animator_confirm = ObjectAnimator.ofFloat(mFragment.binding.tbCancel, "translationX", -200, 0);
  67 +
  68 + AnimatorSet set = new AnimatorSet();
  69 + set.playTogether(animator_cancel, animator_confirm);
  70 + set.setInterpolator(new OvershootInterpolator());
  71 + set.setDuration(200);
  72 + set.start();
  73 +
  74 + }
  75 +
  76 + public void initPre() {
  77 + mMediaFile = new PLMediaFile(mFragment.path);
  78 + PLVideoEditSetting setting = new PLVideoEditSetting();
  79 + setting.setSourceFilepath(mFragment.path);
  80 + setting.setGifPreviewEnabled(false);
  81 + if (mFragment.mShortVideoEditor == null)
  82 + mFragment.mShortVideoEditor = new PLShortVideoEditor(mFragment.binding.gvVideo);
  83 + mFragment.mShortVideoEditor.setVideoEditSetting(setting);
  84 + mFragment.mShortVideoEditor.setPlaybackLoop(true);
  85 + mFragment.mShortVideoEditor.setDisplayMode(PLDisplayMode.FULL);
  86 + mFragment.mShortVideoEditor.startPlayback();
  87 + mFragment.isPlaying = true;
  88 + }
  89 +
  90 + private void initGlSurfaceView() {
  91 + RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mFragment.binding.flVideo.getLayoutParams();
  92 + FrameLayout.LayoutParams surfaceLayout = (FrameLayout.LayoutParams) mFragment.binding.gvVideo.getLayoutParams();
  93 + int outputWidth = mMediaFile.getVideoWidth();
  94 + int outputHeight = mMediaFile.getVideoHeight();
  95 + int rotation = mMediaFile.getVideoRotation();
  96 + if ((rotation == 90 || rotation == 270)) {
  97 + int temp = outputWidth;
  98 + outputWidth = outputHeight;
  99 + outputHeight = temp;
  100 + }
  101 +
  102 + surfaceLayout.width = mFragment.mScreenSize.x;
  103 + surfaceLayout.height = Math.round((float) outputHeight * mFragment.mScreenSize.x / outputWidth);
  104 + ViewGroup.MarginLayoutParams marginParams = null;
  105 + if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
  106 + marginParams = (ViewGroup.MarginLayoutParams) surfaceLayout;
  107 + } else {
  108 + marginParams = new ViewGroup.MarginLayoutParams(surfaceLayout);
  109 + }
  110 + mFragment.binding.flVideo.setLayoutParams(layoutParams);
  111 + mFragment.binding.gvVideo.setLayoutParams(marginParams);
  112 + }
  113 +
  114 + public void showMessage(String message) {
  115 + if (mFragment == null || TextUtils.isEmpty(message)) return;
  116 + AlertUtil.showDeftToast(mFragment.getActivity(), message);
  117 + }
  118 +
  119 + public void showSuccessMessage(String message) {
  120 + if (mFragment == null || TextUtils.isEmpty(message)) return;
  121 + AlertUtil.showSuccessToast(mFragment.getActivity(), message);
  122 + }
  123 +
  124 + public void savePic(RecordActivity mActivity) {
  125 +
  126 + AlbumProcessUtil.saveBitmap(mActivity, mActivity.preBitmap, new OnSaveCallback() {
  127 + @Override
  128 + public void onSuccess(String path) {
  129 + File file = new File(path);
  130 + if (file != null && file.exists() && file.canRead() && file.canWrite()) {
  131 + Media media = new Media(path, file.getName(), System.currentTimeMillis(), 1, file.length(), (int) System.currentTimeMillis(), file.getParent(), Uri.fromFile(file).toString());
  132 + media.setSelect(false);
  133 + media.setReturnUri(mActivity.mOptions.isReturnUri());
  134 + if (mActivity.preBitmap != null && mActivity.preBitmap.getHeight() > 0 && mActivity.preBitmap.getWidth() > 0) {
  135 + media.setImgHeight(mActivity.preBitmap.getHeight());
  136 + media.setImgWidth(mActivity.preBitmap.getWidth());
  137 + media.setLongImg(MediaUtils.isLongImg(mActivity.preBitmap.getWidth(), mActivity.preBitmap.getHeight()));
  138 + }
  139 + if (mActivity.mOptions.needCrop) {
  140 + ImageCropActivity.start(mActivity, path, mActivity.mOptions);
  141 + } else if (mActivity.mOptions.isSinglePick() || mActivity.mOptions.getMaxImageSize() == 1) {
  142 + MeidaResultObservable.getInstance().finishMedia(true, media);
  143 + mActivity.finish();
  144 + } else if (mActivity.isJumpCamera) {
  145 + if (mActivity.selectMedia == null)
  146 + mActivity.selectMedia = new ArrayList<Media>();
  147 + mActivity.selectMedia.add(media);
  148 + Intent intent = new Intent();
  149 + intent.putParcelableArrayListExtra(PickerConfig.EXTRA_RESULT, mActivity.selectMedia);
  150 + mActivity.setResult(mActivity.resultCode, intent);
  151 + mActivity.finish();
  152 + } else {
  153 + MediaAddObservable.getInstance().addMedia(media);
  154 + mActivity.finish();
  155 + }
  156 +
  157 + } else {
  158 + mFragment.requireActivity().getOnBackPressedDispatcher().onBackPressed();
  159 + }
  160 + }
  161 +
  162 + @Override
  163 + public void onFail(String message) {
  164 + showMessage("图片保存异常");
  165 + }
  166 + });
  167 + }
  168 +
  169 + public void saveVideo(RecordActivity mActivity) {
  170 + if (mMediaFile == null || mActivity == null) return;
  171 + File file = new File(mMediaFile.getFilepath());
  172 + Media media = new Media(mMediaFile.getFilepath(), file.getName(), System.currentTimeMillis(), 3, file.length(), (int) System.currentTimeMillis(), file.getParent(), (int) mMediaFile.getDurationMs(), Uri.fromFile(file).toString());
  173 + media.setImgWidth(mMediaFile.getVideoWidth());
  174 + media.setImgHeight(mMediaFile.getVideoHeight());
  175 + media.setSelect(false);
  176 + media.setReturnUri(mActivity.mOptions.isReturnUri());
  177 + if (mActivity.isJumpCamera) {
  178 + MeidaResultObservable.getInstance().finishMedia(true, media);
  179 + } else if (mActivity.mOptions.isSinglePick() || mActivity.mOptions.getMaxImageSize() == 1) {
  180 + MeidaResultObservable.getInstance().finishMedia(true, media);
  181 + mActivity.finish();
  182 + } else if (mActivity.mOptions.needCrop) {
  183 + RecordActivity.newInstance(mActivity, mActivity.mOptions);
  184 + mActivity.finish();
  185 + } else {
  186 + MediaAddObservable.getInstance().addMedia(media);
  187 + mActivity.finish();
  188 + }
  189 +
  190 + mMediaFile.release();
  191 +
  192 + }
  193 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/view/RecordView.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/view/RecordView.java
  1 +package com.cnlive.media.frame.view;
  2 +
  3 +import android.animation.Animator;
  4 +import android.animation.AnimatorSet;
  5 +import android.animation.ObjectAnimator;
  6 +import android.app.Dialog;
  7 +import android.content.pm.ActivityInfo;
  8 +import android.graphics.Bitmap;
  9 +import android.os.Build;
  10 +import android.os.Environment;
  11 +import android.text.TextUtils;
  12 +import android.util.Log;
  13 +import android.view.MotionEvent;
  14 +import android.view.View;
  15 +import android.view.animation.OvershootInterpolator;
  16 +
  17 +import androidx.activity.OnBackPressedCallback;
  18 +import androidx.core.app.ActivityCompat;
  19 +import androidx.fragment.app.Fragment;
  20 +
  21 +import com.cnlive.libs.base.util.AlertUtil;
  22 +import com.cnlive.media.PickerConfig;
  23 +import com.cnlive.media.ui.activity.RecordActivity;
  24 +import com.cnlive.media.ui.fragment.RecordPreviewFragment;
  25 +import com.cnlive.media.utlis.AlertDialogUtils;
  26 +import com.cnlive.media.utlis.AndroidQUtil;
  27 +import com.cnlive.media.utlis.PermissionChecker;
  28 +import com.cnlive.media.utlis.ScreenUtils;
  29 +import com.cnlive.meidia.R;
  30 +import com.hannesdorfmann.mosby3.mvp.MvpView;
  31 +import com.qiniu.pili.droid.shortvideo.PLAudioEncodeSetting;
  32 +import com.qiniu.pili.droid.shortvideo.PLCameraSetting;
  33 +import com.qiniu.pili.droid.shortvideo.PLDisplayMode;
  34 +import com.qiniu.pili.droid.shortvideo.PLErrorCode;
  35 +import com.qiniu.pili.droid.shortvideo.PLFocusListener;
  36 +import com.qiniu.pili.droid.shortvideo.PLMicrophoneSetting;
  37 +import com.qiniu.pili.droid.shortvideo.PLRecordSetting;
  38 +import com.qiniu.pili.droid.shortvideo.PLRecordStateListener;
  39 +import com.qiniu.pili.droid.shortvideo.PLScreenRecorderSetting;
  40 +import com.qiniu.pili.droid.shortvideo.PLShortVideoRecorder;
  41 +import com.qiniu.pili.droid.shortvideo.PLVideoEncodeSetting;
  42 +
  43 +import java.io.File;
  44 +
  45 +/**
  46 + * 作 者 : wkq
  47 + * <p>
  48 + * 时 间 : 2020/9/22 13:32
  49 + * <p>
  50 + * 名 字 : RecordView
  51 + * <p>
  52 + * 简 介 :
  53 + */
  54 +public class RecordView implements MvpView, PLRecordStateListener {
  55 +
  56 + RecordActivity mActivity;
  57 + private PLRecordSetting recordSetting;
  58 + private PLAudioEncodeSetting audioEncodeSetting;
  59 + private PLMicrophoneSetting microphoneSetting;
  60 + private PLVideoEncodeSetting videoEncodeSetting;
  61 + private PLCameraSetting cameraSetting;
  62 + String videoCaceDirPath;
  63 +
  64 + public RecordView(RecordActivity mActivity) {
  65 + this.mActivity = mActivity;
  66 + }
  67 +
  68 + public void initView() {
  69 + //处理fragment 回调
  70 + mActivity.getOnBackPressedDispatcher().addCallback(mActivity, new OnBackPressedCallback(true) {
  71 + @Override
  72 + public void handleOnBackPressed() {
  73 + Fragment currentFragment = mActivity.getSupportFragmentManager().findFragmentById(R.id.pre_frame);
  74 + if (currentFragment instanceof RecordPreviewFragment) {
  75 + showControl();
  76 + mActivity.getSupportFragmentManager().popBackStack();
  77 + } else {
  78 + mActivity.finish();
  79 + }
  80 + }
  81 + });
  82 +
  83 + if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
  84 + mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  85 + }
  86 + checkPermisssion();
  87 + }
  88 +
  89 + //检测权限
  90 + public void checkPermisssion() {
  91 +
  92 + boolean hasPermissions = mActivity.getPresenter()
  93 + .checkPermissions(mActivity, mActivity.permissionsRecord, mActivity.PERMISISSION_CODE_ASK, true);
  94 + if (hasPermissions) {
  95 + initQNRecord();
  96 + }
  97 + }
  98 +
  99 + public void showControl() {
  100 +
  101 + mActivity.runOnUiThread(new Runnable() {
  102 + @Override
  103 + public void run() {
  104 + mActivity.binding.gSf.setVisibility(View.VISIBLE);
  105 + mActivity.binding.rcControl.setVisibility(View.VISIBLE);
  106 + mActivity.binding.preFrame.setVisibility(View.GONE);
  107 + }
  108 + });
  109 + }
  110 +
  111 + public void showPre() {
  112 + mActivity.runOnUiThread(new Runnable() {
  113 + @Override
  114 + public void run() {
  115 + mActivity.binding.gSf.setVisibility(View.GONE);
  116 + mActivity.binding.rcControl.setVisibility(View.GONE);
  117 + mActivity.binding.preFrame.setVisibility(View.VISIBLE);
  118 + }
  119 + });
  120 +
  121 + }
  122 +
  123 + private PLCameraSetting.CAMERA_FACING_ID chooseCameraFacingId() {
  124 + if (PLCameraSetting.hasCameraFacing(PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_3RD)) {
  125 + return PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_3RD;
  126 + } else if (PLCameraSetting.hasCameraFacing(PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_BACK)) {
  127 + return PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_BACK;
  128 + } else {
  129 + return PLCameraSetting.CAMERA_FACING_ID.CAMERA_FACING_FRONT;
  130 + }
  131 + }
  132 +
  133 + @Override
  134 + public void onReady() {
  135 + //设置闪光灯
  136 + mActivity.isReady = true;
  137 + }
  138 +
  139 + @Override
  140 + public void onError(int i) {
  141 + processError(i);
  142 + mActivity.isReady=false;
  143 + mActivity.isRecordIng=false;
  144 + }
  145 +
  146 + @Override
  147 + public void onDurationTooShort() {
  148 + Log.e("", "");
  149 + }
  150 +
  151 + @Override
  152 + public void onRecordStarted() {
  153 + Log.e("", "");
  154 + }
  155 +
  156 + @Override
  157 + public void onSectionRecording(long l, long l1, int i) {
  158 + Log.e("", "");
  159 + }
  160 +
  161 + @Override
  162 + public void onRecordStopped() {
  163 + Log.e("", "");
  164 + }
  165 +
  166 + @Override
  167 + public void onSectionIncreased(long l, long l1, int i) {
  168 + Log.e("", "");
  169 + }
  170 +
  171 + @Override
  172 + public void onSectionDecreased(long l, long l1, int i) {
  173 + Log.e("", "");
  174 + }
  175 +
  176 + @Override
  177 + public void onRecordCompleted() {
  178 + mActivity.isReady=false;
  179 + mActivity.isRecordIng=false;
  180 + }
  181 +
  182 + /**
  183 + * 初始化七牛录制
  184 + */
  185 + private void initQNRecord() {
  186 + // 摄像头采集选项
  187 + if (mActivity.plShortVideoRecorder == null)
  188 + mActivity.plShortVideoRecorder = new PLShortVideoRecorder();
  189 + if (cameraSetting == null)
  190 + cameraSetting = new PLCameraSetting();
  191 + //设置摄像头
  192 + cameraSetting.setCameraId(chooseCameraFacingId());
  193 + cameraSetting.setCameraPreviewSizeRatio(PLCameraSetting.CAMERA_PREVIEW_SIZE_RATIO.RATIO_16_9);
  194 + cameraSetting.setCameraPreviewSizeLevel(PLCameraSetting.CAMERA_PREVIEW_SIZE_LEVEL.PREVIEW_SIZE_LEVEL_720P);
  195 + // 麦克风采集选项
  196 + if (microphoneSetting == null)
  197 + microphoneSetting = new PLMicrophoneSetting();
  198 + // 视频编码选项
  199 + videoEncodeSetting = new PLVideoEncodeSetting(mActivity);
  200 + videoEncodeSetting.setEncodingSizeLevel(PLVideoEncodeSetting.VIDEO_ENCODING_SIZE_LEVEL.VIDEO_ENCODING_SIZE_LEVEL_720P_3); // 480x480
  201 + videoEncodeSetting.setEncodingBitrate( 4000 * 1024); // 1000kbps
  202 + videoEncodeSetting.setHWCodecEnabled(true); // true:硬编 false:软编
  203 + // 音频编码选项
  204 + audioEncodeSetting = new PLAudioEncodeSetting();
  205 + audioEncodeSetting.setHWCodecEnabled(true); // true:硬编 false:软编
  206 + // 美颜选项
  207 + // 录制选项
  208 + recordSetting = new PLRecordSetting();
  209 +// 最大录制时常
  210 + recordSetting.setMaxRecordDuration(mActivity.mOptions.getMaxTime());
  211 + recordSetting.setRecordSpeedVariable(true);
  212 + recordSetting.setDisplayMode(PLDisplayMode.FULL);
  213 +
  214 +
  215 + if (TextUtils.isEmpty(mActivity.mOptions.getCachePath())) {
  216 + if (AndroidQUtil.isAndroidQ()) {
  217 + videoCaceDirPath = mActivity.getExternalFilesDir("").getPath() + File.separator + "MediaPickerVideo";
  218 + } else {
  219 + videoCaceDirPath = Environment.getExternalStorageDirectory().getPath() + File.separator + "MediaPickerVideo";
  220 + }
  221 + } else {
  222 + if (AndroidQUtil.isAndroidQ()) {
  223 + videoCaceDirPath = mActivity.getExternalFilesDir("").getPath() + File.separator + "MediaPickerVideo";
  224 + }else {
  225 + videoCaceDirPath= mActivity.mOptions.getCachePath();
  226 + }
  227 + }
  228 + mActivity.mOptions.setCachePath(videoCaceDirPath);
  229 + recordSetting.setVideoCacheDir(videoCaceDirPath);
  230 +
  231 + mActivity.videoPath = mActivity.mOptions.getCachePath() + System.currentTimeMillis() + ".mp4";
  232 + recordSetting.setVideoFilepath(mActivity.videoPath);
  233 + mActivity.binding.rcControl.setFlashState(false);
  234 + mActivity.binding.rcControl.setMaxTime(mActivity.mOptions.getMaxTime());
  235 +
  236 + //设置闪光灯
  237 +
  238 + // 设置录制速度 (默认为 1.0)
  239 + mActivity.plShortVideoRecorder.setRecordStateListener(this);
  240 + mActivity.plShortVideoRecorder.prepare(mActivity.binding.gSf, cameraSetting, microphoneSetting, videoEncodeSetting, audioEncodeSetting,null, recordSetting);
  241 + //处理手动对焦事件
  242 +
  243 + mActivity.binding.gSf.setOnTouchListener(new View.OnTouchListener() {
  244 + @Override
  245 + public boolean onTouch(View v, MotionEvent event) {
  246 + if (event.getAction() == MotionEvent.ACTION_UP) {
  247 + moveFocus(event.getRawX(), event.getRawY());
  248 + }
  249 + return true;
  250 + }
  251 + });
  252 + //如果是裁剪类型只支持拍照
  253 + if (mActivity.isJumpCamera && mActivity.mOptions.getJumpCameraMode() >= 0) {
  254 + mActivity.binding.rcControl.setRecordType(mActivity.mOptions.getJumpCameraMode());
  255 + } else {
  256 + if (mActivity.mOptions.isNeedCrop()) {
  257 + mActivity.binding.rcControl.setRecordType(PickerConfig.CAMERA_MODE_PIC);
  258 + } else {
  259 + mActivity.binding.rcControl.setRecordType(PickerConfig.CAMERA_MODE_ALL);
  260 + }
  261 + }
  262 + }
  263 +
  264 + //移动对焦的动画
  265 + public void moveFocus(float x, float y) {
  266 +
  267 + mActivity.plShortVideoRecorder.manualFocus(80, 80, (int) x, (int) y);
  268 + //缩小
  269 + float transX = x - ScreenUtils.getScreenWidth(mActivity) / 2;
  270 +
  271 + float transY = y - ScreenUtils.getScreenHeight(mActivity) / 2;
  272 + ObjectAnimator translationX = ObjectAnimator.ofFloat(mActivity.binding.fv, "translationX", 0, transX);
  273 + ObjectAnimator translationY = ObjectAnimator.ofFloat(mActivity.binding.fv, "translationY", 0, transY);
  274 + AnimatorSet animSet = new AnimatorSet();
  275 + animSet.play(translationX).with(translationY);
  276 + animSet.start();
  277 + animSet.addListener(new Animator.AnimatorListener() {
  278 + @Override
  279 + public void onAnimationStart(Animator animation) {
  280 +
  281 + }
  282 +
  283 + @Override
  284 + public void onAnimationEnd(Animator animation) {
  285 + mActivity.binding.fv.setVisibility(View.VISIBLE);
  286 + }
  287 +
  288 + @Override
  289 + public void onAnimationCancel(Animator animation) {
  290 +
  291 + }
  292 +
  293 + @Override
  294 + public void onAnimationRepeat(Animator animation) {
  295 +
  296 + }
  297 + });
  298 + ObjectAnimator scaleX = ObjectAnimator.ofFloat(mActivity.binding.fv, "scaleX", 1, 0.6f);
  299 + ObjectAnimator scaleY = ObjectAnimator.ofFloat(mActivity.binding.fv, "scaleY", 1, 0.6f);
  300 +
  301 + AnimatorSet animSet2 = new AnimatorSet();
  302 + animSet2.play(scaleY).with(scaleX);
  303 + animSet2.setInterpolator(new OvershootInterpolator());
  304 + animSet2.setDuration(800);
  305 + animSet2.start();
  306 + animSet2.addListener(new Animator.AnimatorListener() {
  307 +
  308 + @Override
  309 + public void onAnimationStart(Animator animation) {
  310 +
  311 + }
  312 +
  313 + @Override
  314 + public void onAnimationEnd(Animator animation) {
  315 + mActivity.binding.fv.setVisibility(View.GONE);
  316 + }
  317 +
  318 + @Override
  319 + public void onAnimationCancel(Animator animation) {
  320 +
  321 + }
  322 +
  323 + @Override
  324 + public void onAnimationRepeat(Animator animation) {
  325 +
  326 + }
  327 + });
  328 + }
  329 +
  330 + public void showMesage(String message) {
  331 +
  332 + if (TextUtils.isEmpty(message) || mActivity == null || mActivity.isFinishing()) return;
  333 + mActivity.runOnUiThread(new Runnable() {
  334 + @Override
  335 + public void run() {
  336 + AlertUtil.showDeftToast(mActivity, message);
  337 + }
  338 + });
  339 +
  340 +
  341 + }
  342 +
  343 + public void processError(int code) {
  344 + showMesage("相机异常:" + code);
  345 + if (PLErrorCode.ERROR_UNAUTHORIZED != code) {
  346 + initQNRecord();
  347 + }
  348 + }
  349 +
  350 + public void processFlash(boolean isFlashingState) {
  351 + mActivity.binding.rcControl.setFlashState(isFlashingState);
  352 + }
  353 +
  354 + public void showPreViewImg(Bitmap plbitMap) {
  355 + mActivity.runOnUiThread(new Runnable() {
  356 + @Override
  357 + public void run() {
  358 + if (plbitMap != null && plbitMap.getByteCount() > 0) {
  359 + showPre();
  360 + mActivity.preBitmap = plbitMap;
  361 + mActivity.getSupportFragmentManager().beginTransaction().add(R.id.pre_frame, RecordPreviewFragment.newInstance(0, "")).addToBackStack("").commit();
  362 +
  363 + } else {
  364 + showMesage("相机异常");
  365 + }
  366 + }
  367 + });
  368 +
  369 + }
  370 +
  371 +
  372 + public void showPermission(String[] needList, int requestCode) {
  373 + if (mActivity.dialog != null) mActivity.dialog.dismiss();
  374 + mActivity.dialog = AlertDialogUtils.showTwoButtonDialog(
  375 + mActivity,
  376 + mActivity.getString(R.string.dialog_imagepicker_permission_nerver_ask_cancel),
  377 + mActivity.getString(R.string.dialog_imagepicker_permission_confirm),
  378 + mActivity.getString(R.string.dialog_imagepicker_permission_camera_nerver_ask_message),
  379 + R.color.color_dialog_btn, R.color.color_ffa300, new AlertDialogUtils.DialogTwoListener() {
  380 + @Override
  381 + public void onClickLeft(Dialog dialog) {
  382 + dialog.dismiss();
  383 + showMesage("无法获取存读取权限,您的app将无法正常使用");
  384 + mActivity.finish();
  385 + }
  386 +
  387 + @Override
  388 + public void onClickRight(Dialog dialog) {
  389 + dialog.dismiss();
  390 + ActivityCompat.requestPermissions(mActivity, needList, requestCode);
  391 + }
  392 + });
  393 + }
  394 +
  395 + public void showPermissionPerpetual(int requestCode) {
  396 +
  397 + if (mActivity.dialog != null) mActivity.dialog.dismiss();
  398 + mActivity.dialog = AlertDialogUtils.showTwoButtonDialog(
  399 + mActivity,
  400 + mActivity.getString(R.string.dialog_imagepicker_permission_nerver_ask_cancel),
  401 + mActivity.getString(R.string.dialog_imagepicker_permission_confirm),
  402 + mActivity.getString(R.string.dialog_imagepicker_permission_camera_nerver_ask_message),
  403 + R.color.color_dialog_btn, R.color.color_ffa300, new AlertDialogUtils.DialogTwoListener() {
  404 + @Override
  405 + public void onClickLeft(Dialog dialog) {
  406 + dialog.dismiss();
  407 + showMesage("无法获取存读取权限,您的app将无法正常使用");
  408 + mActivity.finish();
  409 + }
  410 +
  411 + @Override
  412 + public void onClickRight(Dialog dialog) {
  413 + dialog.dismiss();
  414 + PermissionChecker.settingPermissionActivity(mActivity, requestCode);
  415 + mActivity.isNeverAsk = true;
  416 + }
  417 + });
  418 +
  419 + }
  420 +}
... ...
lib_media/src/main/java/com/cnlive/media/frame/view/VideoPlayerView.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/frame/view/VideoPlayerView.java
  1 +package com.cnlive.media.frame.view;
  2 +
  3 +import android.content.Context;
  4 +import android.content.pm.ActivityInfo;
  5 +import android.media.AudioManager;
  6 +import android.net.Uri;
  7 +import android.os.Build;
  8 +import android.text.TextUtils;
  9 +import android.view.View;
  10 +
  11 +import com.bumptech.glide.Glide;
  12 +import com.cnlive.libs.base.util.AlertUtil;
  13 +import com.cnlive.libs.video.video.base.IMediaPlayer;
  14 +import com.cnlive.media.ui.activity.VideoPlayerActivity;
  15 +import com.cnlive.media.utlis.AndroidQUtil;
  16 +import com.hannesdorfmann.mosby3.mvp.MvpView;
  17 +
  18 +/**
  19 + * 作 者 : wkq
  20 + * <p>
  21 + * 时 间 : 2020/10/15 11:13
  22 + * <p>
  23 + * 名 字 : VideoPlayerView
  24 + * <p>
  25 + * 简 介 :
  26 + */
  27 +public class VideoPlayerView implements MvpView {
  28 + VideoPlayerActivity mActivity;
  29 +
  30 + public VideoPlayerView(VideoPlayerActivity mActivity) {
  31 + this.mActivity = mActivity;
  32 + }
  33 +
  34 + public void initView() {
  35 + if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
  36 + mActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
  37 + }
  38 + mActivity.binding.video.setTimeout(60, 60);
  39 + mActivity.binding.video.setKeepScreenOn(true);
  40 + mActivity.binding.video.setLooping(true);
  41 + mActivity.binding.video.setDataSource(mActivity, Uri.parse(mActivity.path));
  42 +
  43 + mActivity.binding.video.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() {
  44 + @Override
  45 + public void onPrepared(IMediaPlayer iMediaPlayer) {
  46 + mActivity.isCanPlay = true;
  47 + setPlayState();
  48 + }
  49 + });
  50 +
  51 + mActivity.binding.video.setOnCompletionListener(new IMediaPlayer.OnCompletionListener() {
  52 + @Override
  53 + public void onCompletion(IMediaPlayer iMediaPlayer) {
  54 + mActivity.isPlayIng = false;
  55 + mActivity.binding.video.seekTo(0);
  56 + onPause();
  57 + }
  58 + });
  59 +
  60 + mActivity.binding.video.setOnErrorListener(new IMediaPlayer.OnErrorListener() {
  61 + @Override
  62 + public boolean onError(IMediaPlayer iMediaPlayer, int i, int i1) {
  63 + showMessage("视频播放异常");
  64 + mActivity.isPlayIng = false;
  65 + return false;
  66 + }
  67 + });
  68 +
  69 + mActivity.binding.ivPlay.setOnClickListener(v -> {
  70 + setPlayState();
  71 + });
  72 + mActivity.binding.video.setOnClickListener(v -> {
  73 + setPlayState();
  74 + });
  75 +
  76 +
  77 + Glide.with(mActivity).load(Uri.parse(mActivity.path)).into(mActivity.binding.ivThumbnail);
  78 +
  79 + }
  80 +
  81 +
  82 + public void showMessage(String message) {
  83 + if (mActivity == null || TextUtils.isEmpty(message)) {
  84 + return;
  85 + }
  86 + AlertUtil.showDeftToast(mActivity, message);
  87 + }
  88 +
  89 + public void requestAudioFocus() {
  90 + if (mActivity == null)
  91 + return;
  92 + AudioManager audioManager = (AudioManager) mActivity.getSystemService(Context.AUDIO_SERVICE);
  93 + if (audioManager != null) {
  94 + int ret = audioManager.requestAudioFocus(mOnAudioFocusChangeListener,
  95 + AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN);
  96 + if (ret != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
  97 + }
  98 + }
  99 + }
  100 +
  101 + /**
  102 + * 释放音频焦点
  103 + */
  104 + public void abandonAudioFocus() {
  105 + if (mActivity == null)
  106 + return;
  107 + AudioManager audioManager = (AudioManager) mActivity.getSystemService(Context.AUDIO_SERVICE);
  108 + if (audioManager != null) {
  109 + audioManager.abandonAudioFocus(mOnAudioFocusChangeListener);
  110 + }
  111 + }
  112 +
  113 + private AudioManager.OnAudioFocusChangeListener mOnAudioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() {
  114 + @Override
  115 + public void onAudioFocusChange(int focusChange) {
  116 + if (focusChange == AudioManager.AUDIOFOCUS_LOSS ||
  117 + focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
  118 + //失去焦点之后的操作
  119 + onPause();
  120 + } else if (focusChange == AudioManager.AUDIOFOCUS_GAIN ||
  121 + focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT ||
  122 + focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE ||
  123 + focusChange == AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK) {
  124 + //获得焦点之后的操作
  125 + }
  126 + }
  127 + };
  128 +
  129 + /**
  130 + * 设置播放状态
  131 + */
  132 + public void setPlayState() {
  133 + if (mActivity == null) return;
  134 + if (mActivity.isCanPlay) {
  135 + if (mActivity.isPlayIng) {
  136 + mActivity.binding.video.pause();
  137 + mActivity.binding.rlThum.setVisibility(View.VISIBLE);
  138 + mActivity.binding.ivThumbnail.setVisibility(View.GONE);
  139 + mActivity.isPlayIng = false;
  140 + } else {
  141 + mActivity.binding.video.start();
  142 + mActivity.binding.rlThum.setVisibility(View.GONE);
  143 + mActivity.isPlayIng = true;
  144 + }
  145 + }
  146 + }
  147 +
  148 +
  149 + public void onResume() {
  150 + mActivity.isPlayIng = false;
  151 + mActivity.binding.video.pause();
  152 + mActivity.binding.rlThum.setVisibility(View.VISIBLE);
  153 + }
  154 +
  155 + public void onPause() {
  156 + mActivity.isPlayIng = false;
  157 + mActivity.binding.video.pause();
  158 + mActivity.binding.rlThum.setVisibility(View.VISIBLE);
  159 + }
  160 +}
... ...
lib_media/src/main/java/com/cnlive/media/meidia/DataCallback.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/meidia/DataCallback.java
  1 +package com.cnlive.media.meidia;
  2 +
  3 +
  4 +import com.cnlive.media.meidia.entity.Folder;
  5 +
  6 +import java.util.ArrayList;
  7 +
  8 +
  9 +public interface DataCallback {
  10 +
  11 +
  12 + void onData(ArrayList<Folder> list);
  13 +
  14 +}
... ...
lib_media/src/main/java/com/cnlive/media/meidia/entity/Folder.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/meidia/entity/Folder.java
  1 +package com.cnlive.media.meidia.entity;
  2 +
  3 +import android.os.Parcel;
  4 +import android.os.Parcelable;
  5 +
  6 +import java.util.ArrayList;
  7 +/**
  8 + * 作 者 : wkq
  9 + * <p>
  10 + * 时 间 : 2020/9/15 11:26
  11 + * <p>
  12 + * 名 字 : Folder
  13 + * <p>
  14 + * 简 介 : 文件夹的数据模型
  15 + */
  16 +
  17 +public class Folder implements Parcelable {
  18 +
  19 + public String name;
  20 +
  21 + public int count;
  22 +
  23 + ArrayList<Media> medias = new ArrayList<>();
  24 +
  25 + public void addMedias(Media media) {
  26 + medias.add(media);
  27 + }
  28 +
  29 + public Folder(String name) {
  30 + this.name = name;
  31 + }
  32 +
  33 + public ArrayList<Media> getMedias() {
  34 + return this.medias;
  35 + }
  36 +
  37 +
  38 + @Override
  39 + public int describeContents() {
  40 + return 0;
  41 + }
  42 +
  43 + @Override
  44 + public void writeToParcel(Parcel dest, int flags) {
  45 + dest.writeString(this.name);
  46 + dest.writeInt(this.count);
  47 + dest.writeTypedList(this.medias);
  48 + }
  49 +
  50 +
  51 + protected Folder(Parcel in) {
  52 + this.name = in.readString();
  53 + this.count = in.readInt();
  54 + this.medias = in.createTypedArrayList(Media.CREATOR);
  55 + }
  56 +
  57 + public static final Creator<Folder> CREATOR = new Creator<Folder>() {
  58 + @Override
  59 + public Folder createFromParcel(Parcel source) {
  60 + return new Folder(source);
  61 + }
  62 +
  63 + @Override
  64 + public Folder[] newArray(int size) {
  65 + return new Folder[size];
  66 + }
  67 + };
  68 +}
... ...
lib_media/src/main/java/com/cnlive/media/meidia/entity/Media.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/meidia/entity/Media.java
  1 +package com.cnlive.media.meidia.entity;
  2 +
  3 +import android.os.Parcel;
  4 +import android.os.Parcelable;
  5 +
  6 +import java.util.Objects;
  7 +
  8 +/**
  9 + * 作 者 : wkq
  10 + * <p>
  11 + * 时 间 : 2020/9/15 11:26
  12 + * <p>
  13 + * 名 字 : Media
  14 + * <p>
  15 + * 简 介 : 媒体数据的数据模型
  16 + */
  17 +public class Media implements Parcelable {
  18 + public String path;
  19 + public String name;
  20 + public long time;
  21 + // mediaType 3:视频 1:图片 0: 相机
  22 + public int mediaType;
  23 + public long size;
  24 + public int id;
  25 + public String parentDir;
  26 + public boolean isDeleted;
  27 + public int duration;
  28 + public boolean compressed;
  29 + //
  30 + public boolean isReturnUri;
  31 + public String fileUri;
  32 +
  33 + //是否选中
  34 + public boolean isSelect;
  35 +
  36 + public int imgWidth;
  37 + public int imgHeight;
  38 +
  39 + public boolean isLongImg;
  40 +
  41 + public int getImgWidth() {
  42 + return imgWidth;
  43 + }
  44 +
  45 + public void setImgWidth(int imgWidth) {
  46 + this.imgWidth = imgWidth;
  47 + }
  48 +
  49 + public int getImgHeight() {
  50 + return imgHeight;
  51 + }
  52 +
  53 + public void setImgHeight(int imgHeight) {
  54 + this.imgHeight = imgHeight;
  55 + }
  56 +
  57 + public boolean isLongImg() {
  58 + return isLongImg;
  59 + }
  60 +
  61 + public void setLongImg(boolean longImg) {
  62 + isLongImg = longImg;
  63 + }
  64 +
  65 +
  66 +
  67 + public Media(int mediaType) {
  68 + this.mediaType = mediaType;
  69 + }
  70 +
  71 + public Media(String path, String name, long time, int mediaType, long size, int id, String parentDir, int duration, String fileUri) {
  72 + this.path = path;
  73 + this.name = name;
  74 + this.time = time;
  75 + this.mediaType = mediaType;
  76 + this.size = size;
  77 + this.id = id;
  78 + this.parentDir = parentDir;
  79 + this.duration = duration;
  80 + this.compressed = false;
  81 + this.fileUri = fileUri;
  82 + }
  83 +
  84 +
  85 + public Media(String path, String name, long time, int mediaType, long size, int id, String parentDir, int duration, boolean compressed) {
  86 + this.path = path;
  87 + this.name = name;
  88 + this.time = time;
  89 + this.mediaType = mediaType;
  90 + this.size = size;
  91 + this.id = id;
  92 + this.parentDir = parentDir;
  93 + this.duration = duration;
  94 + this.compressed = compressed;
  95 + this.fileUri = fileUri;
  96 + }
  97 +
  98 + public Media(String path, String name, long time, int mediaType, long size, int id, String parentDir, String fileUri) {
  99 + this.path = path;
  100 + this.name = name;
  101 + this.time = time;
  102 + this.mediaType = mediaType;
  103 + this.size = size;
  104 + this.id = id;
  105 + this.parentDir = parentDir;
  106 + this.fileUri = fileUri;
  107 + }
  108 +
  109 + @Override
  110 + public int describeContents() {
  111 + return 0;
  112 + }
  113 +
  114 + @Override
  115 + public void writeToParcel(Parcel dest, int flags) {
  116 + dest.writeString(this.path);
  117 + dest.writeString(this.name);
  118 + dest.writeLong(this.time);
  119 + dest.writeInt(this.mediaType);
  120 + dest.writeLong(this.size);
  121 + dest.writeInt(this.id);
  122 + dest.writeString(this.parentDir);
  123 + dest.writeByte((byte) (isDeleted ? 1 : 0));
  124 + dest.writeByte((byte) (isSelect ? 1 : 0));
  125 + dest.writeByte((byte) (isReturnUri ? 1 : 0));
  126 + dest.writeInt(duration);
  127 + dest.writeByte((byte) (compressed ? 1 : 0));
  128 + dest.writeString(this.fileUri);
  129 + }
  130 +
  131 + protected Media(Parcel in) {
  132 + this.path = in.readString();
  133 + this.name = in.readString();
  134 + this.time = in.readLong();
  135 + this.mediaType = in.readInt();
  136 + this.size = in.readLong();
  137 + this.id = in.readInt();
  138 + this.parentDir = in.readString();
  139 + this.isDeleted = in.readByte() != 0;
  140 + this.isSelect = in.readByte() != 0;
  141 + this.isReturnUri = in.readByte() != 0;
  142 + this.duration = in.readInt();
  143 + this.compressed = in.readByte() != 0;
  144 + this.fileUri = in.readString();
  145 + }
  146 +
  147 + public static final Creator<Media> CREATOR = new Creator<Media>() {
  148 + @Override
  149 + public Media createFromParcel(Parcel source) {
  150 + return new Media(source);
  151 + }
  152 +
  153 + @Override
  154 + public Media[] newArray(int size) {
  155 + return new Media[size];
  156 + }
  157 + };
  158 +
  159 + public boolean isReturnUri() {
  160 + return isReturnUri;
  161 + }
  162 +
  163 + public void setReturnUri(boolean isReturnUri) {
  164 + this.isReturnUri = isReturnUri;
  165 + }
  166 + public boolean isSelect() {
  167 + return isSelect;
  168 + }
  169 +
  170 + public void setSelect(boolean select) {
  171 + isSelect = select;
  172 + }
  173 +
  174 + @Override
  175 + public boolean equals(Object o) {
  176 + if (this == o) return true;
  177 + if (o == null || getClass() != o.getClass()) return false;
  178 + Media media = (Media) o;
  179 + return
  180 + mediaType == media.mediaType &&
  181 + size == media.size &&
  182 + id == media.id &&
  183 + duration == media.duration &&
  184 + Objects.equals(path, media.path) &&
  185 + Objects.equals(name, media.name) &&
  186 + Objects.equals(parentDir, media.parentDir) &&
  187 + Objects.equals(fileUri, media.fileUri);
  188 + }
  189 +
  190 + @Override
  191 + public int hashCode() {
  192 + return Objects.hash(path, name, mediaType, size, id, parentDir, duration, fileUri);
  193 + }
  194 +}
... ...
lib_media/src/main/java/com/cnlive/media/meidia/loader/ImageLoader.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/meidia/loader/ImageLoader.java
  1 +package com.cnlive.media.meidia.loader;
  2 +
  3 +import android.app.LoaderManager;
  4 +import android.content.Context;
  5 +import android.content.CursorLoader;
  6 +import android.content.Loader;
  7 +import android.database.Cursor;
  8 +import android.net.Uri;
  9 +import android.os.Bundle;
  10 +import android.provider.MediaStore;
  11 +import android.text.TextUtils;
  12 +
  13 +import com.cnlive.media.meidia.DataCallback;
  14 +import com.cnlive.media.meidia.entity.Folder;
  15 +import com.cnlive.media.meidia.entity.Media;
  16 +import com.cnlive.media.utlis.MediaUtils;
  17 +import com.cnlive.meidia.R;
  18 +
  19 +import java.io.File;
  20 +import java.util.ArrayList;
  21 +
  22 +/**
  23 + * Created by dmcBig on 2017/7/3.
  24 + */
  25 +
  26 +public class ImageLoader extends LoaderM implements LoaderManager.LoaderCallbacks {
  27 + private static ArrayList<Folder> folders=new ArrayList<>();
  28 + private final String TAG = this.getClass().getName();
  29 + String[] IMAGE_PROJECTION = {
  30 + MediaStore.Images.Media.DATA,
  31 + MediaStore.Images.Media.DISPLAY_NAME,
  32 + MediaStore.Images.Media.DATE_ADDED,
  33 + MediaStore.Files.FileColumns.MEDIA_TYPE,
  34 + MediaStore.Images.Media.SIZE,
  35 + MediaStore.Images.Media.WIDTH,
  36 + MediaStore.Images.Media.HEIGHT,
  37 + MediaStore.Images.Media._ID};
  38 +
  39 + Context mContext;
  40 + DataCallback mLoader;
  41 +
  42 + private static ImageLoader instance = null;
  43 +
  44 + public synchronized static ImageLoader getInstance(Context context, DataCallback loader) {
  45 + if (instance == null || folders == null) {
  46 + instance = new ImageLoader(context);
  47 + folders = new ArrayList<>();
  48 + }
  49 + instance.setmLoader(loader);
  50 + return instance;
  51 + }
  52 +
  53 + public ImageLoader(Context context) {
  54 + this.mContext = context;
  55 + }
  56 +
  57 + public void setmLoader(DataCallback mLoader) {
  58 + this.mLoader = mLoader;
  59 + }
  60 +
  61 +// public ImageLoader(Context context, DataCallback loader) {
  62 +// this.mContext = context;
  63 +// this.mLoader = loader;
  64 +// }
  65 +
  66 + @Override
  67 + public Loader onCreateLoader(int picker_type, Bundle bundle) {
  68 + String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
  69 + + MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE;
  70 + Uri queryUri = MediaStore.Files.getContentUri("external");
  71 + CursorLoader cursorLoader = new CursorLoader(
  72 + mContext,
  73 + queryUri,
  74 + IMAGE_PROJECTION,
  75 + selection,
  76 + null, // Selection args (none).
  77 + MediaStore.Images.Media.DATE_ADDED + " DESC" // Sort order.
  78 + );
  79 + return cursorLoader;
  80 + }
  81 +
  82 + @Override
  83 + public void onLoadFinished(Loader loader, Object o) {
  84 + if (folders == null || mLoader == null || instance == null) return;
  85 + if (folders.size() > 0) {
  86 + mLoader.onData(folders);
  87 + return;
  88 + }
  89 +
  90 + Folder allFolder = new Folder(mContext.getResources().getString(R.string.all_image));
  91 + folders.add(allFolder);
  92 + Cursor cursor = null;
  93 + if (o != null) cursor = (Cursor) o;
  94 + while (cursor != null && cursor.moveToNext()) {
  95 + String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
  96 + File file = new File(path);
  97 + if (!file.exists()) {
  98 + continue;
  99 + }
  100 +
  101 + //判断路径的长度是否大于后缀名
  102 + if (path.length() > ".wbmp".length()) {
  103 + //进行判断
  104 + if (path.lastIndexOf(".wbmp") != -1) {
  105 + continue;
  106 + }
  107 + }
  108 + String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME));
  109 + long dateTime = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED));
  110 + int mediaType = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MEDIA_TYPE));
  111 + long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE));
  112 + if (size < 512) continue;
  113 + int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
  114 + Uri photoUri = Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString() + File.separator + id);
  115 + String fileUri = photoUri.toString();
  116 + if (TextUtils.isEmpty(path)) continue;
  117 + String dirName = getParent(path);
  118 + if (TextUtils.isEmpty(dirName)) continue;
  119 + Media media = new Media(path, name, dateTime, mediaType, size, id, dirName, fileUri);
  120 + //获取图片宽高
  121 + int width = cursor.getInt
  122 + (cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.WIDTH));
  123 +
  124 + int height = cursor.getInt
  125 + (cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.HEIGHT));
  126 + //设置图片大小
  127 + media.setImgWidth(width);
  128 + media.setImgHeight(height);
  129 + media.setLongImg(MediaUtils.isLongImg(media));
  130 + allFolder.addMedias(media);
  131 +
  132 + int index = hasDir(folders, dirName);
  133 + if (index != -1) {
  134 + folders.get(index).addMedias(media);
  135 + } else {
  136 + Folder folder = new Folder(dirName);
  137 + folder.addMedias(media);
  138 + folders.add(folder);
  139 + }
  140 + }
  141 + if (mLoader != null) mLoader.onData(folders);
  142 +// Log.e(TAG, "数据为空: " + folders.size());
  143 + if (cursor != null) cursor.close();
  144 + }
  145 +
  146 + @Override
  147 + public void onLoaderReset(Loader loader) {
  148 +
  149 + }
  150 +
  151 +
  152 + @Override
  153 + public void onDestory() {
  154 + if (null != instance && null != folders) {
  155 + folders.clear();
  156 + folders = null;
  157 + instance = null;
  158 + }
  159 + }
  160 +}
0 161 \ No newline at end of file
... ...
lib_media/src/main/java/com/cnlive/media/meidia/loader/LoaderM.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/meidia/loader/LoaderM.java
  1 +package com.cnlive.media.meidia.loader;
  2 +
  3 +
  4 +import com.cnlive.media.meidia.entity.Folder;
  5 +
  6 +import java.util.ArrayList;
  7 +
  8 +/**
  9 + * Created by dmcBig on 2017/7/20.
  10 + */
  11 +
  12 +public abstract class LoaderM {
  13 +
  14 + public String getParent(String path) {
  15 + String[] sp = path.split("/");
  16 + return sp.length == 0 ? "" : sp[sp.length - 2];
  17 + }
  18 +
  19 + public int hasDir(ArrayList<Folder> folders, String dirName) {
  20 + for (int i = 0; i < folders.size(); i++) {
  21 + Folder folder = folders.get(i);
  22 + if (folder.name.equals(dirName)) {
  23 + return i;
  24 + }
  25 + }
  26 + return -1;
  27 + }
  28 +
  29 + public abstract void onDestory();
  30 +}
... ...
lib_media/src/main/java/com/cnlive/media/meidia/loader/MediaLoader.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/meidia/loader/MediaLoader.java
  1 +package com.cnlive.media.meidia.loader;
  2 +
  3 +import android.app.LoaderManager;
  4 +import android.content.Context;
  5 +import android.content.CursorLoader;
  6 +import android.content.Loader;
  7 +import android.database.Cursor;
  8 +import android.net.Uri;
  9 +import android.os.Bundle;
  10 +import android.provider.MediaStore;
  11 +import android.text.TextUtils;
  12 +
  13 +import com.cnlive.media.meidia.DataCallback;
  14 +import com.cnlive.media.meidia.entity.Folder;
  15 +import com.cnlive.media.meidia.entity.Media;
  16 +import com.cnlive.media.utlis.MediaUtils;
  17 +import com.cnlive.meidia.R;
  18 +
  19 +import java.io.File;
  20 +import java.util.ArrayList;
  21 +
  22 +
  23 +/**
  24 + * Created by dmcBig on 2017/6/9.
  25 + */
  26 +
  27 +public class MediaLoader extends LoaderM implements LoaderManager.LoaderCallbacks {
  28 + private final String TAG = this.getClass().getName();
  29 +
  30 + String[] MEDIA_PROJECTION = {
  31 + MediaStore.Files.FileColumns.DATA,
  32 + MediaStore.Files.FileColumns.DISPLAY_NAME,
  33 + MediaStore.Files.FileColumns.DATE_ADDED,
  34 + MediaStore.Files.FileColumns.MEDIA_TYPE,
  35 + MediaStore.Files.FileColumns.SIZE,
  36 + MediaStore.Files.FileColumns._ID,
  37 + MediaStore.Files.FileColumns.WIDTH,
  38 + MediaStore.Files.FileColumns.HEIGHT,
  39 + MediaStore.Files.FileColumns.PARENT,
  40 + MediaStore.Video.VideoColumns.DURATION};
  41 +
  42 + Context mContext;
  43 + DataCallback mLoader;
  44 + private Uri photoUri;
  45 + private static MediaLoader instance;
  46 + private static ArrayList<Folder> folders = new ArrayList<>();
  47 +
  48 + public synchronized static MediaLoader getInstance(Context context, DataCallback loader) {
  49 + if (instance == null) {
  50 + instance = new MediaLoader(context);
  51 + folders = new ArrayList<>();
  52 + }
  53 + instance.setmLoader(loader);
  54 + return instance;
  55 + }
  56 +
  57 + public MediaLoader(Context context) {
  58 + if (context == null) return;
  59 + this.mContext = context;
  60 + }
  61 +
  62 + public void setmLoader(DataCallback mLoader) {
  63 + this.mLoader = mLoader;
  64 + }
  65 +
  66 + @Override
  67 + public Loader onCreateLoader(int picker_type, Bundle bundle) {
  68 + String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
  69 + + MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE
  70 + + " OR "
  71 + + MediaStore.Files.FileColumns.MEDIA_TYPE + "="
  72 + + MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
  73 +
  74 + Uri queryUri = MediaStore.Files.getContentUri("external");
  75 + CursorLoader cursorLoader = new CursorLoader(
  76 + mContext,
  77 + queryUri,
  78 + MEDIA_PROJECTION,
  79 + selection,
  80 + null, // Selection args (none).
  81 + MediaStore.Files.FileColumns.DATE_ADDED + " DESC" // Sort order.
  82 + );
  83 + return cursorLoader;
  84 + }
  85 +
  86 + @Override
  87 + public void onLoadFinished(Loader loader, Object o) {
  88 + if (folders == null || mLoader == null || instance == null) return;
  89 + if (folders.size() > 0) {
  90 + mLoader.onData(folders);
  91 + return;
  92 + }
  93 + Folder allFolder = new Folder(mContext.getResources().getString(R.string.all_dir_name));
  94 + folders.add(allFolder);
  95 + Folder allVideoDir = new Folder(mContext.getResources().getString(R.string.video_dir_name));
  96 + folders.add(allVideoDir);
  97 + Cursor cursor = (Cursor) o;
  98 + if (cursor != null) {
  99 + while (cursor.moveToNext()) {
  100 + String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA));
  101 + File file = new File(path);
  102 + if (!file.exists()) {
  103 + continue;
  104 + }
  105 + String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME));
  106 + long dateTime = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATE_ADDED));
  107 + int mediaType = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MEDIA_TYPE));
  108 + long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE));
  109 + int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID));
  110 + int duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.VideoColumns.DURATION));
  111 + if (size < 512) continue;
  112 + if (mediaType == 3) {
  113 + photoUri = Uri.parse(MediaStore.Video.Media.EXTERNAL_CONTENT_URI.toString() + File.separator + id);
  114 + } else if (mediaType == 1) {
  115 + photoUri = Uri.parse(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString() + File.separator + id);
  116 + }
  117 +
  118 + //获取图片宽高
  119 + int width = cursor.getInt
  120 + (cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.WIDTH));
  121 +
  122 + int height = cursor.getInt
  123 + (cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.HEIGHT));
  124 +
  125 + String fileUri = photoUri.toString();
  126 +
  127 + String dirName = getParent(path);
  128 + if (TextUtils.isEmpty(dirName)) continue;
  129 + Media media = new Media(path, name, dateTime, mediaType, size, id, dirName, duration, fileUri);
  130 +
  131 + allFolder.addMedias(media);
  132 + if (mediaType == 3) {
  133 + allVideoDir.addMedias(media);
  134 + }
  135 +
  136 + int index = hasDir(folders, dirName);
  137 + if (index != -1) {
  138 + folders.get(index).addMedias(media);
  139 + } else {
  140 + Folder folder = new Folder(dirName);
  141 + media.setImgWidth(width);
  142 + media.setImgHeight(height);
  143 + media.setLongImg(MediaUtils.isLongImg(media));
  144 + folder.addMedias(media);
  145 + folders.add(folder);
  146 + }
  147 + }
  148 + cursor.close();
  149 + }
  150 +// Log.e(TAG, "数据为空: " + folders.size());
  151 + if (mLoader != null) mLoader.onData(folders);
  152 + }
  153 +
  154 +
  155 + @Override
  156 + public void onLoaderReset(Loader loader) {
  157 +
  158 + }
  159 +
  160 + @Override
  161 + public void onDestory() {
  162 + if (null != instance && null != folders) {
  163 + folders.clear();
  164 + folders = null;
  165 + instance = null;
  166 + }
  167 + }
  168 +}
... ...
lib_media/src/main/java/com/cnlive/media/meidia/loader/VideoLoader.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/meidia/loader/VideoLoader.java
  1 +package com.cnlive.media.meidia.loader;
  2 +
  3 +import android.app.LoaderManager;
  4 +import android.content.Context;
  5 +import android.content.CursorLoader;
  6 +import android.content.Loader;
  7 +import android.database.Cursor;
  8 +import android.net.Uri;
  9 +import android.os.Bundle;
  10 +import android.provider.MediaStore;
  11 +import android.text.TextUtils;
  12 +import android.util.Log;
  13 +
  14 +
  15 +import com.cnlive.media.meidia.DataCallback;
  16 +import com.cnlive.media.meidia.entity.Folder;
  17 +import com.cnlive.media.meidia.entity.Media;
  18 +import com.cnlive.meidia.R;
  19 +
  20 +import java.io.File;
  21 +import java.util.ArrayList;
  22 +
  23 +
  24 +/**
  25 + * Created by dmcBig on 2017/6/9.
  26 + */
  27 +
  28 +public class VideoLoader extends LoaderM implements LoaderManager.LoaderCallbacks {
  29 + private final String TAG = this.getClass().getName();
  30 + private static VideoLoader instance = null;
  31 + private static ArrayList<Folder> folders=new ArrayList<>();
  32 + String[] MEDIA_PROJECTION = {
  33 + MediaStore.Files.FileColumns.DATA,
  34 + MediaStore.Files.FileColumns.DISPLAY_NAME,
  35 + MediaStore.Files.FileColumns.DATE_ADDED,
  36 + MediaStore.Files.FileColumns.MEDIA_TYPE,
  37 + MediaStore.Files.FileColumns.SIZE,
  38 + MediaStore.Files.FileColumns._ID,
  39 + MediaStore.Files.FileColumns.PARENT,
  40 + MediaStore.Video.VideoColumns.DURATION};
  41 +
  42 + Context mContext;
  43 + DataCallback mLoader;
  44 +
  45 + public synchronized static VideoLoader getInstance(Context context, DataCallback loader) {
  46 + if (instance == null || folders == null) {
  47 + instance = new VideoLoader(context);
  48 + folders = new ArrayList<>();
  49 + }
  50 + instance.setmLoader(loader);
  51 + return instance;
  52 + }
  53 +
  54 + public VideoLoader(Context context) {
  55 + this.mContext = context;
  56 + }
  57 +
  58 + public void setmLoader(DataCallback mLoader) {
  59 + this.mLoader = mLoader;
  60 + }
  61 +
  62 + @Override
  63 + public Loader onCreateLoader(int picker_type, Bundle bundle) {
  64 + String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
  65 + + MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
  66 +
  67 + Uri queryUri = MediaStore.Files.getContentUri("external");
  68 + CursorLoader cursorLoader = new CursorLoader(
  69 + mContext,
  70 + queryUri,
  71 + MEDIA_PROJECTION,
  72 + selection,
  73 + null, // Selection args (none).
  74 + MediaStore.Files.FileColumns.DATE_ADDED + " DESC" // Sort order.
  75 + );
  76 + return cursorLoader;
  77 + }
  78 +
  79 + @Override
  80 + public void onLoadFinished(Loader loader, Object o) {
  81 + if (folders == null || mLoader == null || instance == null) return;
  82 + if (folders.size() > 0) {
  83 + mLoader.onData(folders);
  84 + return;
  85 + }
  86 +
  87 + Folder allFolder = new Folder(mContext.getResources().getString(R.string.all_video));
  88 + folders.add(allFolder);
  89 + Cursor cursor = (Cursor) o;
  90 + Log.e("dmc", cursor.getCount() + "数量数量");
  91 + while (cursor.moveToNext()) {
  92 + //获取的视频路径
  93 + String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATA));
  94 + File file = new File(path);
  95 + if (!file.exists()) {
  96 + continue;
  97 + }
  98 +
  99 + long size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE));
  100 + int duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Video.VideoColumns.DURATION));
  101 + if (size < 512 || duration < 1) continue;
  102 + String name = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DISPLAY_NAME));
  103 + long dateTime = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.DATE_ADDED));
  104 + int mediaType = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MEDIA_TYPE));
  105 +
  106 + int id = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID));
  107 +
  108 +
  109 + Uri photoUri = Uri.parse(MediaStore.Video.Media.EXTERNAL_CONTENT_URI.toString() + File.separator + id);
  110 + String fileUri = photoUri.toString();
  111 +
  112 + String dirName = getParent(path);
  113 + if (TextUtils.isEmpty(dirName)) continue;
  114 + Media media = new Media(path, name, dateTime, mediaType, size, id, dirName, duration, fileUri);
  115 + allFolder.addMedias(media);
  116 +
  117 + int index = hasDir(folders, dirName);
  118 + if (index != -1) {
  119 + folders.get(index).addMedias(media);
  120 + } else {
  121 + Folder folder = new Folder(dirName);
  122 + folder.addMedias(media);
  123 + folders.add(folder);
  124 + }
  125 + }
  126 +// Log.e(TAG, "数据为空: " + folders.size());
  127 +
  128 + mLoader.onData(folders);
  129 + cursor.close();
  130 + }
  131 +
  132 +
  133 + @Override
  134 + public void onLoaderReset(Loader loader) {
  135 +
  136 + }
  137 +
  138 + @Override
  139 + public void onDestory() {
  140 + if (null != instance && null != folders) {
  141 + folders.clear();
  142 + folders = null;
  143 + instance = null;
  144 + }
  145 + }
  146 +}
... ...
lib_media/src/main/java/com/cnlive/media/model/CircleChoose.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/model/CircleChoose.java
  1 +package com.cnlive.media.model;
  2 +
  3 +
  4 +/**
  5 + * Author by Yuansiwen.com, Date on 2018/8/28.
  6 + * PS: Not easy to write code, please indicate.
  7 + */
  8 +public class CircleChoose {
  9 + private CircleData.ReleaseVideoTypeListBean message;
  10 + public CircleChoose(CircleData.ReleaseVideoTypeListBean message){
  11 + this.message=message;
  12 + }
  13 + public CircleData.ReleaseVideoTypeListBean getMessage() {
  14 + return message;
  15 + }
  16 +
  17 + public void setMessage(CircleData.ReleaseVideoTypeListBean message) {
  18 + this.message = message;
  19 + }
  20 +
  21 +}
... ...
lib_media/src/main/java/com/cnlive/media/model/CircleData.java 0 → 100644
  1 +++ a/lib_media/src/main/java/com/cnlive/media/model/CircleData.java
  1 +package com.cnlive.media.model;
  2 +
  3 +
  4 +import android.text.TextUtils;
  5 +
  6 +import java.io.Serializable;
  7 +import java.util.List;
  8 +
  9 +public class CircleData implements Serializable {
  10 +
  11 +
  12 + private List<ReleaseVideoTypeListBean> releaseVideoTypeList;
  13 + private List<SnowVideoTypeListBean> snowVideoTypeList;
  14 +
  15 + public List<ReleaseVideoTypeListBean> getReleaseVideoTypeList() {
  16 + return releaseVideoTypeList;
  17 + }
  18 +
  19 + public void setReleaseVideoTypeList(List<ReleaseVideoTypeListBean> releaseVideoTypeList) {
  20 + this.releaseVideoTypeList = releaseVideoTypeList;
  21 + }
  22 +
  23 + public List<SnowVideoTypeListBean> getSnowVideoTypeList() {
  24 + return snowVideoTypeList;
  25 + }
  26 +
  27 + public void setSnowVideoTypeList(List<SnowVideoTypeListBean> snowVideoTypeList) {
  28 + this.snowVideoTypeList = snowVideoTypeList;
  29 + }
  30 +
  31 + public static class ReleaseVideoTypeListBean implements Serializable {
  32 + /**
  33 + * id : 111
  34 + * path : http://apiwjjtest.cnlive.com/Daren/witness/releaseWitness.action
  35 + * pic : https://wjj.ys1.cnliveimg.com/769/img/2018/0129/grzx_mjz.png
  36 + * text : 目击者
  37 + * videoType : witness
  38 + * multiplecategory:888
  39 + * multipleCategory
  40 + */
  41 +
  42 + private int id;
  43 + private String path;
  44 + private String pic;
  45 + private String text;
  46 + private String videoType;
  47 + private String changePath;
  48 + private int multipleCategory;
  49 + private List<indextag> categoryTag;
  50 + private String defaultText;
  51 + private int detailAddress;
  52 + private String labelColor;
  53 + private int source;
  54 + private String title;
  55 + private String bottomSrc;
  56 + private String protocolAddress;
  57 + private String releaseButtonColor;
  58 + private String topColor;
  59 + private String defaultTitle;
  60 + private String fixedTitle;
  61 + private String successJumpType;//发布成功跳转类型 1->回到分类二级页面
  62 +
  63 +
  64 + public String getSuccessJumpType() {
  65 + return successJumpType;
  66 + }
  67 +
  68 + public void setSuccessJumpType(String successJumpType) {
  69 + this.successJumpType = successJumpType;
  70 + }
  71 +
  72 + public String getBottomSrc() {
  73 + return bottomSrc;
  74 + }
  75 +
  76 + public void setBottomSrc(String bottomSrc) {
  77 + this.bottomSrc = bottomSrc;
  78 + }
  79 +
  80 + public String getProtocolAddress() {
  81 + return protocolAddress;
  82 + }
  83 +
  84 + public void setProtocolAddress(String protocolAddress) {
  85 + this.protocolAddress = protocolAddress;
  86 + }
  87 +
  88 + public String getReleaseButtonColor() {
  89 + return releaseButtonColor;
  90 + }
  91 +
  92 + public void setReleaseButtonColor(String releaseButtonColor) {
  93 + this.releaseButtonColor = releaseButtonColor;
  94 + }
  95 +
  96 + public String getTopColor() {
  97 + return topColor;
  98 + }
  99 +
  100 + public void setTopColor(String topColor) {
  101 + this.topColor = topColor;
  102 + }
  103 +
  104 + public String getDefaultTitle() {
  105 + return defaultTitle;
  106 + }
  107 +
  108 + public void setDefaultTitle(String defaultTitle) {
  109 + this.defaultTitle = defaultTitle;
  110 + }
  111 +
  112 + public String getFixedTitle() {
  113 + return fixedTitle;
  114 + }
  115 +
  116 + public void setFixedTitle(String fixedTitle) {
  117 + this.fixedTitle = fixedTitle;
  118 + }
  119 +
  120 + public int getMultipleCategory() {
  121 + return multipleCategory;
  122 + }
  123 +
  124 + public void setMultipleCategory(int multipleCategory) {
  125 + this.multipleCategory = multipleCategory;
  126 + }
  127 +
  128 + public String getDefaultText() {
  129 + return defaultText;
  130 + }
  131 +
  132 + public void setDefaultText(String defaultText) {
  133 + this.defaultText = defaultText;
  134 + }
  135 +
  136 + public int getDetailAddress() {
  137 + return detailAddress;
  138 + }
  139 +
  140 + public void setDetailAddress(int detailAddress) {
  141 + this.detailAddress = detailAddress;
  142 + }
  143 +
  144 + public String getLabelColor() {
  145 + return labelColor;
  146 + }
  147 +
  148 + public void setLabelColor(String labelColor) {
  149 + this.labelColor = labelColor;
  150 + }
  151 +
  152 + public int getSource() {
  153 + return source;
  154 + }
  155 +
  156 + public void setSource(int source) {
  157 + this.source = source;
  158 + }
  159 +
  160 + public String getTitle() {
  161 + return title;
  162 + }
  163 +
  164 + public void setTitle(String title) {
  165 + this.title = title;
  166 + }
  167 +
  168 + /* public ReleaseVideoTypeListBean(Parcel in) {
  169 + id = in.readInt();
  170 + path = in.readString();
  171 + pic = in.readString();
  172 + text = in.readString();
  173 + videoType = in.readString();
  174 + changePath = in.readString();
  175 + multipleCategory = in.readInt();
  176 + }*/
  177 +
  178 + /* public static final Parcelable.Creator<ReleaseVideoTypeListBean> CREATOR = new Parcelable.Creator<ReleaseVideoTypeListBean>() {
  179 + @Override
  180 + public ReleaseVideoTypeListBean createFromParcel(Parcel in) {
  181 + return new ReleaseVideoTypeListBean(in);
  182 + }
  183 +
  184 + @Override
  185 + public ReleaseVideoTypeListBean[] newArray(int size) {
  186 + return new ReleaseVideoTypeListBean[size];
  187 + }
  188 + };*/
  189 +
  190 + public List<indextag> getCategoryTag() {
  191 + return categoryTag;
  192 + }
  193 +
  194 + public void setCategoryTag(List<indextag> categoryTag) {
  195 + this.categoryTag = categoryTag;
  196 + }
  197 +
  198 +
  199 + public int getMultiplecategory() {
  200 + return multipleCategory;
  201 + }
  202 +
  203 + public void setMultiplecategory(int multipleCategory) {
  204 + this.multipleCategory = multipleCategory;
  205 + }
  206 +
  207 +
  208 + public String getChangePath() {
  209 + return changePath;
  210 + }
  211 +
  212 + public void setChangePath(String changePath) {
  213 + this.changePath = changePath;
  214 + }
  215 +
  216 +
  217 + public int getId() {
  218 + return id;
  219 + }
  220 +
  221 + public void setId(int id) {
  222 + this.id = id;
  223 + }
  224 +
  225 + public String getPath() {
  226 + return TextUtils.isEmpty(path) ? "Daren/moment/releaseMoment.action" : path;
  227 + }
  228 +
  229 + public void setPath(String path) {
  230 + this.path = path;
  231 + }
  232 +
  233 + public String getPic() {
  234 + return TextUtils.isEmpty(pic) ? "https://wjj.ys1.cnliveimg.com/769/img/2018/0129/grzx_shq.png" : pic;
  235 + }
  236 +
  237 + public void setPic(String pic) {
  238 + this.pic = pic;
  239 + }
  240 +
  241 + public String getText() {
  242 + return TextUtils.isEmpty(text) ? "生活圈" : text;
  243 + }
  244 +
  245 + public void setText(String text) {
  246 + this.text = text;
  247 + }
  248 +
  249 + public String getVideoType() {
  250 + return videoType;
  251 + }
  252 +
  253 + public void setVideoType(String videoType) {
  254 + this.videoType = videoType;
  255 + }
  256 +
  257 + /* @Override
  258 + public int describeContents() {
  259 + return 0;
  260 + }
  261 +
  262 + @Override
  263 + public void writeToParcel(Parcel dest, int flags) {
  264 + dest.writeInt(id);
  265 + dest.writeString(path);
  266 + dest.writeString(pic);
  267 + dest.writeString(text);
  268 + dest.writeString(videoType);
  269 + dest.writeString(changePath);
  270 + dest.writeInt(multipleCategory);
  271 + }*/
  272 + }
  273 +
  274 + public static class indextag {
  275 + private String tagId;
  276 + private String tagName;
  277 + private String colour;
  278 +
  279 + public String getColour() {
  280 + return colour;
  281 + }
  282 +
  283 + public void setColour(String colour) {
  284 + this.colour = colour;
  285 + }
  286 +
  287 + public String getTagId() {
  288 + return tagId;
  289 + }
  290 +
  291 + public void setTagId(String tagId) {
  292 + this.tagId = tagId;
  293 + }
  294 +
  295 + public String getTagName() {
  296 + return tagName;
  297 + }
  298 +
  299 + public void setTagName(String tagName) {
  300 + this.tagName = tagName;
  301 + }
  302 + }
  303 +
  304 + public static class SnowVideoTypeListBean {
  305 + /**
  306 + * id : 333
  307 + * pic : https://wjj.ys1.cnliveimg.com/769/img/2018/0129/882612314493918438.jpg
  308 + * text : 上冰雪
  309 + * videoType : snow
  310 + * path : http://apiwjjtest.cnlive.com/Daren/snow/releaseSnow.action
  311 + */
  312 +
  313 + private int id;
  314 + private String pic;
  315 + private String text;
  316 + private String videoType;
  317 + private String path;
  318 + private String changePath;
  319 + private int multipleCategory;
  320 +
  321 + public int getMultiplecategory() {
  322 + return multipleCategory;
  323 + }
  324 +
  325 + public void setMultiplecategory(int multipleCategory) {
  326 + this.multipleCategory = multipleCategory;
  327 + }
  328 +
  329 + public String getChangePath() {
  330 + return changePath;
  331 + }
  332 +
  333 + public void setChangePath(String changePath) {
  334 + this.changePath = changePath;
  335 + }
  336 +
  337 + public int getId() {
  338 + return id;
  339 + }
  340 +
  341 + public void setId(int id) {
  342 + this.id = id;
  343 + }
  344 +
  345 + public String getPic() {
  346 + return pic;
  347 + }
  348 +
  349 + public void setPic(String pic) {
  350 + this.pic = pic;
  351 + }
  352 +
  353 + public String getText() {
  354 + return text;
  355 + }
  356 +
  357 + public void setText(String text) {
  358 + this.text = text;
  359 + }
  360 +
  361 + public String getVideoType() {
  362 + return videoType;
  363 + }
  364 +
  365 + public void setVideoType(String videoType) {
  366 + this.videoType = videoType;
  367 + }
  368 +
  369 + public String getPath() {
  370 + return path;
  371 + }
  372 +
  373 + public void setPath(String path) {
  374 + this.path = path;
  375 + }
  376 + }
  377 +}
... ...