├── 360RePlugin
├── README.md
├── RePlugin
│ ├── .gitignore
│ ├── app
│ │ ├── .gitignore
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── replugin
│ │ │ │ └── pro
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── base
│ │ │ │ └── BaseApplication.java
│ │ │ └── res
│ │ │ ├── layout
│ │ │ └── activity_main.xml
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── RePluginDemo
│ ├── .gitignore
│ ├── app
│ │ ├── .gitignore
│ │ ├── build.gradle
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── replugin
│ │ │ │ └── demo
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── TipsActivity.java
│ │ │ └── res
│ │ │ ├── drawable-v24
│ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── drawable
│ │ │ └── ic_launcher_background.xml
│ │ │ ├── layout
│ │ │ ├── activity_main.xml
│ │ │ └── activity_tips.xml
│ │ │ ├── mipmap-anydpi-v26
│ │ │ ├── ic_launcher.xml
│ │ │ └── ic_launcher_round.xml
│ │ │ ├── mipmap-hdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-mdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
└── plugin_demo.apk
├── AndroidVideoClip
├── .gitignore
├── README.md
├── app
│ ├── build.gradle
│ ├── libs
│ │ └── isoviewer-1.0-RC-27.jar
│ ├── proguard-rules.pro
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── play
│ │ │ └── pro
│ │ │ ├── BaseApplication.java
│ │ │ ├── FullScreenActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── constants
│ │ │ └── FinalConstants.java
│ │ │ ├── player
│ │ │ ├── MediaManager.java
│ │ │ └── PlayerControl.java
│ │ │ ├── utils
│ │ │ ├── ProUtils.java
│ │ │ ├── ScreenUtils.java
│ │ │ ├── TimerUtils.java
│ │ │ ├── ToastUtils.java
│ │ │ └── TrimVideoUtils.java
│ │ │ └── widgets
│ │ │ └── VideoSeekBar.java
│ │ └── res
│ │ ├── drawable
│ │ ├── ic_back_wy_selector.xml
│ │ └── seekbar_media_paly.xml
│ │ ├── layout
│ │ ├── activity_full_screen.xml
│ │ ├── activity_main.xml
│ │ └── include_player.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_back_white.png
│ │ ├── ic_back_yellow.png
│ │ ├── ic_cut.png
│ │ ├── ic_launcher.png
│ │ ├── ic_loading_point_grey.png
│ │ ├── ic_loading_point_white.png
│ │ ├── ic_logo.png
│ │ ├── ic_media_fullscreen_shrink_white.png
│ │ ├── ic_media_fullscreen_stretch_white.png
│ │ ├── ic_media_play.png
│ │ ├── ic_media_stop.png
│ │ ├── ic_seekbar_thumb.png
│ │ ├── ic_slider_left.png
│ │ └── ic_slider_right.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ └── values
│ │ ├── color.xml
│ │ ├── strings.xml
│ │ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── BuglyHotfix
├── .gitignore
├── README.md
├── app
│ ├── .gitignore
│ ├── build.gradle
│ ├── demo.jks
│ ├── proguard-rules.pro
│ ├── src
│ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── java
│ │ │ └── bugly
│ │ │ │ └── hotfix
│ │ │ │ └── pro
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── base
│ │ │ │ ├── SampleApplication.java
│ │ │ │ └── SampleApplicationLike.java
│ │ │ └── res
│ │ │ ├── layout
│ │ │ └── activity_main.xml
│ │ │ ├── mipmap-xxhdpi
│ │ │ ├── ic_launcher.png
│ │ │ └── ic_launcher_round.png
│ │ │ ├── values
│ │ │ ├── colors.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ │ └── xml
│ │ │ └── provider_paths.xml
│ └── tinker-support.gradle
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── LICENSE
├── PlaySeekbar
├── .gitignore
├── README.md
├── app
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── play
│ │ │ └── pro
│ │ │ ├── BaseApplication.java
│ │ │ ├── FullScreenActivity.java
│ │ │ ├── MainActivity.java
│ │ │ ├── constants
│ │ │ └── FinalConstants.java
│ │ │ ├── player
│ │ │ ├── MediaManager.java
│ │ │ └── PlayerControl.java
│ │ │ ├── utils
│ │ │ ├── ProUtils.java
│ │ │ ├── ScreenUtils.java
│ │ │ ├── TimerUtils.java
│ │ │ └── ToastUtils.java
│ │ │ └── widgets
│ │ │ └── VideoSeekBar.java
│ │ └── res
│ │ ├── drawable
│ │ ├── ic_back_wy_selector.xml
│ │ └── seekbar_media_paly.xml
│ │ ├── layout
│ │ ├── activity_full_screen.xml
│ │ ├── activity_main.xml
│ │ └── include_player.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_back_white.png
│ │ ├── ic_back_yellow.png
│ │ ├── ic_launcher.png
│ │ ├── ic_loading_point_grey.png
│ │ ├── ic_loading_point_white.png
│ │ ├── ic_logo.png
│ │ ├── ic_media_fullscreen_shrink_white.png
│ │ ├── ic_media_fullscreen_stretch_white.png
│ │ ├── ic_media_play.png
│ │ ├── ic_media_stop.png
│ │ ├── ic_seekbar_thumb.png
│ │ ├── ic_slider_left.png
│ │ └── ic_slider_right.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ └── values
│ │ ├── color.xml
│ │ ├── strings.xml
│ │ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── mdFile
│ └── img1.gif
└── settings.gradle
├── README.md
├── RecordVideo
├── README.md
├── app
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── record
│ │ │ └── video
│ │ │ ├── activitys
│ │ │ ├── MainActivity.java
│ │ │ ├── MediaRecordActivity.java
│ │ │ └── MediaResultPreActivity.java
│ │ │ ├── bean
│ │ │ ├── MediaInfoBean.java
│ │ │ └── item
│ │ │ │ ├── AbsMediaInfoItem.java
│ │ │ │ ├── MediaItem.java
│ │ │ │ └── media
│ │ │ │ ├── ImageInfoItem.java
│ │ │ │ └── VideoInfoItem.java
│ │ │ ├── config
│ │ │ ├── able
│ │ │ │ └── ResultCallback.java
│ │ │ ├── base
│ │ │ │ └── BaseApplication.java
│ │ │ └── constants
│ │ │ │ ├── KeyConstants.java
│ │ │ │ ├── NotifyConstants.java
│ │ │ │ └── ProConstants.java
│ │ │ ├── utils
│ │ │ ├── CameraUtils.java
│ │ │ ├── DevUtils.java
│ │ │ ├── MediaDealUtils.java
│ │ │ ├── RotateTransformation.java
│ │ │ ├── TimerUtils.java
│ │ │ ├── ToastUtils.java
│ │ │ └── player
│ │ │ │ ├── RecordMediaManager.java
│ │ │ │ └── RecordPlayerControl.java
│ │ │ └── widget
│ │ │ ├── MediaRecorderView.java
│ │ │ ├── RecordLoadDialog.java
│ │ │ └── RecordProgressBar.java
│ │ └── res
│ │ ├── anim
│ │ ├── anim_record_loading.xml
│ │ ├── noanim_left_in.xml
│ │ └── noanim_left_out.xml
│ │ ├── drawable-hdpi
│ │ ├── chat_focusing.png
│ │ ├── chat_play_big.png
│ │ ├── chat_play_middle.png
│ │ ├── photograph.png
│ │ ├── photograph_back.png
│ │ ├── photograph_confirm.png
│ │ ├── photograph_invert_camera.png
│ │ ├── photograph_return.png
│ │ └── photograph_transcribe.png
│ │ ├── drawable-xhdpi
│ │ ├── chat_focusing.png
│ │ ├── chat_op_loading.png
│ │ ├── chat_play_big.png
│ │ ├── chat_play_middle.png
│ │ ├── photograph.png
│ │ ├── photograph_back.png
│ │ ├── photograph_confirm.png
│ │ ├── photograph_invert_camera.png
│ │ ├── photograph_return.png
│ │ └── photograph_transcribe.png
│ │ ├── drawable
│ │ └── camera_reverse_selector.xml
│ │ ├── layout
│ │ ├── activity_main.xml
│ │ ├── activity_media_record.xml
│ │ ├── activity_media_result_pre.xml
│ │ ├── dialog_record_load.xml
│ │ └── inflate_media_recorder.xml
│ │ ├── mipmap-mdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── mipmap-xhdpi
│ │ ├── ic_launcher.png
│ │ └── ic_launcher_round.png
│ │ ├── values-1024x600
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-1024x768
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-1136x640
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-1184x720
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-1196x720
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-1280x720
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-1280x768
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-1280x800
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-1334x750
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-1776x1080
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-1812x1080
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-1920x1080
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-2560x1440
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-480x320
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-800x480
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-845x480
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ ├── values-960x540
│ │ ├── lay_x.xml
│ │ └── lay_y.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── mdFile
│ ├── img1.png
│ ├── img2.png
│ ├── img3.png
│ └── img4.png
└── settings.gradle
├── RecordView
├── .gitignore
├── README.md
├── app
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── pro
│ │ │ └── record
│ │ │ ├── MainActivity.java
│ │ │ ├── utils
│ │ │ ├── ProUtils.java
│ │ │ └── ScreenUtils.java
│ │ │ └── widgets
│ │ │ └── RecordTimeView.java
│ │ └── res
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-xxhdpi
│ │ ├── ic_launcher.png
│ │ ├── ic_location.png
│ │ ├── ic_play.png
│ │ └── ic_stop.png
│ │ └── values
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── mdFile
│ └── img1.gif
└── settings.gradle
└── SophixPro
├── .gitignore
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── sophix
│ │ └── pro
│ │ ├── MainActivity.java
│ │ ├── base
│ │ ├── BaseApplication.java
│ │ └── hotfix
│ │ │ └── SophixStubApplication.java
│ │ └── utils
│ │ ├── AppUtils.java
│ │ ├── LogPrintUtils.java
│ │ └── ToastUtils.java
│ └── res
│ ├── layout
│ └── activity_main.xml
│ ├── mipmap-xxhdpi
│ └── logo.png
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── demo.jks
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── mdFile
├── hint.txt
├── img1.png
└── 包.zip
└── settings.gradle
/360RePlugin/README.md:
--------------------------------------------------------------------------------
1 | # [360RePlugin](https://github.com/afkT/Android/tree/master/360RePlugin)
2 |
3 | Android 插件化开发 - 360 RePlugin 框架
4 |
5 |
6 | - 具体参照 Demo
7 |
8 | - RePlugin 主程序
9 |
10 | - RePluginDemo 插件程序 -> 后续新插件都以该插件 Demo 相同
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | defaultConfig {
6 | applicationId "replugin.pro"
7 | minSdkVersion 19
8 | targetSdkVersion 27
9 | versionCode 1
10 | versionName "1.0"
11 | }
12 | buildTypes {
13 | release {
14 | minifyEnabled false
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
16 | }
17 | }
18 | }
19 |
20 | dependencies {
21 | implementation fileTree(dir: 'libs', include: ['*.jar'])
22 | implementation 'com.android.support:appcompat-v7:27.1.1'
23 | implementation 'com.android.support.constraint:constraint-layout:1.1.0'
24 |
25 | compile 'com.qihoo360.replugin:replugin-host-lib:2.2.4'
26 | }
27 |
28 | // ATTENTION!!! Must be PLACED AFTER "android{}" to read the applicationId
29 | apply plugin: 'replugin-host-gradle'
30 |
31 | /**
32 | * 配置项均为可选配置,默认无需添加
33 | * 更多可选配置项参见replugin-host-gradle的RepluginConfig类
34 | * 可更改配置项参见 自动生成RePluginHostConfig.java
35 | */
36 | repluginHostConfig {
37 | /**
38 | * 是否使用 AppCompat 库
39 | * 不需要个性化配置时,无需添加
40 | */
41 | useAppCompat = true
42 | /**
43 | * 背景不透明的坑的数量
44 | * 不需要个性化配置时,无需添加
45 | */
46 | countNotTranslucentStandard = 6
47 | countNotTranslucentSingleTop = 2
48 | countNotTranslucentSingleTask = 3
49 | countNotTranslucentSingleInstance = 2
50 | }
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/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
22 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/app/src/main/java/replugin/pro/MainActivity.java:
--------------------------------------------------------------------------------
1 | package replugin.pro;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 | import android.view.View;
6 |
7 | import com.qihoo360.replugin.RePlugin;
8 | import com.qihoo360.replugin.model.PluginInfo;
9 |
10 | public class MainActivity extends AppCompatActivity implements View.OnClickListener{
11 |
12 | @Override
13 | protected void onCreate(Bundle savedInstanceState) {
14 | super.onCreate(savedInstanceState);
15 | setContentView(R.layout.activity_main);
16 | }
17 |
18 | // 中文文档
19 | // https://github.com/Qihoo360/RePlugin/blob/dev/README_CN.md
20 |
21 | // 主程序 项目
22 | // https://github.com/Qihoo360/RePlugin/wiki/主程序接入指南
23 |
24 | // 插件项目 - 属于单独打包出来的 apk
25 | // https://github.com/Qihoo360/RePlugin/wiki/插件接入指南
26 |
27 | // 完整目录结构
28 | // https://github.com/Qihoo360/RePlugin/wiki/详细教程
29 |
30 | // 插件安装、卸载更新等
31 | // https://github.com/Qihoo360/RePlugin/wiki/插件的管理
32 |
33 | // 插件组件、跳转使用等
34 | // https://github.com/Qihoo360/RePlugin/wiki/插件的组件
35 |
36 | // 插件apk地址, 使用外置插件方式
37 | private String pluginApk = "plugin_demo.apk";
38 | // 插件名 -> 其实就是插件的包名, 具有唯一性
39 | private String pluginPack = "replugin.demo";
40 |
41 | @Override
42 | public void onClick(View v) {
43 | switch (v.getId()){
44 | case R.id.vid_install:
45 | try {
46 | // 安装插件
47 | PluginInfo pi = RePlugin.install("/sdcard/" + pluginApk);
48 | if (pi != null) {
49 | // 预加载插件
50 | RePlugin.preload(pi);
51 | }
52 | } catch (Exception e){
53 | e.printStackTrace();
54 | }
55 | break;
56 | case R.id.vid_uninstall:
57 | try {
58 | // 卸载插件
59 | RePlugin.uninstall(pluginPack);
60 | } catch (Exception e){
61 | e.printStackTrace();
62 | }
63 | break;
64 | case R.id.vid_start:
65 | try {
66 | // 跳转插件页面
67 | RePlugin.startActivity(MainActivity.this, RePlugin.createIntent(pluginPack,
68 | "replugin.demo.MainActivity"));
69 | } catch (Exception e){
70 | e.printStackTrace();
71 | }
72 | break;
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/app/src/main/java/replugin/pro/base/BaseApplication.java:
--------------------------------------------------------------------------------
1 | package replugin.pro.base;
2 |
3 | import com.qihoo360.replugin.RePluginApplication;
4 |
5 | /**
6 | * Created by Administrator on 2018/6/5.
7 | */
8 |
9 | public class BaseApplication extends RePluginApplication {
10 | }
11 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
17 |
18 |
26 |
27 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePlugin/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePlugin/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | RePlugin
3 |
4 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.0'
11 |
12 | classpath 'com.qihoo360.replugin:replugin-host-gradle:2.2.4'
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 | }
23 | }
24 |
25 | task clean(type: Delete) {
26 | delete rootProject.buildDir
27 | }
28 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePlugin/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Jun 05 14:10:40 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/360RePlugin/RePlugin/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | defaultConfig {
6 | applicationId "replugin.demo"
7 | minSdkVersion 19
8 | targetSdkVersion 27
9 | versionCode 1
10 | versionName "1.0"
11 | }
12 | buildTypes {
13 | release {
14 | minifyEnabled false
15 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
16 | }
17 | }
18 | }
19 |
20 | dependencies {
21 | implementation fileTree(dir: 'libs', include: ['*.jar'])
22 | implementation 'com.android.support:appcompat-v7:27.1.1'
23 | implementation 'com.android.support.constraint:constraint-layout:1.1.0'
24 |
25 | compile 'com.qihoo360.replugin:replugin-plugin-lib:2.2.4'
26 | }
27 |
28 | apply plugin: 'replugin-plugin-gradle'
29 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/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
22 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/java/replugin/demo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package replugin.demo;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.view.View;
7 |
8 | public class MainActivity extends AppCompatActivity implements View.OnClickListener {
9 |
10 | @Override
11 | protected void onCreate(Bundle savedInstanceState) {
12 | super.onCreate(savedInstanceState);
13 | setContentView(R.layout.activity_main);
14 | }
15 |
16 | @Override
17 | public void onClick(View v) {
18 | if (v.getId() == R.id.vid_btn) {
19 | startActivity(new Intent(this, TipsActivity.class));
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/java/replugin/demo/TipsActivity.java:
--------------------------------------------------------------------------------
1 | package replugin.demo;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 |
6 | public class TipsActivity extends AppCompatActivity {
7 |
8 | @Override
9 | protected void onCreate(Bundle savedInstanceState) {
10 | super.onCreate(savedInstanceState);
11 | setContentView(R.layout.activity_tips);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/layout/activity_tips.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePluginDemo/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePluginDemo/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePluginDemo/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePluginDemo/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePluginDemo/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | RePluginDemo
3 |
4 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.0'
11 |
12 | classpath 'com.qihoo360.replugin:replugin-plugin-gradle:2.2.4'
13 |
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | google()
22 | jcenter()
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/RePluginDemo/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Jun 05 14:20:43 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/360RePlugin/RePluginDemo/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/360RePlugin/plugin_demo.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/360RePlugin/plugin_demo.apk
--------------------------------------------------------------------------------
/AndroidVideoClip/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.0"
6 | defaultConfig {
7 | applicationId "com.play.pro"
8 | minSdkVersion 19
9 | targetSdkVersion 23
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(include: ['*.jar'], dir: 'libs')
24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25 | exclude group: 'com.android.support', module: 'support-annotations'
26 | })
27 | compile 'com.android.support:appcompat-v7:23.0.0'
28 | compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
29 | compile files('libs/isoviewer-1.0-RC-27.jar')
30 | }
31 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/libs/isoviewer-1.0-RC-27.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/libs/isoviewer-1.0-RC-27.jar
--------------------------------------------------------------------------------
/AndroidVideoClip/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in F:\Development\AndroidStudio\SDK\android_sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/java/com/play/pro/BaseApplication.java:
--------------------------------------------------------------------------------
1 | package com.play.pro;
2 |
3 | import com.nostra13.universalimageloader.core.DisplayImageOptions;
4 | import com.nostra13.universalimageloader.core.ImageLoader;
5 | import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
6 | import com.nostra13.universalimageloader.core.assist.ImageScaleType;
7 | import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
8 | import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
9 |
10 | import android.app.Application;
11 | import android.content.Context;
12 | import android.graphics.Bitmap.Config;
13 |
14 | /**
15 | * 整个项目全局对象
16 | */
17 | public class BaseApplication extends Application {
18 |
19 | /** 全局上下文 */
20 | protected Context mContext;
21 |
22 | @Override
23 | public void onCreate() {
24 | super.onCreate();
25 | // 初始化全局上下文
26 | mContext = getApplicationContext();
27 | // 初始化ImageLoader
28 | initImageLoader();
29 | }
30 |
31 | @Override
32 | public void onLowMemory() {
33 | super.onLowMemory();
34 | }
35 |
36 | // =============================
37 |
38 | public void initImageLoader() {
39 | // 图片缓存
40 | DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
41 | //.showImageOnLoading(R.drawable.bg_df_loader) // 设置图片在下载期间显示的图片
42 | ////.showStubImage(R.drawable.loading_image_hint) // 设置图片在下载期间显示的图片
43 | //.showImageForEmptyUri(R.drawable.bg_df_loader) // 设置图片Uri为空或是错误的时候显示的图片
44 | //.showImageOnFail(R.drawable.bg_df_loader) // 设置图片加载/解码过程中错误时候显示的图片
45 | .imageScaleType(ImageScaleType.EXACTLY) // 设置图片缩放
46 | .bitmapConfig(Config.RGB_565) // 图片解码类型
47 | .cacheInMemory(true)// 是否保存到内存
48 | .cacheOnDisk(true).build();// 是否保存到sd卡上(硬盘控件)
49 |
50 | // 针对图片缓存的全局配置,主要有线程类、缓存大小、磁盘大小、图片下载与解析、日志方面的配置。
51 | ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(mContext)
52 | .defaultDisplayImageOptions(defaultOptions) // 加载DisplayImageOptions参数
53 | .threadPriority(Thread.NORM_PRIORITY - 2) // 线程池内加载的数量
54 | .denyCacheImageMultipleSizesInMemory()
55 | //.memoryCache(new UsingFreqLimitedMemoryCache(1024 * 1024)) // 通过自己的内存缓存实现
56 | .memoryCacheSize(2 * 1024 * 1024) // 内存缓存最大值
57 | .memoryCacheSizePercentage(13)
58 | //.diskCacheSize(50 * 1024 * 1024) // SD卡缓存最大值 50mb
59 | //.discCacheFileNameGenerator(new Md5FileNameGenerator()) // 将保存的时候的URI名称用MD5 加密
60 | //.diskCacheFileCount(100) // 缓存的文件数量
61 | //.memoryCache(new WeakMemoryCache()).diskCacheFileNameGenerator(new HashCodeFileNameGenerator())
62 | .imageDownloader(new BaseImageDownloader(mContext)) // default
63 | .tasksProcessingOrder(QueueProcessingType.LIFO).build();
64 | ImageLoader.getInstance().init(config);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/java/com/play/pro/constants/FinalConstants.java:
--------------------------------------------------------------------------------
1 | package com.play.pro.constants;
2 |
3 | /**
4 | * 常量配置
5 | */
6 | public class FinalConstants {
7 |
8 | /** 基数 */
9 | public static final int FINAL_BASE = 1000;
10 | // --
11 | /** 返回 */
12 | public static final int BACK = FINAL_BASE + 1;
13 | /** 全屏 */
14 | public static final int FULL_SCREEN = FINAL_BASE + 2;
15 | /** 播放 */
16 | public static final int PLAY_START = FINAL_BASE + 3;
17 | /** 恢复播放 */
18 | public static final int PLAY_RESTART = FINAL_BASE + 4;
19 | /** 暂停播放 */
20 | public static final int PLAY_PAUSE = FINAL_BASE + 5;
21 | /** 播放结束 */
22 | public static final int PLAY_COMPLE = FINAL_BASE + 6;
23 | /** 播放时间定时器触发 */
24 | public static final int PLAY_TIME = FINAL_BASE + 7;
25 | /** 倒计时定时器触发 */
26 | public static final int COUNT_DOWN = FINAL_BASE + 8;
27 | /** 重新加载 */
28 | public static final int RELOAD = FINAL_BASE + 9;
29 | /** 播放异常 */
30 | public static final int PLAY_ERROR = FINAL_BASE + 10;
31 | /** 播放时间改变触发 */
32 | public static final int PLAY_TIME_CHANGE = FINAL_BASE + 11;
33 |
34 | /** 封面地址 */
35 | public static final String COVER_URL = "coverUrl";
36 | /** 视频地址 */
37 | public static final String VIDEO_URL = "videoUrl";
38 | /** 是否播放结束 */
39 | public static final String IS_PLAY_FINISH = "isPlayFinish";
40 | /** 是否点击Home键 */
41 | public static final String IS_CLICK_HOME = "isClickHome";
42 | }
43 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/java/com/play/pro/utils/TimerUtils.java:
--------------------------------------------------------------------------------
1 | package com.play.pro.utils;
2 |
3 | import java.util.Timer;
4 | import java.util.TimerTask;
5 |
6 | import android.os.Handler;
7 |
8 | /**
9 | * 定时器工具类
10 | */
11 | public class TimerUtils {
12 |
13 | /** 定时器 */
14 | private Timer timer;
15 | /** 定时器任务栈 */
16 | private TimerTask timerTask;
17 | /** 通知Handler */
18 | private Handler handler;
19 | /** 通知类型 */
20 | private int notifyWhat;
21 | // --
22 | /** 延迟时间 - 多少毫秒后开始执行 */
23 | private long delay;
24 | /** 循环时间 - 每隔多少秒执行一次 */
25 | private long period;
26 | /** 触发次数上限 */
27 | private int triggerLimit = 1;
28 | /** 触发次数 */
29 | private int triggerNumber = 0;
30 |
31 | public TimerUtils() {
32 | super();
33 | }
34 |
35 | public TimerUtils(Handler handler) {
36 | super();
37 | this.handler = handler;
38 | }
39 |
40 |
41 | /**
42 | * 定时器操作
43 | * @param isOpen 是否打开
44 | */
45 | private void timerOperate(boolean isOpen){
46 | if (isOpen) {
47 | // 每次重置触发次数
48 | triggerNumber = 0;
49 | try {
50 | if (timer != null) {
51 | timer.cancel();
52 | timer = null;
53 | }
54 | if (timerTask != null) {
55 | timerTask.cancel();
56 | timerTask = null;
57 | }
58 | } catch (Exception e) {
59 | }
60 | // 开启定时器
61 | timer = new Timer(); // 每次重新new 防止被取消
62 | // 重新生成定时器 防止出现TimerTask is scheduled already 所以同一个定时器任务只能被放置一次
63 | timerTask = new TimerTask() {
64 | @Override
65 | public void run() {
66 | // 先进行通知
67 | if(handler != null){
68 | handler.sendEmptyMessage(notifyWhat);
69 | }
70 | // 累积触发次数
71 | triggerNumber++;
72 | // 如果大于触发次数,则关闭
73 | if(triggerNumber >= triggerLimit && triggerLimit >= 0){
74 | // 进行关闭
75 | timerOperate(false);
76 | }
77 | }
78 | };
79 | try {
80 | // xx毫秒后执行,每隔xx毫秒再执行一次
81 | timer.schedule(timerTask, delay, period);
82 | } catch (Exception e) {
83 | }
84 | } else {
85 | try {
86 | if (timer != null) {
87 | timer.cancel();
88 | timer = null;
89 | }
90 | if (timerTask != null) {
91 | timerTask.cancel();
92 | timerTask = null;
93 | }
94 | } catch (Exception e) {
95 | }
96 | }
97 | }
98 |
99 |
100 | // ================ 对外公开方法 =====================
101 | /**
102 | * 设置通知的Handler
103 | * @param handler
104 | */
105 | public void setHandler(Handler handler) {
106 | this.handler = handler;
107 | }
108 |
109 | /**
110 | * 设置通知的What
111 | * @param notifyWhat
112 | */
113 | public void setNotifyWhat(int notifyWhat) {
114 | this.notifyWhat = notifyWhat;
115 | }
116 |
117 | /**
118 | * 设置时间
119 | * @param delay 延迟时间 - 多少毫秒后开始执行
120 | * @param period 循环时间 - 每隔多少秒执行一次
121 | */
122 | public void setTime(long delay, long period) {
123 | this.delay = delay;
124 | this.period = period;
125 | }
126 |
127 | /**
128 | * 设置触发次数上限
129 | * @param triggerLimit
130 | */
131 | public void setTriggerLimit(int triggerLimit) {
132 | this.triggerLimit = triggerLimit;
133 | }
134 |
135 |
136 | // ========================
137 |
138 | /** 开始定时 */
139 | public void startTimer(){
140 | timerOperate(true);
141 | }
142 |
143 | /** 关闭定时 */
144 | public void closeTimer(){
145 | timerOperate(false);
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/java/com/play/pro/utils/ToastUtils.java:
--------------------------------------------------------------------------------
1 | package com.play.pro.utils;
2 |
3 | import android.content.Context;
4 | import android.widget.Toast;
5 |
6 | /**
7 | * 自定义Toast工具类,防止用户快速操作导致Dialog多次显示
8 | */
9 | public class ToastUtils {
10 |
11 | /** 系统默认延时 */
12 | private static Toast mToast;
13 |
14 | public static void showToast(Context mContext, String text, int duration) {
15 | if (mToast != null) {
16 | mToast.setText(text);
17 | mToast.setDuration(duration);
18 | } else {
19 | mToast = Toast.makeText(mContext, text, duration);
20 | }
21 | mToast.show();
22 | }
23 |
24 | public static void showToast(Context mContext, String text) {
25 | showToast(mContext, text, Toast.LENGTH_SHORT);
26 | }
27 |
28 | public static void showToast(Context mContext, int resId) {
29 | showToast(mContext, mContext.getResources().getString(resId), Toast.LENGTH_SHORT);
30 | }
31 |
32 | public static void showToast(Context mContext, int resId, Object... obj) {
33 | showToast(mContext, mContext.getResources().getString(resId, obj), Toast.LENGTH_SHORT);
34 | }
35 |
36 | public static void showToast(Context mContext, int resId, int duration) {
37 | showToast(mContext, mContext.getResources().getString(resId), duration);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/drawable/ic_back_wy_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/drawable/seekbar_media_paly.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 |
9 |
10 |
11 |
12 | -
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | -
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/layout/activity_full_screen.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
14 |
15 |
19 |
20 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
12 |
13 |
17 |
18 |
22 |
23 |
24 |
32 |
33 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_back_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_back_white.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_back_yellow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_back_yellow.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_cut.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_cut.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_loading_point_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_loading_point_grey.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_loading_point_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_loading_point_white.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_logo.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_media_fullscreen_shrink_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_media_fullscreen_shrink_white.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_media_fullscreen_stretch_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_media_fullscreen_stretch_white.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_media_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_media_play.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_media_stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_media_stop.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_seekbar_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_seekbar_thumb.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_slider_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_slider_left.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_slider_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xhdpi/ic_slider_right.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/values/color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | #FF0000
6 | #000000
7 | #66000000
8 | #00000000
9 | #FFFFFF
10 | #CCFFFFFF
11 | #808080
12 | #a0000000
13 | #0080FF
14 | #0000FF
15 |
16 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PlaySeekBar
5 |
6 |
--------------------------------------------------------------------------------
/AndroidVideoClip/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/AndroidVideoClip/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/AndroidVideoClip/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/AndroidVideoClip/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/AndroidVideoClip/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/AndroidVideoClip/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/AndroidVideoClip/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/AndroidVideoClip/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/BuglyHotfix/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/BuglyHotfix/README.md:
--------------------------------------------------------------------------------
1 | # [BuglyHotfix](https://github.com/afkT/Android/tree/master/BuglyHotfix)
2 |
3 | Android 热修复 - Bugly
4 |
5 |
6 | ### Gradle
7 |
8 | ```
9 | dependencies {
10 | compile "com.android.support:multidex:1.0.1" // 多 dex 配置
11 |
12 | // 注释掉原有 bugly 的仓库
13 | // 其中 latest.release 指代最新版本号,也可以指定明确的版本号,例如 2.3.2
14 | // compile 'com.tencent.bugly:crashreport:latest.release'
15 |
16 | // https://blog.csdn.net/y505772146/article/details/78966676
17 | compile 'com.tencent.bugly:crashreport_upgrade:1.3.4'
18 |
19 | // 其中 latest.release 指代最新版本号,也可以指定明确的版本号,例如 2.2.0
20 | compile 'com.tencent.bugly:nativecrashreport:latest.release'
21 | }
22 | ```
23 |
24 | ### 使用方法
25 |
26 | - [热更新使用指南](https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix/?v=20180521124306)
27 |
28 | - [热更新使用详解](https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix-demo/?v=20180521124306)
29 |
30 | - [官方 Demo](https://github.com/BuglyDevTeam/Bugly-Android-Demo)
31 |
32 | ### 注意事项
33 |
34 | ``` java
35 | // 需要注意的是,假设我发了个包
36 | // 然后这个包有 bug,这个时候以这个基准包,生成了 Tinker 补丁,然后发布
37 | // 但是发现修复了第一个 bug 后,导致出现了第二个 bug
38 | // 这个时候打的差异包,必须还是最开始的基准包 (发包的 apk),这样才能直接修复没有更新过补丁的用户
39 | // 以及修复,更新过一次补丁,导致二次 bug 的用户
40 | // 以此类推,每次的基准包都是以发包的版本为基准包,只是修复的差异包,一直包含最新的代码
41 |
42 | // 反正步骤,如下:只要基础包生成过一次后,或者指定位置后,只需要每次修复都是 buildTinkerPatchRelease 上传补丁就行
43 | // https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix-demo/?v=20180521124306
44 | // 每次先生成基准包 在 :app -> Tasks -> build -> assembleRelease 构建后,复制最新的地址替换 baseApkDir
45 | // 接着进行修复bug,修复好了后,更改 tinkerId
46 | // 并且进行 :app -> Tasks -> tinker-support -> buildTinkerPatchRelease 生成补丁包
47 | ```
48 |
49 |
50 | - 具体配置方法在 tinker-support.gradle 中
51 |
52 | - [https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix-demo/?v=20180521124306](https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix-demo/?v=20180521124306)
53 |
54 | - 每次先生成基准包 在 :app -> Tasks -> build -> assembleRelease 构建后,复制最新的地址替换 baseApkDir
55 |
56 | - 接着进行修复bug,修复好了后,更改 tinkerId
57 |
58 | - 并且进行 :app -> Tasks -> tinker-support -> buildTinkerPatchRelease 生成补丁包
--------------------------------------------------------------------------------
/BuglyHotfix/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/BuglyHotfix/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply from: 'tinker-support.gradle'
3 |
4 | // 使用 tinker-support.gradle 会出现
5 | //Error:Manifest Tasks does not support the manifestOutputFile property any more, please use the manifestOutputDirectory instead.
6 | //For more information, please check https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html
7 |
8 | android {
9 | compileSdkVersion 26
10 | defaultConfig {
11 | applicationId "bugly.hotfix.pro"
12 | minSdkVersion 19
13 | targetSdkVersion 26
14 | versionCode 1
15 | versionName "10.0.0"
16 |
17 | // 开启multidex
18 | multiDexEnabled true
19 |
20 | ndk {
21 | //设置支持的SO库架构
22 | abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
23 | }
24 |
25 | javaCompileOptions {
26 | annotationProcessorOptions {
27 | includeCompileClasspath = true //加上这行即可
28 | }
29 | }
30 | }
31 |
32 | // 签名配置
33 | signingConfigs {
34 | release {
35 | storeFile file("demo.jks")
36 | storePassword "123456"
37 | keyAlias "demo"
38 | keyPassword "123456"
39 | }
40 |
41 | debug {
42 | storeFile file("demo.jks")
43 | storePassword "123456"
44 | keyAlias "demo"
45 | keyPassword "123456"
46 | }
47 | }
48 |
49 | buildTypes {
50 | release {
51 | minifyEnabled false
52 | signingConfig signingConfigs.release
53 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
54 | }
55 | debug {
56 | debuggable true
57 | minifyEnabled false
58 | signingConfig signingConfigs.debug
59 | }
60 | }
61 | }
62 |
63 | dependencies {
64 | implementation fileTree(dir: 'libs', include: ['*.jar'])
65 | implementation 'com.android.support:appcompat-v7:26.1.0'
66 | implementation 'com.android.support.constraint:constraint-layout:1.1.0'
67 |
68 | compile "com.android.support:multidex:1.0.1" // 多dex配置
69 | // 注释掉原有bugly的仓库
70 | // compile 'com.tencent.bugly:crashreport:latest.release' // 其中latest.release指代最新版本号,也可以指定明确的版本号,例如2.3.2
71 | compile 'com.tencent.bugly:crashreport_upgrade:1.3.4' // https://blog.csdn.net/y505772146/article/details/78966676
72 | compile 'com.tencent.bugly:nativecrashreport:latest.release' // 其中latest.release指代最新版本号,也可以指定明确的版本号,例如2.2.0
73 | }
--------------------------------------------------------------------------------
/BuglyHotfix/app/demo.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/BuglyHotfix/app/demo.jks
--------------------------------------------------------------------------------
/BuglyHotfix/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
22 |
--------------------------------------------------------------------------------
/BuglyHotfix/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
32 |
33 |
38 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/BuglyHotfix/app/src/main/java/bugly/hotfix/pro/MainActivity.java:
--------------------------------------------------------------------------------
1 | package bugly.hotfix.pro;
2 |
3 | import android.support.v7.app.AppCompatActivity;
4 | import android.os.Bundle;
5 | import android.view.View;
6 | import android.widget.Button;
7 | import android.widget.Toast;
8 |
9 | public class MainActivity extends AppCompatActivity implements View.OnClickListener{
10 |
11 | // 热更新使用指南
12 | // https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix/?v=20180521124306
13 |
14 | // 热更新使用详解
15 | // https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix-demo/?v=20180521124306
16 |
17 | // 官方 demo
18 | // https://github.com/BuglyDevTeam/Bugly-Android-Demo
19 |
20 |
21 | Button vid_btn;
22 |
23 | @Override
24 | protected void onCreate(Bundle savedInstanceState) {
25 | super.onCreate(savedInstanceState);
26 | setContentView(R.layout.activity_main);
27 |
28 | vid_btn = findViewById(R.id.vid_btn);
29 |
30 | vid_btn.setText("点击显示结果");
31 | }
32 |
33 | // 需要注意的是, 假设我发了个包
34 | // 然后这个包有bug, 这个时候以这个基准包, 生成了Tinker补丁, 然后发布
35 | // 但是发现修复了第一个bug后, 导致出现了第二个bug
36 | // 这个时候打的差异包, 必须还是最开始的基准包(发包的apk), 这样才能直接修复没有更新过补丁的用户
37 | // 以及修复,更新过一次补丁,导致二次bug的用户
38 | // 以此类推,每次的基准包都是以发包的版本为基准包, 只是修复的差异包,一直包含最新的代码
39 |
40 | // 反正步骤 如下, 只要基础包生成过一次后, 或者指定位置后, 只需要每次修复都是 buildTinkerPatchRelease 上传补丁就行
41 | // https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix-demo/?v=20180521124306
42 | // 每次先生成基准包 在 :app -> Tasks -> build -> assembleRelease 构建后,复制最新的地址替换 baseApkDir
43 | // 接着进行修复bug, 修复好了后, 更改 tinkerId
44 | // 并且进行 :app -> Tasks -> tinker-support -> buildTinkerPatchRelease 生成补丁包
45 |
46 | @Override
47 | public void onClick(View v) {
48 |
49 | try {
50 | String data = null;
51 | data.split("1");
52 | } catch (Exception e){
53 | // 原始崩溃
54 | Toast.makeText(MainActivity.this, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
55 |
56 | // 第一次修复
57 | // Toast.makeText(MainActivity.this, "bug 已修复", Toast.LENGTH_SHORT).show();
58 |
59 | // 第二次修复
60 | // Toast.makeText(MainActivity.this, "bug 二次修复, 并且添加: " + getPackageName(), Toast.LENGTH_SHORT).show();
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/BuglyHotfix/app/src/main/java/bugly/hotfix/pro/base/SampleApplication.java:
--------------------------------------------------------------------------------
1 | package bugly.hotfix.pro.base;
2 |
3 | import com.tencent.tinker.loader.app.TinkerApplication;
4 | import com.tencent.tinker.loader.shareutil.ShareConstants;
5 |
6 | public class SampleApplication extends TinkerApplication {
7 |
8 | // https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix/?v=20180521124306
9 |
10 | public SampleApplication() {
11 | super(ShareConstants.TINKER_ENABLE_ALL, "bugly.hotfix.pro.base.SampleApplicationLike",
12 | "com.tencent.tinker.loader.TinkerLoader", false);
13 |
14 | // 注意:这个类集成TinkerApplication类,这里面不做任何操作,所有Application的代码都会放到ApplicationLike继承类当中
15 | // 参数解析
16 | // 参数1:tinkerFlags 表示Tinker支持的类型 dex only、library only or all suuport,default: TINKER_ENABLE_ALL
17 | // 参数2:delegateClassName Application代理类 这里填写你自定义的ApplicationLike
18 | // 参数3:loaderClassName Tinker的加载器,使用默认即可
19 | // 参数4:tinkerLoadVerifyFlag 加载dex或者lib是否验证md5,默认为false
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/BuglyHotfix/app/src/main/java/bugly/hotfix/pro/base/SampleApplicationLike.java:
--------------------------------------------------------------------------------
1 | package bugly.hotfix.pro.base;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Application;
5 | import android.content.Context;
6 | import android.content.Intent;
7 | import android.os.Build;
8 | import android.support.multidex.MultiDex;
9 |
10 | import com.tencent.bugly.Bugly;
11 | import com.tencent.bugly.beta.Beta;
12 | import com.tencent.tinker.loader.app.DefaultApplicationLike;
13 |
14 | public class SampleApplicationLike extends DefaultApplicationLike {
15 |
16 | public static final String TAG = "Tinker.SampleApplicationLike";
17 |
18 | public SampleApplicationLike(Application application, int tinkerFlags,
19 | boolean tinkerLoadVerifyFlag, long applicationStartElapsedTime,
20 | long applicationStartMillisTime, Intent tinkerResultIntent) {
21 | super(application, tinkerFlags, tinkerLoadVerifyFlag, applicationStartElapsedTime, applicationStartMillisTime, tinkerResultIntent);
22 | }
23 |
24 |
25 | @Override
26 | public void onCreate() {
27 | super.onCreate();
28 | // 这里实现SDK初始化,appId替换成你的在Bugly平台申请的appId
29 | // 调试时,将第三个参数改为true
30 | Bugly.init(getApplication(), "039d8ce6e4", true);
31 | }
32 |
33 |
34 | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
35 | @Override
36 | public void onBaseContextAttached(Context base) {
37 | super.onBaseContextAttached(base);
38 | // you must install multiDex whatever tinker is installed!
39 | MultiDex.install(base);
40 | // 安装tinker
41 | // TinkerManager.installTinker(this); 替换成下面Bugly提供的方法
42 | Beta.installTinker(this);
43 | }
44 |
45 | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
46 | public void registerActivityLifecycleCallback(Application.ActivityLifecycleCallbacks callbacks) {
47 | getApplication().registerActivityLifecycleCallbacks(callbacks);
48 | }
49 |
50 | }
--------------------------------------------------------------------------------
/BuglyHotfix/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/BuglyHotfix/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/BuglyHotfix/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/BuglyHotfix/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/BuglyHotfix/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/BuglyHotfix/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/BuglyHotfix/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | BuglyHotfix
3 |
4 |
--------------------------------------------------------------------------------
/BuglyHotfix/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/BuglyHotfix/app/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
11 |
--------------------------------------------------------------------------------
/BuglyHotfix/app/tinker-support.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.tencent.bugly.tinker-support'
2 |
3 | def bakPath = file("${buildDir}/bakApk/")
4 |
5 | /**
6 | * 此处填写每次构建生成的基准包目录
7 | */
8 | def baseApkDir = "app-0606-14-28-42"
9 |
10 |
11 | // https://bugly.qq.com/docs/user-guide/instruction-manual-android-hotfix-demo/?v=20180521124306
12 | // 每次先生成基准包 在 :app -> Tasks -> build -> assembleRelease 构建后,复制最新的地址替换 baseApkDir
13 | // 接着进行修复bug, 修复好了后, 更改 tinkerId
14 | // 并且进行 :app -> Tasks -> tinker-support -> buildTinkerPatchRelease 生成补丁包
15 |
16 | /**
17 | * 对于插件各参数的详细解析请参考
18 | */
19 | tinkerSupport {
20 |
21 | // 开启tinker-support插件,默认值true
22 | enable = true
23 |
24 | // 指定归档目录,默认值当前module的子目录tinker
25 | autoBackupApkDir = "${bakPath}"
26 |
27 | // 是否启用覆盖tinkerPatch配置功能,默认值false
28 | // 开启后tinkerPatch配置不生效,即无需添加tinkerPatch
29 | overrideTinkerPatchConfiguration = true
30 |
31 | // 编译补丁包时,必需指定基线版本的apk,默认值为空
32 | // 如果为空,则表示不是进行补丁包的编译
33 | // @{link tinkerPatch.oldApk }
34 | baseApk = "${bakPath}/${baseApkDir}/app-release.apk"
35 |
36 | // 对应tinker插件applyMapping
37 | baseApkProguardMapping = "${bakPath}/${baseApkDir}/app-release-mapping.txt"
38 |
39 | // 对应tinker插件applyResourceMapping
40 | baseApkResourceMapping = "${bakPath}/${baseApkDir}/app-release-R.txt"
41 |
42 | // 构建基准包和补丁包都要指定不同的tinkerId,并且必须保证唯一性
43 | tinkerId = "10.0.0-patch" // 10.0.0-base
44 | // 第一次更新 10.0.0-patch
45 | // 第二次更新 10.0.0-patch
46 | // ..xxxx 每次更新需要注意的时候, 必须以最开始的依赖包(发的包)
47 |
48 | // 构建多渠道补丁时使用
49 | // buildAllFlavorsDir = "${bakPath}/${baseApkDir}"
50 |
51 | // 是否启用加固模式,默认为false.(tinker-spport 1.0.7起支持)
52 | // isProtectedApp = true
53 |
54 | // 是否开启反射Application模式
55 | enableProxyApplication = false
56 |
57 | }
58 |
59 | /**
60 | * 一般来说,我们无需对下面的参数做任何的修改
61 | * 对于各参数的详细介绍请参考:
62 | * https://github.com/Tencent/tinker/wiki/Tinker-%E6%8E%A5%E5%85%A5%E6%8C%87%E5%8D%97
63 | */
64 | tinkerPatch {
65 | //oldApk ="${bakPath}/${appName}/app-release.apk"
66 | ignoreWarning = false
67 | useSign = true
68 | dex {
69 | dexMode = "jar"
70 | pattern = ["classes*.dex"]
71 | loader = []
72 | }
73 | lib {
74 | pattern = ["lib/*/*.so"]
75 | }
76 |
77 | res {
78 | pattern = ["res/*", "r/*", "assets/*", "resources.arsc", "AndroidManifest.xml"]
79 | ignoreChange = []
80 | largeModSize = 100
81 | }
82 |
83 | packageConfig {
84 | }
85 | sevenZip {
86 | zipArtifact = "com.tencent.mm:SevenZip:1.1.10"
87 | // path = "/usr/local/bin/7za"
88 | }
89 | buildConfig {
90 | keepDexApply = false
91 | //tinkerId = "1.0.1-base"
92 | //applyMapping = "${bakPath}/${appName}/app-release-mapping.txt" // 可选,设置mapping文件,建议保持旧apk的proguard混淆方式
93 | //applyResourceMapping = "${bakPath}/${appName}/app-release-R.txt" // 可选,设置R.txt文件,通过旧apk文件保持ResId的分配
94 | }
95 | }
--------------------------------------------------------------------------------
/BuglyHotfix/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.0'
11 |
12 | // 下面代码有个注意事项,否则会出现这个异常
13 | // Error:Cause: generateTinkerApk: Android Application plugin required
14 |
15 | // 意思主要是说 需要 Tinker 插件
16 | // 正常bugly 只有 classpath "com.tencent.bugly:tinker-support:1.0.8" 这一句
17 | // 需要先单独 加载 tinker 插件 然后同步一下, 接着再加载 tinkersupport 插件
18 | // 并且 app 主module的 build.gradle 暂时不能引用 tinker-support.gradle, 必须先加载好两个插件,按顺序后才能form
19 |
20 | // 先加载 tinker 插件
21 | // classpath ('com.tencent.tinker:tinker-patch-gradle-plugin:1.9.1');
22 |
23 | // tinkersupport插件, 其中lastest.release指拉取最新版本,也可以指定明确版本号,例如1.1.2
24 | classpath "com.tencent.bugly:tinker-support:latest.release"
25 |
26 | // 文档是1.0.8, 升级到1.1.2 解决
27 | // Error:Could not get unknown property 'apkVariantData' for object of type com.android.build.gradle.internal.api.ApplicationVariantImpl.
28 |
29 | // 使用最新的插件, 可以不需要引用 tinker 插件, 内部自动引用
30 | }
31 | }
32 |
33 | allprojects {
34 | repositories {
35 | google()
36 | jcenter()
37 | }
38 | }
39 |
40 | task clean(type: Delete) {
41 | delete rootProject.buildDir
42 | }
--------------------------------------------------------------------------------
/BuglyHotfix/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/BuglyHotfix/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/BuglyHotfix/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/BuglyHotfix/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Jun 05 20:58:31 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/BuglyHotfix/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/BuglyHotfix/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/PlaySeekbar/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/PlaySeekbar/README.md:
--------------------------------------------------------------------------------
1 | # [PlaySeekbar](https://github.com/afkT/Android/tree/master/PlaySeekbar)
2 |
3 | 视频裁剪自定义 View
4 |
5 |
6 | ### 功能需求与预览
7 |
8 | - 有个视频裁剪功能,需要自定义 View 具体如下
9 |
10 | 1. 裁剪选择区域模块,可以自定义最少裁剪时间
11 |
12 | 2. 当选择低于最少裁剪时间时,再次滑动会自动推动左右选择轴,直至碰到边缘为止
13 |
14 | 3. 选择空白区域,并左右滑动时自动推动选择轴的位置
15 |
16 | 4. 可选控制(是否裁剪模式,是否显示播放进度,裁剪模式下(未选中的背景增加阴影图层),播放过的背景增加阴影图层等)
17 |
18 | 
19 |
20 |
21 | ### 具体实现与使用
22 |
23 | - [VideoSeekBar.java](https://github.com/afkT/Android/blob/master/PlaySeekbar/app/src/main/java/com/play/pro/widgets/VideoSeekBar.java)
24 |
25 |
26 | ### 使用方法:
27 |
28 | > 运行 Demo 前需要找个视频, 并且在 MainActivity 设置本地视频地址
29 |
30 | ```java
31 | public void initValues(){
32 | // 初始化播放控制器
33 | playerControl = new PlayerControl(this, vHandler);
34 | // 根目录
35 | String rootPath = ProUtils.getSDCartPath();
36 | // 本地视频
37 | String videoUrl = rootPath + "/a.mp4";
38 | // --
39 | // videoUrl = rootPath + "/b.mp4";
40 | // 重新赋值地址
41 | PLAY_URL = videoUrl;
42 | // 加载视频封面
43 | playerControl.initLoad(COVER_URL, false);
44 | // 开始播放
45 | vHandler.sendEmptyMessage(FinalConstants.PLAY_START);
46 |
47 | // ====== 视频剪辑View ======
48 | // 进行重置
49 | am_video_seekbar.reset();
50 | // // 是否需要绘制进度 - 白色进度动,以及走过的画面背景变暗 - 统一控制setProgressLine(isDrawProgress), setProgressBG(isDrawProgress)
51 | // am_video_seekbar.setProgressDraw(isDrawProgress);
52 | // //// 是否需要绘制进度 - 播放中,有个白色的线条在动
53 | // am_video_seekbar.setProgressLine(isDrawProgressLine);
54 | // // 是否需要绘制进度 - 播放过的画面背景变暗
55 | // am_video_seekbar.setProgressBG(isDrawProgressBG);
56 | // // 是否属于裁剪模式 - 两边有进度滑动
57 | // am_video_seekbar.setCutMode(isCutMode);
58 | // // 是否属于裁剪模式 - 是否绘制非裁剪模块变暗
59 | // am_video_seekbar.setCutMode(isCutMode, isDrawProgressLine);
60 | // 视频关键帧间隔(毫秒,表示左右两个模块最低限度滑动时间,无法选择低于该关键帧的裁剪时间)
61 | float videoFrame = 60 * 1000f;
62 | // 设置本地视频路径 - 默认裁剪模式,则不绘制播放背景
63 | am_video_seekbar.setVideoUri(true, PLAY_URL, videoFrame);
64 | // // 不设置关键帧时间,则默认最多是两个ImageView左右多出的宽度
65 | // am_video_seekbar.setVideoUri(isCutMode, videoUri);
66 | }
67 | ```
--------------------------------------------------------------------------------
/PlaySeekbar/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.0"
6 | defaultConfig {
7 | applicationId "com.play.pro"
8 | minSdkVersion 19
9 | targetSdkVersion 23
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25 | exclude group: 'com.android.support', module: 'support-annotations'
26 | })
27 | compile 'com.android.support:appcompat-v7:23.0.0'
28 | compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
29 | }
30 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in F:\Development\AndroidStudio\SDK\android_sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
17 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/java/com/play/pro/BaseApplication.java:
--------------------------------------------------------------------------------
1 | package com.play.pro;
2 |
3 | import com.nostra13.universalimageloader.core.DisplayImageOptions;
4 | import com.nostra13.universalimageloader.core.ImageLoader;
5 | import com.nostra13.universalimageloader.core.ImageLoaderConfiguration;
6 | import com.nostra13.universalimageloader.core.assist.ImageScaleType;
7 | import com.nostra13.universalimageloader.core.assist.QueueProcessingType;
8 | import com.nostra13.universalimageloader.core.download.BaseImageDownloader;
9 |
10 | import android.app.Application;
11 | import android.content.Context;
12 | import android.graphics.Bitmap.Config;
13 |
14 | /**
15 | * 整个项目全局对象
16 | */
17 | public class BaseApplication extends Application {
18 |
19 | /** 全局上下文 */
20 | protected Context mContext;
21 |
22 | @Override
23 | public void onCreate() {
24 | super.onCreate();
25 | // 初始化全局上下文
26 | mContext = getApplicationContext();
27 | // 初始化ImageLoader
28 | initImageLoader();
29 | }
30 |
31 | @Override
32 | public void onLowMemory() {
33 | super.onLowMemory();
34 | }
35 |
36 | // =============================
37 |
38 | public void initImageLoader() {
39 | // 图片缓存
40 | DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
41 | //.showImageOnLoading(R.drawable.bg_df_loader) // 设置图片在下载期间显示的图片
42 | ////.showStubImage(R.drawable.loading_image_hint) // 设置图片在下载期间显示的图片
43 | //.showImageForEmptyUri(R.drawable.bg_df_loader) // 设置图片Uri为空或是错误的时候显示的图片
44 | //.showImageOnFail(R.drawable.bg_df_loader) // 设置图片加载/解码过程中错误时候显示的图片
45 | .imageScaleType(ImageScaleType.EXACTLY) // 设置图片缩放
46 | .bitmapConfig(Config.RGB_565) // 图片解码类型
47 | .cacheInMemory(true)// 是否保存到内存
48 | .cacheOnDisk(true).build();// 是否保存到sd卡上(硬盘控件)
49 |
50 | // 针对图片缓存的全局配置,主要有线程类、缓存大小、磁盘大小、图片下载与解析、日志方面的配置。
51 | ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(mContext)
52 | .defaultDisplayImageOptions(defaultOptions) // 加载DisplayImageOptions参数
53 | .threadPriority(Thread.NORM_PRIORITY - 2) // 线程池内加载的数量
54 | .denyCacheImageMultipleSizesInMemory()
55 | //.memoryCache(new UsingFreqLimitedMemoryCache(1024 * 1024)) // 通过自己的内存缓存实现
56 | .memoryCacheSize(2 * 1024 * 1024) // 内存缓存最大值
57 | .memoryCacheSizePercentage(13)
58 | //.diskCacheSize(50 * 1024 * 1024) // SD卡缓存最大值 50mb
59 | //.discCacheFileNameGenerator(new Md5FileNameGenerator()) // 将保存的时候的URI名称用MD5 加密
60 | //.diskCacheFileCount(100) // 缓存的文件数量
61 | //.memoryCache(new WeakMemoryCache()).diskCacheFileNameGenerator(new HashCodeFileNameGenerator())
62 | .imageDownloader(new BaseImageDownloader(mContext)) // default
63 | .tasksProcessingOrder(QueueProcessingType.LIFO).build();
64 | ImageLoader.getInstance().init(config);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/java/com/play/pro/constants/FinalConstants.java:
--------------------------------------------------------------------------------
1 | package com.play.pro.constants;
2 |
3 | /**
4 | * 常量配置
5 | */
6 | public class FinalConstants {
7 |
8 | /** 基数 */
9 | public static final int FINAL_BASE = 1000;
10 | // --
11 | /** 返回 */
12 | public static final int BACK = FINAL_BASE + 1;
13 | /** 全屏 */
14 | public static final int FULL_SCREEN = FINAL_BASE + 2;
15 | /** 播放 */
16 | public static final int PLAY_START = FINAL_BASE + 3;
17 | /** 恢复播放 */
18 | public static final int PLAY_RESTART = FINAL_BASE + 4;
19 | /** 暂停播放 */
20 | public static final int PLAY_PAUSE = FINAL_BASE + 5;
21 | /** 播放结束 */
22 | public static final int PLAY_COMPLE = FINAL_BASE + 6;
23 | /** 播放时间定时器触发 */
24 | public static final int PLAY_TIME = FINAL_BASE + 7;
25 | /** 倒计时定时器触发 */
26 | public static final int COUNT_DOWN = FINAL_BASE + 8;
27 | /** 重新加载 */
28 | public static final int RELOAD = FINAL_BASE + 9;
29 | /** 播放异常 */
30 | public static final int PLAY_ERROR = FINAL_BASE + 10;
31 | /** 播放时间改变触发 */
32 | public static final int PLAY_TIME_CHANGE = FINAL_BASE + 11;
33 |
34 | /** 封面地址 */
35 | public static final String COVER_URL = "coverUrl";
36 | /** 视频地址 */
37 | public static final String VIDEO_URL = "videoUrl";
38 | /** 是否播放结束 */
39 | public static final String IS_PLAY_FINISH = "isPlayFinish";
40 | /** 是否点击Home键 */
41 | public static final String IS_CLICK_HOME = "isClickHome";
42 | }
43 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/java/com/play/pro/utils/TimerUtils.java:
--------------------------------------------------------------------------------
1 | package com.play.pro.utils;
2 |
3 | import java.util.Timer;
4 | import java.util.TimerTask;
5 |
6 | import android.os.Handler;
7 |
8 | /**
9 | * 定时器工具类
10 | */
11 | public class TimerUtils {
12 |
13 | /** 定时器 */
14 | private Timer timer;
15 | /** 定时器任务栈 */
16 | private TimerTask timerTask;
17 | /** 通知Handler */
18 | private Handler handler;
19 | /** 通知类型 */
20 | private int notifyWhat;
21 | // --
22 | /** 延迟时间 - 多少毫秒后开始执行 */
23 | private long delay;
24 | /** 循环时间 - 每隔多少秒执行一次 */
25 | private long period;
26 | /** 触发次数上限 */
27 | private int triggerLimit = 1;
28 | /** 触发次数 */
29 | private int triggerNumber = 0;
30 |
31 | public TimerUtils() {
32 | super();
33 | }
34 |
35 | public TimerUtils(Handler handler) {
36 | super();
37 | this.handler = handler;
38 | }
39 |
40 |
41 | /**
42 | * 定时器操作
43 | * @param isOpen 是否打开
44 | */
45 | private void timerOperate(boolean isOpen){
46 | if (isOpen) {
47 | // 每次重置触发次数
48 | triggerNumber = 0;
49 | try {
50 | if (timer != null) {
51 | timer.cancel();
52 | timer = null;
53 | }
54 | if (timerTask != null) {
55 | timerTask.cancel();
56 | timerTask = null;
57 | }
58 | } catch (Exception e) {
59 | }
60 | // 开启定时器
61 | timer = new Timer(); // 每次重新new 防止被取消
62 | // 重新生成定时器 防止出现TimerTask is scheduled already 所以同一个定时器任务只能被放置一次
63 | timerTask = new TimerTask() {
64 | @Override
65 | public void run() {
66 | // 先进行通知
67 | if(handler != null){
68 | handler.sendEmptyMessage(notifyWhat);
69 | }
70 | // 累积触发次数
71 | triggerNumber++;
72 | // 如果大于触发次数,则关闭
73 | if(triggerNumber >= triggerLimit && triggerLimit >= 0){
74 | // 进行关闭
75 | timerOperate(false);
76 | }
77 | }
78 | };
79 | try {
80 | // xx毫秒后执行,每隔xx毫秒再执行一次
81 | timer.schedule(timerTask, delay, period);
82 | } catch (Exception e) {
83 | }
84 | } else {
85 | try {
86 | if (timer != null) {
87 | timer.cancel();
88 | timer = null;
89 | }
90 | if (timerTask != null) {
91 | timerTask.cancel();
92 | timerTask = null;
93 | }
94 | } catch (Exception e) {
95 | }
96 | }
97 | }
98 |
99 |
100 | // ================ 对外公开方法 =====================
101 | /**
102 | * 设置通知的Handler
103 | * @param handler
104 | */
105 | public void setHandler(Handler handler) {
106 | this.handler = handler;
107 | }
108 |
109 | /**
110 | * 设置通知的What
111 | * @param notifyWhat
112 | */
113 | public void setNotifyWhat(int notifyWhat) {
114 | this.notifyWhat = notifyWhat;
115 | }
116 |
117 | /**
118 | * 设置时间
119 | * @param delay 延迟时间 - 多少毫秒后开始执行
120 | * @param period 循环时间 - 每隔多少秒执行一次
121 | */
122 | public void setTime(long delay, long period) {
123 | this.delay = delay;
124 | this.period = period;
125 | }
126 |
127 | /**
128 | * 设置触发次数上限
129 | * @param triggerLimit
130 | */
131 | public void setTriggerLimit(int triggerLimit) {
132 | this.triggerLimit = triggerLimit;
133 | }
134 |
135 |
136 | // ========================
137 |
138 | /** 开始定时 */
139 | public void startTimer(){
140 | timerOperate(true);
141 | }
142 |
143 | /** 关闭定时 */
144 | public void closeTimer(){
145 | timerOperate(false);
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/java/com/play/pro/utils/ToastUtils.java:
--------------------------------------------------------------------------------
1 | package com.play.pro.utils;
2 |
3 | import android.content.Context;
4 | import android.widget.Toast;
5 |
6 | /**
7 | * 自定义Toast工具类,防止用户快速操作导致Dialog多次显示
8 | */
9 | public class ToastUtils {
10 |
11 | /** 系统默认延时 */
12 | private static Toast mToast;
13 |
14 | public static void showToast(Context mContext, String text, int duration) {
15 | if (mToast != null) {
16 | mToast.setText(text);
17 | mToast.setDuration(duration);
18 | } else {
19 | mToast = Toast.makeText(mContext, text, duration);
20 | }
21 | mToast.show();
22 | }
23 |
24 | public static void showToast(Context mContext, String text) {
25 | showToast(mContext, text, Toast.LENGTH_SHORT);
26 | }
27 |
28 | public static void showToast(Context mContext, int resId) {
29 | showToast(mContext, mContext.getResources().getString(resId), Toast.LENGTH_SHORT);
30 | }
31 |
32 | public static void showToast(Context mContext, int resId, Object... obj) {
33 | showToast(mContext, mContext.getResources().getString(resId, obj), Toast.LENGTH_SHORT);
34 | }
35 |
36 | public static void showToast(Context mContext, int resId, int duration) {
37 | showToast(mContext, mContext.getResources().getString(resId), duration);
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/drawable/ic_back_wy_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/drawable/seekbar_media_paly.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | -
6 |
7 |
8 |
9 |
10 |
11 |
12 | -
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | -
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/layout/activity_full_screen.xml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
14 |
15 |
19 |
20 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
12 |
13 |
17 |
18 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_back_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_back_white.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_back_yellow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_back_yellow.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_loading_point_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_loading_point_grey.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_loading_point_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_loading_point_white.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_logo.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_media_fullscreen_shrink_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_media_fullscreen_shrink_white.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_media_fullscreen_stretch_white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_media_fullscreen_stretch_white.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_media_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_media_play.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_media_stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_media_stop.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_seekbar_thumb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_seekbar_thumb.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_slider_left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_slider_left.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_slider_right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xhdpi/ic_slider_right.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/values/color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | #FF0000
6 | #000000
7 | #66000000
8 | #00000000
9 | #FFFFFF
10 | #CCFFFFFF
11 | #808080
12 | #a0000000
13 | #0080FF
14 | #0000FF
15 |
16 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | PlaySeekBar
5 |
6 |
--------------------------------------------------------------------------------
/PlaySeekbar/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/PlaySeekbar/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/PlaySeekbar/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/PlaySeekbar/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/PlaySeekbar/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/PlaySeekbar/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/PlaySeekbar/mdFile/img1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/PlaySeekbar/mdFile/img1.gif
--------------------------------------------------------------------------------
/PlaySeekbar/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
Android
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | 🍖 这是一个 Android 相关联功能实现代码合集,
20 |
21 | 主要存储自定义 View 效果、部分功能 ( 实现逻辑、思路 )、Demo 等功能代码。
22 |
23 |
24 |
25 |
26 |
27 | Android 规范
28 | 、
29 |
30 | Java 规范
31 | 、
32 |
33 | Git 规范
34 |
35 |
36 |
37 |
38 | ## 目录结构
39 |
40 | ```
41 | - Android | 根目录
42 | - 360RePlugin | Android 插件化开发 - 360 RePlugin 框架
43 | - AndroidVideoClip | Android 视频裁剪 ( 含裁剪 View )
44 | - BuglyHotfix | Android 热修复 - Bugly
45 | - PlaySeekbar | 视频裁剪自定义 View
46 | - RecordVideo | 录制视频 View ( 拍照 + 视频 )
47 | - RecordView | 录制进步式 View
48 | - SophixPro | Android - 热修复 Sophix
49 | ```
50 |
51 |
52 | ## License
53 |
54 | Copyright 2022 afkT
55 |
56 | Licensed under the Apache License, Version 2.0 (the "License");
57 | you may not use this file except in compliance with the License.
58 | You may obtain a copy of the License at
59 |
60 | http://www.apache.org/licenses/LICENSE-2.0
61 |
62 | Unless required by applicable law or agreed to in writing, software
63 | distributed under the License is distributed on an "AS IS" BASIS,
64 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
65 | See the License for the specific language governing permissions and
66 | limitations under the License.
67 |
68 |
--------------------------------------------------------------------------------
/RecordVideo/README.md:
--------------------------------------------------------------------------------
1 | # [RecordVideo](https://github.com/afkT/Android/tree/master/RecordVideo)
2 |
3 | Android 录制视频 View (拍照 + 视频) 支持前、后置,录制拉近以及横竖屏翻转处理
4 |
5 |
6 | ### 预览
7 |
8 | |  |  |
9 | |:-|:-|
10 |
11 | |  |  |
12 | |:-|:-|
13 |
14 |
15 | ### 具体实现类
16 |
17 | - [MediaRecorderView](https://github.com/afkT/Android/blob/master/RecordVideo/app/src/main/java/com/record/video/widget/MediaRecorderView.java) 主要是显示 Camera 预览画面,以及录制代码、拍照代码,包括横竖屏、屏幕翻转等逻辑代码
18 |
19 | - [MediaDealUtils](https://github.com/afkT/Android/blob/master/RecordVideo/app/src/main/java/com/record/video/utils/MediaDealUtils.java) 是对录制视频后缩略图生成、缩放处理
20 |
21 | - [CameraUtils](https://github.com/afkT/Android/blob/master/RecordVideo/app/src/main/java/com/record/video/utils/CameraUtils.java) 摄像头资源操作
22 |
23 | - [MediaRecordActivity](https://github.com/afkT/Android/blob/master/RecordVideo/app/src/main/java/com/record/video/activitys/MediaRecordActivity.java) 录制、拍照页面,[MediaResultPreActivity](https://github.com/afkT/Android/blob/master/RecordVideo/app/src/main/java/com/record/video/activitys/MediaResultPreActivity.java) 录制、拍照结果预览页面
24 |
25 | ### 注意实现
26 |
27 | 录制视频,如果手机支持 480x640、360x640,则默认使用该分辨率录制,可在 MediaRecorderView 中进行修改判断
28 |
29 | ```java
30 | /**
31 | * 设置配置大小 (不同比例控制不同)
32 | * @param params
33 | */
34 | private void setConfigSize(Camera.Parameters params){
35 | // 计算预览大小
36 | setPreviewSize(params);
37 | // 计算录制大小
38 | setVideoSize(params);
39 | }
40 | ```
41 |
42 | 预览默认使用最符合屏幕分辨率的大小,拍照相同
43 |
44 |
45 | ### 存在的缺陷:
46 |
47 | 该 Demo 使用的是 MediaRecorder 进行录制视频
48 |
49 | 并且该效果要求 点击拍照,长按超过 0.x 秒则实现为录制,而录制视频的时候需要切换 Camera 配置,会导致录制一瞬间导致卡顿
50 |
51 | ```java
52 | // 拍照的时候,不能调用该方法,但是录制视频必须调用该方法,导致需要重新初始化 Camera,并重新配置参数
53 |
54 | initCamera() { // 该方法中
55 | // 导致无法拍照
56 | mCamera.unlock();
57 | }
58 |
59 | // 具体实现代码,看 MediaRecorderView 类处理了翻转对应视频、图片旋转角度摆正,并且支持摄像头手势上下滑动,缩放摄像头
60 | ```
--------------------------------------------------------------------------------
/RecordVideo/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 27
5 | buildToolsVersion "27.0.2"
6 | defaultConfig {
7 | applicationId "com.record.video"
8 | minSdkVersion 19
9 | targetSdkVersion 27
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | buildTypes {
14 | release {
15 | minifyEnabled false
16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
17 | }
18 | }
19 |
20 | sourceSets {
21 | main {
22 | jniLibs.srcDirs = ['libs']
23 | }
24 | }
25 | }
26 |
27 | dependencies {
28 | compile fileTree(dir: 'libs', include: ['*.jar'])
29 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
30 | exclude group: 'com.android.support', module: 'support-annotations'
31 | })
32 | compile 'com.android.support:appcompat-v7:27.0.0'
33 |
34 | compile 'com.jakewharton:butterknife:8.5.1'
35 | compile 'com.jakewharton:butterknife-compiler:8.5.1'
36 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
37 |
38 | compile 'com.github.bumptech.glide:glide:4.3.1'
39 | annotationProcessor 'com.github.bumptech.glide:compiler:4.3.1'
40 | compile "com.github.bumptech.glide:okhttp3-integration:4.3.1"
41 |
42 | // ImagerLoader 图片加载框架
43 | compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
44 | // 日志库
45 | implementation 'com.github.afkT:DevLogger:1.0'
46 | // 权限
47 | compile 'com.anthonycr.grant:permissions:1.0'
48 | }
49 |
--------------------------------------------------------------------------------
/RecordVideo/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in E:\Development\Android\SDK\android_sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Uncomment this to preserve the line number information for
20 | # debugging stack traces.
21 | #-keepattributes SourceFile,LineNumberTable
22 |
23 | # If you keep the line number information, uncomment this to
24 | # hide the original source file name.
25 | #-renamesourcefileattribute SourceFile
26 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
42 |
43 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/bean/MediaInfoBean.java:
--------------------------------------------------------------------------------
1 | package com.record.video.bean;
2 |
3 | import com.record.video.bean.item.MediaItem;
4 |
5 | /**
6 | * detail: 多媒体信息实体类
7 | * Created by Ttt
8 | */
9 | public abstract class MediaInfoBean extends MediaItem {
10 | }
11 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/bean/item/MediaItem.java:
--------------------------------------------------------------------------------
1 | package com.record.video.bean.item;
2 |
3 | import android.text.TextUtils;
4 |
5 | import java.io.File;
6 |
7 | /**
8 | * detail: 多媒体Item, 单独特殊处理
9 | * Created by Ttt
10 | */
11 | public class MediaItem extends AbsMediaInfoItem {
12 |
13 | /** 多媒体类型 */
14 | public enum MediaTypeEnum {
15 |
16 | UNKNOWN(0),
17 |
18 | // 视频
19 | VIDEO(1),
20 |
21 | // 图片
22 | IMAGE(2),
23 |
24 | // 音频
25 | AUDIO(3);
26 |
27 | private int val;
28 |
29 | MediaTypeEnum(int val){
30 | this.val = val;
31 | }
32 |
33 | /**
34 | * 获取值
35 | * @return
36 | */
37 | public int getValue(){
38 | return this.val;
39 | }
40 |
41 | /**
42 | * 获取多媒体类型
43 | * @param val
44 | * @return
45 | */
46 | public static MediaTypeEnum getMediaType(int val){
47 | if (val == 1){
48 | return VIDEO;
49 | } else if (val == 2){
50 | return IMAGE;
51 | } else if (val == 3){
52 | return AUDIO;
53 | }
54 | return UNKNOWN;
55 | }
56 | }
57 |
58 | // ==
59 |
60 | // 多媒体类型
61 | protected MediaTypeEnum mediaTypeEnum;
62 |
63 | /**
64 | * 获取多媒体类型
65 | * @return
66 | */
67 | public MediaTypeEnum getMediaTypeEnum() {
68 | return mediaTypeEnum;
69 | }
70 |
71 | // ==
72 |
73 | /**
74 | * 判断是否网络资源
75 | * @return
76 | */
77 | public boolean isHttpRes(){
78 | return isHttpRes(getMediaUri());
79 | }
80 |
81 | /**
82 | * 判断是否网络资源
83 | * @param uri
84 | * @return
85 | */
86 | public static boolean isHttpRes(String uri){
87 | if (!TextUtils.isEmpty(uri)){
88 | // 属于第一位开始, 才是属于网络视频
89 | if (uri.toLowerCase().startsWith("http")){
90 | return true;
91 | }
92 | }
93 | return false;
94 | }
95 |
96 | // ==
97 |
98 | /**
99 | * 判断是否本地资源
100 | * @return
101 | */
102 | public boolean isLocalRes(){
103 | return isLocalRes(getMediaUri());
104 | }
105 |
106 | /**
107 | * 判断是否本地资源
108 | * @param uri
109 | * @return
110 | */
111 | public static boolean isLocalRes(String uri){
112 | if (!TextUtils.isEmpty(uri)){
113 | return new File(uri).exists();
114 | }
115 | return false;
116 | }
117 |
118 |
119 | }
120 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/bean/item/media/ImageInfoItem.java:
--------------------------------------------------------------------------------
1 | package com.record.video.bean.item.media;
2 |
3 | import android.graphics.Bitmap;
4 | import android.graphics.BitmapFactory;
5 |
6 | import com.record.video.bean.MediaInfoBean;
7 |
8 | /**
9 | * detail: 图片信息实体类, 特殊处理
10 | * Created by Ttt
11 | */
12 | public class ImageInfoItem extends MediaInfoBean {
13 |
14 | /**
15 | * 生成图片信息数据模型类
16 | * @param mediaUri
17 | * @param isPortrait
18 | * @param isFrontCamera
19 | * @param cameraRotate
20 | * @return
21 | */
22 | public static ImageInfoItem build(String mediaUri, boolean isPortrait, boolean isFrontCamera, int cameraRotate){
23 | ImageInfoItem imageInfoItem = new ImageInfoItem();
24 | // ==
25 | imageInfoItem.mediaTypeEnum = MediaTypeEnum.IMAGE;
26 | imageInfoItem.setMediaUri(mediaUri);
27 | imageInfoItem.setPortrait(isPortrait);
28 | imageInfoItem.setFrontCamera(isFrontCamera);
29 | imageInfoItem.setCameraRotate(cameraRotate);
30 | // 获取图片宽度高度
31 | int[] whArys = getImageWidthHeight(mediaUri);
32 | // 设置宽高
33 | imageInfoItem.setMediaWidth(whArys[0]);
34 | imageInfoItem.setMediaHeight(whArys[1]);
35 | return imageInfoItem;
36 | }
37 |
38 | @Override
39 | public String toString() {
40 | // 进行拼接
41 | StringBuffer stringBuffer = new StringBuffer();
42 | stringBuffer.append("\n文件名字:");
43 | stringBuffer.append(getMediaName());
44 | stringBuffer.append("\n文件类型");
45 | stringBuffer.append(getMediaSuffix());
46 | stringBuffer.append("\n文件处理MD5");
47 | stringBuffer.append(getMediaMD5());
48 | stringBuffer.append("\n文件信息");
49 | stringBuffer.append("宽(" + getMediaWidth() + "), 高(" + getMediaHeight() + "), 文件大小(" + getMediaSize() + ")");
50 | stringBuffer.append("\n文件地址");
51 | stringBuffer.append(getMediaUri());
52 | // 返回字符串
53 | return stringBuffer.toString();
54 | }
55 |
56 | /**
57 | * 获取图片宽度高度
58 | * @param path
59 | * @return
60 | */
61 | public static int[] getImageWidthHeight(String path){
62 | BitmapFactory.Options options = new BitmapFactory.Options();
63 | // 不解析图片信息
64 | options.inJustDecodeBounds = true;
65 | // 此时返回的bitmap为null
66 | Bitmap bitmap = BitmapFactory.decodeFile(path, options);
67 | // options.outHeight为原始图片的高
68 | return new int[]{options.outWidth,options.outHeight};
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/bean/item/media/VideoInfoItem.java:
--------------------------------------------------------------------------------
1 | package com.record.video.bean.item.media;
2 |
3 | import com.record.video.bean.MediaInfoBean;
4 |
5 | /**
6 | * detail: 视频信息实体类, 特殊处理
7 | * Created by Ttt
8 | */
9 | public class VideoInfoItem extends MediaInfoBean {
10 |
11 | /**
12 | * 生成视频信息数据模型类
13 | * @param mediaUri
14 | * @param isPortrait
15 | * @param isFrontCamera
16 | * @param cameraRotate
17 | * @return
18 | */
19 | public static VideoInfoItem build(String mediaUri, boolean isPortrait, boolean isFrontCamera, int cameraRotate){
20 | VideoInfoItem videoInfoItem = new VideoInfoItem();
21 | // ==
22 | videoInfoItem.mediaTypeEnum = MediaTypeEnum.VIDEO;
23 | videoInfoItem.setMediaUri(mediaUri);
24 | videoInfoItem.setPortrait(isPortrait);
25 | videoInfoItem.setFrontCamera(isFrontCamera);
26 | videoInfoItem.setCameraRotate(cameraRotate);
27 | return videoInfoItem;
28 | }
29 |
30 | @Override
31 | public String toString() {
32 | // 进行拼接
33 | StringBuffer stringBuffer = new StringBuffer();
34 | stringBuffer.append("\n文件名字:");
35 | stringBuffer.append(getMediaName());
36 | stringBuffer.append("\n文件类型");
37 | stringBuffer.append(getMediaSuffix());
38 | stringBuffer.append("\n文件处理MD5");
39 | stringBuffer.append(getMediaMD5());
40 | stringBuffer.append("\n文件信息");
41 | stringBuffer.append("宽(" + getMediaWidth() + "), 高(" + getMediaHeight() + "), 时长(" + getMediaTime() + "), 文件大小(" + getMediaSize() + ")");
42 | stringBuffer.append("\n文件地址");
43 | stringBuffer.append(getMediaUri());
44 | // 返回字符串
45 | return stringBuffer.toString();
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/config/able/ResultCallback.java:
--------------------------------------------------------------------------------
1 | package com.record.video.config.able;
2 |
3 | import java.lang.reflect.ParameterizedType;
4 |
5 | /**
6 | * detail: 通用结果回调类
7 | * Created by Ttt
8 | */
9 | public abstract class ResultCallback {
10 |
11 | Class clas;
12 |
13 | /**
14 | * 初始化构造函数,则进行获取泛型Class类
15 | */
16 | protected ResultCallback() {
17 | try {
18 | clas = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
19 | } catch (Exception e){
20 | }
21 | }
22 |
23 | /**
24 | * 获取泛型类Class类型
25 | * @return
26 | */
27 | public final Class getTClass() {
28 | return clas;
29 | }
30 |
31 | // ========== 请求回调 ==========
32 |
33 | /**
34 | * 请求结果回调
35 | * @param t
36 | */
37 | public abstract void onResult(T t);
38 |
39 | /**
40 | * 请求异常回调
41 | * @param e
42 | */
43 | public void onError(Exception e){
44 | }
45 |
46 | /**
47 | * 请求失败回调
48 | * @param errorCode
49 | */
50 | public void onFailure(int errorCode){
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/config/constants/KeyConstants.java:
--------------------------------------------------------------------------------
1 | package com.record.video.config.constants;
2 |
3 | /**
4 | * detail: Key 常量
5 | * Created by Ttt
6 | */
7 | public class KeyConstants {
8 |
9 | // ======== 常量 ========
10 |
11 | /** 多媒体文件地址 */
12 | public static final String EXTRA_MEDIA_URI = "mediaUri";
13 | /** 多媒体类型 */
14 | public static final String EXTRA_MEDIA_TYPE = "mediaType";
15 | /** 视频是否竖屏 */
16 | public static final String EXTRA_VIDEO_ISPORTRAIT = "isPortrait";
17 | /** 视频是否前置摄像头拍摄 */
18 | public static final String EXTRA_VIDEO_ISFRONTCAMERA = "isFrontCamera";
19 | /** 拍摄旋转角度 */
20 | public static final String EXTRA_MEDIA_ROTATE = "mediaRotate";
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/config/constants/NotifyConstants.java:
--------------------------------------------------------------------------------
1 | package com.record.video.config.constants;
2 |
3 | /**
4 | * detail: 通知相关常量
5 | * Created by Ttt
6 | */
7 | public class NotifyConstants {
8 |
9 | // ==================================
10 | // ============ 通知常量 ============
11 | // ==================================
12 |
13 | /** 通知常量 基数 */
14 | private static final int BASE_NOTIFY = 10000;
15 | /** 检查权限 */
16 | public static final int NOTIFY_CHECK_PERMISSION = BASE_NOTIFY + 1;
17 | /** 录制结束 */
18 | public static final int NOTIFY_RECORD_END = BASE_NOTIFY + 2;
19 | /** 开始录制 */
20 | public static final int NOTIFY_RECORD_START = BASE_NOTIFY + 3;
21 | /** 录制计时 */
22 | public static final int NOTIFY_RECORD_TIMING = BASE_NOTIFY + 4;
23 | /** 录制检测 */
24 | public static final int NOTIFY_RECORD_CHECK = BASE_NOTIFY + 5;
25 | /** 录制操作回调 */
26 | public static final int NOTIFY_RECORD_OPERATE = BASE_NOTIFY + 6;
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/config/constants/ProConstants.java:
--------------------------------------------------------------------------------
1 | package com.record.video.config.constants;
2 |
3 | import java.io.File;
4 |
5 | /**
6 | * detail: 项目常量类
7 | * Created by Ttt
8 | */
9 | public class ProConstants {
10 |
11 | // ============== 录制项目 ===============
12 | /** 项目名 */
13 | public static final String BASE_NAME = "RecordVideo";
14 |
15 | // ---------------------- 本地应用数据 -------------------------
16 |
17 | /** 数据缓存 cache*/
18 | public static final String BASE_APPLICATION_CACHE_PATH = File.separator + BASE_NAME + "Data" + File.separator;
19 |
20 | /** 视频录制保存地址 */
21 | public static final String AP_VIDEO_RECORD_PATH = BASE_APPLICATION_CACHE_PATH + "Video" + File.separator;
22 |
23 | /** 视频录制保存地址 */
24 | public static final String AP_VIDEO_RECORD_COVER_PATH = AP_VIDEO_RECORD_PATH + "vCover" + File.separator;
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/utils/RotateTransformation.java:
--------------------------------------------------------------------------------
1 | package com.record.video.utils;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.Matrix;
6 |
7 | import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
8 | import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
9 |
10 | import java.security.MessageDigest;
11 |
12 | /**
13 | * detail: 图片旋转
14 | * Created by Ttt
15 | */
16 | public class RotateTransformation extends BitmapTransformation {
17 |
18 | // 获取拍摄角度
19 | int cameraRotate;
20 | // 判断是否竖屏
21 | boolean isPortrait;
22 | // 是否前置摄像头
23 | boolean isFrontCamera;
24 |
25 | public RotateTransformation(Context context, int cameraRotate, boolean isPortrait, boolean isFrontCamera) {
26 | super(context);
27 | this.cameraRotate = cameraRotate;
28 | this.isPortrait = isPortrait;
29 | this.isFrontCamera = isFrontCamera;
30 | }
31 |
32 | @Override
33 | protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
34 | // 进行图片旋转
35 | Matrix matrix = new Matrix();
36 | // 判断是否需要
37 | if (isFrontCamera && isPortrait){
38 | matrix.preRotate(Math.abs(360 - cameraRotate));
39 | } else {
40 | matrix.preRotate(cameraRotate);
41 | }
42 | // 旋转处理图片
43 | return Bitmap.createBitmap(toTransform, 0, 0, toTransform.getWidth(), toTransform.getHeight(), matrix, true);
44 | }
45 |
46 | @Override
47 | public void updateDiskCacheKey(MessageDigest messageDigest) {
48 |
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/utils/TimerUtils.java:
--------------------------------------------------------------------------------
1 | package com.record.video.utils;
2 |
3 | import android.os.Handler;
4 |
5 | import java.util.Timer;
6 | import java.util.TimerTask;
7 |
8 | /**
9 | * detail: 定时器工具类 (简化版定时器)
10 | * Created by Ttt
11 | */
12 | public class TimerUtils {
13 |
14 | /** 定时器 */
15 | private Timer timer;
16 | /** 定时器任务栈 */
17 | private TimerTask timerTask;
18 | /** 通知Handler */
19 | private Handler handler;
20 | /** 通知类型 */
21 | private int notifyWhat;
22 | // --
23 | /** 延迟时间 - 多少毫秒后开始执行 */
24 | private long delay;
25 | /** 循环时间 - 每隔多少秒执行一次 */
26 | private long period;
27 | /** 触发次数上限 */
28 | private int triggerLimit = 1;
29 | /** 触发次数 */
30 | private int triggerNumber = 0;
31 | /** 定时器是否运行中 */
32 | private boolean isRunTimer = false;
33 |
34 | public TimerUtils() {
35 | super();
36 | }
37 |
38 | /**
39 | * 定时器操作
40 | * @param isOpen 是否打开
41 | */
42 | private void timerOperate(boolean isOpen){
43 | if (isOpen) {
44 | // 表示运行定时器中
45 | isRunTimer = true;
46 | // 每次重置触发次数
47 | triggerNumber = 0;
48 | try {
49 | if (timer != null) {
50 | timer.cancel();
51 | timer = null;
52 | }
53 | if (timerTask != null) {
54 | timerTask.cancel();
55 | timerTask = null;
56 | }
57 | } catch (Exception e) {
58 | }
59 | // 开启定时器
60 | timer = new Timer(); // 每次重新new 防止被取消
61 | // 重新生成定时器 防止出现TimerTask is scheduled already 所以同一个定时器任务只能被放置一次
62 | timerTask = new TimerTask() {
63 | @Override
64 | public void run() {
65 | // 表示运行定时器中
66 | isRunTimer = true;
67 | // 先进行通知
68 | if(handler != null){
69 | handler.sendEmptyMessage(notifyWhat);
70 | }
71 | // 累积触发次数
72 | triggerNumber++;
73 | // 如果大于触发次数,则关闭
74 | if(triggerNumber >= triggerLimit && triggerLimit >= 0){
75 | // 进行关闭
76 | timerOperate(false);
77 | }
78 | }
79 | };
80 | try {
81 | // xx毫秒后执行,每隔xx毫秒再执行一次
82 | timer.schedule(timerTask, delay, period);
83 | } catch (Exception e) {
84 | // 表示非运行定时器中
85 | isRunTimer = false;
86 | }
87 | } else {
88 | // 表示非运行定时器中
89 | isRunTimer = false;
90 | try {
91 | if (timer != null) {
92 | timer.cancel();
93 | timer = null;
94 | }
95 | if (timerTask != null) {
96 | timerTask.cancel();
97 | timerTask = null;
98 | }
99 | } catch (Exception e) {
100 | }
101 | }
102 | }
103 |
104 |
105 | // ================ 对外公开方法 =====================
106 | /**
107 | * 设置通知的Handler
108 | * @param handler
109 | */
110 | public TimerUtils setHandler(Handler handler) {
111 | this.handler = handler;
112 | return this;
113 | }
114 |
115 | /**
116 | * 设置通知的What
117 | * @param notifyWhat
118 | */
119 | public TimerUtils setNotifyWhat(int notifyWhat) {
120 | this.notifyWhat = notifyWhat;
121 | return this;
122 | }
123 |
124 | /**
125 | * 设置时间
126 | * @param delay 延迟时间 - 多少毫秒后开始执行
127 | * @param period 循环时间 - 每隔多少秒执行一次
128 | */
129 | public TimerUtils setTime(long delay, long period) {
130 | this.delay = delay;
131 | this.period = period;
132 | return this;
133 | }
134 |
135 | /**
136 | * 设置触发次数上限
137 | * @param triggerLimit
138 | */
139 | public TimerUtils setTriggerLimit(int triggerLimit) {
140 | this.triggerLimit = triggerLimit;
141 | return this;
142 | }
143 |
144 | // ========================
145 |
146 | /** 开始定时 */
147 | public void startTimer(){
148 | timerOperate(true);
149 | }
150 |
151 | /** 关闭定时 */
152 | public void closeTimer(){
153 | timerOperate(false);
154 | }
155 |
156 | /** 获取是否运行定时器中 */
157 | public boolean isRunTimer() {
158 | return isRunTimer;
159 | }
160 |
161 | /** 获取触发次数 */
162 | public int getTriggerNumber() {
163 | return triggerNumber;
164 | }
165 | }
166 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/widget/RecordLoadDialog.java:
--------------------------------------------------------------------------------
1 | package com.record.video.widget;
2 |
3 | import android.app.Dialog;
4 | import android.content.Context;
5 | import android.view.Gravity;
6 | import android.view.Window;
7 | import android.view.WindowManager;
8 | import android.view.animation.AnimationUtils;
9 | import android.widget.ImageView;
10 |
11 | import com.record.video.R;
12 | import com.record.video.utils.DevUtils;
13 |
14 | import butterknife.BindView;
15 | import butterknife.ButterKnife;
16 |
17 | /**
18 | * detail: 录制加载 Dialog
19 | * Created by Ttt
20 | */
21 | public class RecordLoadDialog extends Dialog{
22 |
23 | // 上下文
24 | Context mContext;
25 | @BindView(R.id.drl_load_igview)
26 | ImageView drl_load_igview;
27 |
28 | public RecordLoadDialog(Context mContext) {
29 | super(mContext, R.style.Theme_Light_FullScreenDialogOperate);
30 | // 解决小米出现 X给截取一半(状态栏遮盖的问题)
31 | getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
32 | // 绑定Layout
33 | this.setContentView(R.layout.dialog_record_load);
34 | this.mContext = mContext;
35 | // --
36 | // 初始化View
37 | ButterKnife.bind(this);
38 | // ==------------------------------------------==
39 | // 设置宽度,高度以及显示的位置
40 | Window window = this.getWindow();
41 | WindowManager.LayoutParams lParams = window.getAttributes();
42 | try {
43 | // 设置透明度
44 | //lParams.dimAmount = 0.0f;
45 | // 获取屏幕宽度高度
46 | int[] screen = DevUtils.getScreenWidthHeight(mContext);
47 | lParams.width = screen[0];
48 | lParams.height = screen[1];
49 | //lParams.x = 0;
50 | // lParams.y = (screen[1] - ScreenUtils.getStatusHeight(mContext)) / 2;
51 | lParams.gravity = Gravity.CENTER;
52 | window.setAttributes(lParams);
53 | } catch (Exception e) {
54 | }
55 | // 禁止返回键关闭
56 | this.setCancelable(false);
57 | // 禁止点击其他地方自动关闭
58 | this.setCanceledOnTouchOutside(false);
59 | }
60 |
61 | // ==
62 |
63 | /** 关闭Dialog */
64 | public void cancelDialog() {
65 | if (this.isShowing()) {
66 | this.cancel();
67 | }
68 | }
69 |
70 | /** 显示Dialog */
71 | public void showDialog(){
72 | // 加载动画
73 | drl_load_igview.startAnimation(AnimationUtils.loadAnimation(mContext, R.anim.anim_record_loading));
74 | // --
75 | this.show();
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/java/com/record/video/widget/RecordProgressBar.java:
--------------------------------------------------------------------------------
1 | package com.record.video.widget;
2 |
3 | import android.content.Context;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.graphics.Canvas;
7 | import android.graphics.Color;
8 | import android.graphics.Paint;
9 | import android.graphics.RectF;
10 | import android.util.AttributeSet;
11 | import android.view.View;
12 |
13 | import com.record.video.R;
14 |
15 | /**
16 | * detail: 录制进度
17 | * Created by Ttt
18 | */
19 | public class RecordProgressBar extends View {
20 |
21 | /** 画笔 */
22 | private Paint paint;
23 | /** 圆环的宽度 */
24 | private float rWidth;
25 | /** 圆环进度颜色 */
26 | private int rProgressColor;
27 | // == 背景图片 ==
28 | /** 图片 */
29 | private Bitmap bBitmap;
30 | /** 图片宽度 */
31 | private int bWidth = 0;
32 | /** 图片高度 */
33 | private int bHeight = 0;
34 | // ==
35 | /** 最大进度 */
36 | private int max = 100;
37 | /** 当前进度 */
38 | private int progress;
39 |
40 | public RecordProgressBar(Context context) {
41 | this(context, null);
42 | }
43 |
44 | public RecordProgressBar(Context context, AttributeSet attrs) {
45 | this(context, attrs, 0);
46 | }
47 |
48 | public RecordProgressBar(Context context, AttributeSet attrs, int defStyle) {
49 | super(context, attrs, defStyle);
50 | // 获取进度图片
51 | bBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.photograph_transcribe);
52 | // 图片宽高
53 | bWidth = bBitmap.getWidth();
54 | bHeight = bBitmap.getHeight();
55 | // 初始化画笔
56 | paint = new Paint();
57 | // 设置默认值
58 | rProgressColor = Color.parseColor("#92B927");
59 | rWidth = getResources().getDimension(R.dimen.x10);
60 | }
61 |
62 |
63 | /** 计算高度 */
64 | @Override
65 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
66 | super.onMeasure(MeasureSpec.makeMeasureSpec(bWidth, MeasureSpec.getMode(widthMeasureSpec)), MeasureSpec.makeMeasureSpec(bHeight, MeasureSpec.getMode(heightMeasureSpec)));
67 | }
68 |
69 |
70 | @Override
71 | protected void onDraw(Canvas canvas) {
72 | super.onDraw(canvas);
73 | // 绘制背景
74 | canvas.drawBitmap(bBitmap, 0, 0, paint);
75 | // 获取圆心的x坐标
76 | int centre = bWidth / 2;
77 | // 圆环的半径
78 | int radius = (int) (centre - rWidth / 2);
79 | //设置进度是实心还是空心
80 | paint.setStrokeWidth(rWidth); // 设置圆环的宽度
81 | paint.setStyle(Paint.Style.STROKE); // 设置空心
82 | paint.setColor(rProgressColor); // 设置进度的颜色
83 | paint.setAntiAlias(true); // 消除锯齿
84 | RectF oval = new RectF(centre - radius, centre - radius, centre + radius, centre + radius); // 用于定义的圆弧的形状和大小的界限
85 | canvas.drawArc(oval, 270, 360 * progress / max, false, paint); // 根据进度画圆弧
86 | // 0 从右边开始
87 | // 270 从上边开始
88 | }
89 |
90 | // ===========
91 |
92 | public synchronized int getMax() {
93 | return max;
94 | }
95 |
96 | /**
97 | * 设置进度的最大值
98 | * @param max
99 | */
100 | public synchronized void setMax(int max) {
101 | if(max < 0){
102 | throw new IllegalArgumentException("max not less than 0");
103 | }
104 | this.max = max;
105 | }
106 |
107 | /**
108 | * 获取进度.需要同步
109 | * @return
110 | */
111 | public synchronized int getProgress() {
112 | return progress;
113 | }
114 |
115 | /**
116 | * 设置进度,此为线程安全控件,由于考虑多线的问题,需要同步
117 | * 刷新界面调用postInvalidate()能在非UI线程刷新
118 | * @param progress
119 | */
120 | public synchronized void setProgress(int progress) {
121 | if(progress < 0){
122 | throw new IllegalArgumentException("progress not less than 0");
123 | }
124 | if(progress > max){
125 | progress = max;
126 | }
127 | if(progress <= max){
128 | this.progress = progress;
129 | postInvalidate();
130 | }
131 | }
132 |
133 | public int getRProgressColor() {
134 | return rProgressColor;
135 | }
136 |
137 | public void setRProgressColor(int cricleProgressColor) {
138 | this.rProgressColor = cricleProgressColor;
139 | }
140 |
141 | public float getRoundWidth() {
142 | return rWidth;
143 | }
144 |
145 | public void setRoundWidth(float roundWidth) {
146 | this.rWidth = roundWidth;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/anim/anim_record_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/anim/noanim_left_in.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/anim/noanim_left_out.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
8 |
9 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-hdpi/chat_focusing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-hdpi/chat_focusing.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-hdpi/chat_play_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-hdpi/chat_play_big.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-hdpi/chat_play_middle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-hdpi/chat_play_middle.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-hdpi/photograph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-hdpi/photograph.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-hdpi/photograph_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-hdpi/photograph_back.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-hdpi/photograph_confirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-hdpi/photograph_confirm.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-hdpi/photograph_invert_camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-hdpi/photograph_invert_camera.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-hdpi/photograph_return.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-hdpi/photograph_return.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-hdpi/photograph_transcribe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-hdpi/photograph_transcribe.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-xhdpi/chat_focusing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-xhdpi/chat_focusing.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-xhdpi/chat_op_loading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-xhdpi/chat_op_loading.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-xhdpi/chat_play_big.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-xhdpi/chat_play_big.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-xhdpi/chat_play_middle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-xhdpi/chat_play_middle.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-xhdpi/photograph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-xhdpi/photograph.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-xhdpi/photograph_back.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-xhdpi/photograph_back.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-xhdpi/photograph_confirm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-xhdpi/photograph_confirm.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-xhdpi/photograph_invert_camera.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-xhdpi/photograph_invert_camera.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-xhdpi/photograph_return.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-xhdpi/photograph_return.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable-xhdpi/photograph_transcribe.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/drawable-xhdpi/photograph_transcribe.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/drawable/camera_reverse_selector.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/layout/activity_media_record.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
10 |
11 |
19 |
20 |
28 |
29 |
36 |
37 |
38 |
39 |
46 |
47 |
48 |
49 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/layout/activity_media_result_pre.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
17 |
18 |
25 |
26 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/layout/dialog_record_load.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/layout/inflate_media_recorder.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | RecordVideo
3 |
4 |
--------------------------------------------------------------------------------
/RecordVideo/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
17 |
18 |
19 |
25 |
26 |
27 |
41 |
42 |
43 |
44 |
45 |
46 |
59 |
60 |
61 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/RecordVideo/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | repositories {
4 | jcenter()
5 | maven { url 'https://jitpack.io' }
6 | maven {
7 | url 'https://maven.google.com/'
8 | name 'Google'
9 | }
10 | }
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:3.0.0'
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 | allprojects {
18 | repositories {
19 | jcenter()
20 | maven { url "https://jitpack.io" }
21 | maven {
22 | url 'https://maven.google.com/'
23 | name 'Google'
24 | }
25 | }
26 | }
27 | task clean(type: Delete) {
28 | delete rootProject.buildDir
29 | }
--------------------------------------------------------------------------------
/RecordVideo/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/RecordVideo/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/RecordVideo/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Tue Jan 02 09:36:33 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/RecordVideo/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/RecordVideo/local.properties:
--------------------------------------------------------------------------------
1 | ## This file is automatically generated by Android Studio.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 | #
7 | # Location of the SDK. This is only used by Gradle.
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | #Fri Dec 22 20:13:58 CST 2017
11 | sdk.dir=F\:\\Android\\SDK\\android_sdk
12 |
--------------------------------------------------------------------------------
/RecordVideo/mdFile/img1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/mdFile/img1.png
--------------------------------------------------------------------------------
/RecordVideo/mdFile/img2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/mdFile/img2.png
--------------------------------------------------------------------------------
/RecordVideo/mdFile/img3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/mdFile/img3.png
--------------------------------------------------------------------------------
/RecordVideo/mdFile/img4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordVideo/mdFile/img4.png
--------------------------------------------------------------------------------
/RecordVideo/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/RecordView/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/RecordView/README.md:
--------------------------------------------------------------------------------
1 | # [RecordView](https://github.com/afkT/Android/tree/master/RecordView)
2 |
3 | 录制进步式 View
4 |
5 |
6 | ### 功能需求与预览
7 |
8 | - 项目有个直播功能,需要显示进度条类似录制进度 View 具体如下
9 |
10 | 1. 可以控制顶部时间间隔,以及是否绘制,是否预留位置
11 |
12 | 2. 能够重头开始,从指定时间开始、恢复、暂停、停止等
13 |
14 | 
15 |
16 | ### 具体实现类
17 |
18 | - [RecordTimeView.java](https://github.com/afkT/Android/blob/master/RecordView/app/src/main/java/com/pro/record/widgets/RecordTimeView.java)
19 |
20 | ### 使用方法
21 |
22 | ```java
23 | /** 时间进度 View */
24 | private RecordTimeView am_rtview;
25 |
26 | am_rtview.setKeepText(false); // 是否保留绘制文本的位置 - 如果进行属于进行绘制,则无视该参数
27 | am_rtview.setDrawText(true); // 是否绘制文本
28 | am_rtview.setTextSize(14.0f); // 设置文本大小 - 默认 13f
29 |
30 | am_rtview.start(); // 开始
31 | //am_rtview.start(20 * 1000f); // 从指定时间开始
32 | am_rtview.stop();// 停止录制
33 | am_rtview.pause(); // 暂停
34 | am_rtview.recover(); // 恢复
35 | am_rtview.getTime(); // 获取时间,单位毫秒
36 | am_rtview.getTimes(); // 获取时间,单位秒数
37 |
38 | /** 设置时间触发回调 */
39 | am_rtview.setRecordTimeCallBack(new RecordTimeView.RecordTimeCallBack() {
40 | @Override
41 | public void preSecond(float dTime) { // 满一秒触发
42 | }
43 | @Override
44 | public void start(float dTime) { // 开始、恢复时触发
45 | }
46 | });
47 | ```
--------------------------------------------------------------------------------
/RecordView/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.0"
6 | defaultConfig {
7 | applicationId "com.pro.record"
8 | minSdkVersion 19
9 | targetSdkVersion 23
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25 | exclude group: 'com.android.support', module: 'support-annotations'
26 | })
27 | }
28 |
--------------------------------------------------------------------------------
/RecordView/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in F:\Development\AndroidStudio\SDK\android_sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/RecordView/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/RecordView/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
14 |
15 |
16 |
25 |
26 |
30 |
31 |
39 |
40 |
41 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/RecordView/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordView/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/RecordView/app/src/main/res/mipmap-xxhdpi/ic_location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordView/app/src/main/res/mipmap-xxhdpi/ic_location.png
--------------------------------------------------------------------------------
/RecordView/app/src/main/res/mipmap-xxhdpi/ic_play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordView/app/src/main/res/mipmap-xxhdpi/ic_play.png
--------------------------------------------------------------------------------
/RecordView/app/src/main/res/mipmap-xxhdpi/ic_stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordView/app/src/main/res/mipmap-xxhdpi/ic_stop.png
--------------------------------------------------------------------------------
/RecordView/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | #FF0000
6 | #000000
7 | #66000000
8 | #00000000
9 | #FFFFFF
10 | #CCFFFFFF
11 | #808080
12 | #a0000000
13 | #0080FF
14 | #0000FF
15 |
16 |
17 |
--------------------------------------------------------------------------------
/RecordView/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | RecordView
3 |
4 |
--------------------------------------------------------------------------------
/RecordView/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/RecordView/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.0'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/RecordView/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/RecordView/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordView/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/RecordView/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/RecordView/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/RecordView/mdFile/img1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/RecordView/mdFile/img1.gif
--------------------------------------------------------------------------------
/RecordView/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/SophixPro/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/SophixPro/README.md:
--------------------------------------------------------------------------------
1 | # [SophixPro](https://github.com/afkT/Android/tree/master/SophixPro)
2 |
3 | Android - 热修复 Sophix
4 |
5 |
6 | ### Gradle
7 |
8 | ```
9 | allprojects {
10 | repositories {
11 | google()
12 | jcenter()
13 |
14 | // 热修复
15 | maven {
16 | url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
17 | }
18 | }
19 | }
20 |
21 | dependencies {
22 | // 分包
23 | compile 'com.android.support:multidex:1.0.1'
24 | // 阿里移动热修复
25 | compile 'com.aliyun.ams:alicloud-android-hotfix:3.2.3'
26 | }
27 | ```
28 |
29 | ### 快速集成
30 |
31 | - [快速集成](https://help.aliyun.com/document_detail/61082.html?spm=a2c4g.11186623.6.560.7fe65c56uYoJfS)
32 |
33 | ### 方案对比
34 |
35 | 
36 |
37 |
38 | ### 注意事项
39 |
40 | - 每次热修复,是和发布的版本对比,而不是已经第 xx 次后的修复对比
41 |
42 | - 可以比作是,每次都当做新的补丁
43 |
44 | - 所以每次提交,都需要存在之前修复 bug 的代码
--------------------------------------------------------------------------------
/SophixPro/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/SophixPro/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 |
5 | compileSdkVersion 26
6 |
7 | defaultConfig {
8 | applicationId "sophix.pro"
9 | minSdkVersion 19
10 | targetSdkVersion 26
11 | versionCode 1
12 | versionName "1.0"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 |
21 | signingConfigs {
22 |
23 | debug {
24 | storeFile file('../demo.jks')
25 | storePassword "123456"
26 | keyAlias "demo"
27 | keyPassword "123456"
28 | }
29 |
30 | release {
31 | storeFile file('../demo.jks')
32 | storePassword "123456"
33 | keyAlias "demo"
34 | keyPassword "123456"
35 | }
36 | }
37 | }
38 |
39 | dependencies {
40 | implementation fileTree(dir: 'libs', include: ['*.jar'])
41 | implementation 'com.android.support:appcompat-v7:26.1.0'
42 | implementation 'com.android.support.constraint:constraint-layout:1.1.0'
43 | // 分包
44 | compile 'com.android.support:multidex:1.0.1'
45 | // 阿里移动热修复
46 | compile 'com.aliyun.ams:alicloud-android-hotfix:3.2.3'
47 | // gson
48 | compile 'com.google.code.gson:gson:2.8.2'
49 | }
50 |
--------------------------------------------------------------------------------
/SophixPro/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
22 |
--------------------------------------------------------------------------------
/SophixPro/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/SophixPro/app/src/main/java/sophix/pro/MainActivity.java:
--------------------------------------------------------------------------------
1 | package sophix.pro;
2 |
3 | import android.content.Context;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.os.Bundle;
6 | import android.util.Log;
7 | import android.view.View;
8 | import android.widget.TextView;
9 |
10 | import sophix.pro.utils.AppUtils;
11 | import sophix.pro.utils.ToastUtils;
12 |
13 | public class MainActivity extends AppCompatActivity implements View.OnClickListener{
14 |
15 | private static final String TAG = "SophixMain";
16 |
17 | private Context mContext;
18 |
19 | @Override
20 | protected void onCreate(Bundle savedInstanceState) {
21 | super.onCreate(savedInstanceState);
22 | setContentView(R.layout.activity_main);
23 |
24 | mContext = MainActivity.this;
25 | }
26 |
27 | @Override
28 | public void onClick(View v) {
29 | switch (v.getId()){
30 | case R.id.vid_btn:
31 | String text = hotfixToast();
32 | // 显示内容
33 | ((TextView) findViewById(R.id.vid_tv)).setText(text);
34 | // 提示 Toast
35 | ToastUtils.showShort(mContext, text);
36 | break;
37 | }
38 | }
39 |
40 | // 热修复key
41 | private int hotfixNumber = 1;
42 |
43 | /**
44 | * 热修复提示内容
45 | * @return
46 | */
47 | private String hotfixToast(){
48 | StringBuilder stringBuilder = new StringBuilder();
49 | stringBuilder.append("verName: " + AppUtils.getAppVersionName());
50 | stringBuilder.append("\nverCode: " + AppUtils.getAppVersionCode());
51 |
52 | // 第一次热修复
53 | stringBuilder.append(addHotfix1());
54 | // 第二次热修复
55 | stringBuilder.append(addHotfix2());
56 |
57 | // 热修复次数
58 | stringBuilder.append("\n\n\n热修复次数 hotfixNumber: " + hotfixNumber);
59 |
60 | String data = stringBuilder.toString();
61 | Log.d(TAG, data);
62 | return data;
63 | }
64 |
65 | /**
66 | * 添加第一次热修复, 分别打开注释
67 | * @return
68 | */
69 | private String addHotfix1(){
70 | StringBuilder stringBuilder = new StringBuilder();
71 | // =============
72 | // stringBuilder.append("\n\n\n==============");
73 | // stringBuilder.append("\n第一次热修复");
74 | // stringBuilder.append("\n==============");
75 | // stringBuilder.append("\n\n" + new Gson().toJson(new TempInfo()));
76 | // hotfixNumber ++;
77 | // =============
78 | return stringBuilder.toString();
79 | }
80 |
81 | // private class TempInfo {
82 | //
83 | // String uuid;
84 | //
85 | // public TempInfo() {
86 | // uuid = UUID.randomUUID().toString();
87 | // }
88 | // }
89 |
90 | /**
91 | * 添加第二次热修复, 分别打开注释
92 | * @return
93 | */
94 | private String addHotfix2(){
95 | StringBuilder stringBuilder = new StringBuilder();
96 | // =============
97 | // stringBuilder.append("\n\n\n==============");
98 | // stringBuilder.append("\n第二次热修复");
99 | // stringBuilder.append("\n==============");
100 | // stringBuilder.append("\n\n" + new Gson().toJson(new UserInfo("林义", "admin", "123798q", "隆东强")));
101 | // hotfixNumber ++;
102 | // =============
103 | return stringBuilder.toString();
104 | }
105 |
106 | // private class UserInfo {
107 | //
108 | // String userName;
109 | //
110 | // String userAccount;
111 | //
112 | // String userPwd;
113 | //
114 | // String userNickName;
115 | //
116 | // public UserInfo(String userName, String userAccount, String userPwd, String userNickName) {
117 | // this.userName = userName;
118 | // this.userAccount = userAccount;
119 | // this.userPwd = userPwd;
120 | // this.userNickName = userNickName;
121 | // }
122 | // }
123 | }
124 |
--------------------------------------------------------------------------------
/SophixPro/app/src/main/java/sophix/pro/base/BaseApplication.java:
--------------------------------------------------------------------------------
1 | package sophix.pro.base;
2 |
3 | import android.app.Application;
4 | import android.content.Context;
5 | import android.util.Log;
6 |
7 | import com.taobao.sophix.SophixManager;
8 |
9 | /**
10 | * detail: 项目 Application 在 SophixStubApplication 中注解 SophixEntry
11 | * Created by Ttt
12 | */
13 | public class BaseApplication extends Application{
14 |
15 | // 生成补丁
16 | // https://help.aliyun.com/document_detail/53247.html
17 |
18 | public static final String TAG = "BaseApplication";
19 |
20 | private static Context sContext;
21 |
22 | @Override
23 | public void onCreate() {
24 | super.onCreate();
25 | Log.d(TAG, "BaseApplication - onCreate()");
26 |
27 | sContext = getApplicationContext();
28 | // Hotfix拉取不到补丁排查步骤
29 | // https://help.aliyun.com/knowledge_detail/65433.html
30 | // 扫描新的路径 -> 这句必须调用, 不然无法拉取需要修复的补丁
31 | SophixManager.getInstance().queryAndLoadNewPatch();
32 | }
33 |
34 | /**
35 | * 获取全局上下文
36 | * @return
37 | */
38 | public static Context getContext(){
39 | return sContext;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/SophixPro/app/src/main/java/sophix/pro/utils/AppUtils.java:
--------------------------------------------------------------------------------
1 | package sophix.pro.utils;
2 |
3 | import android.content.pm.PackageInfo;
4 | import android.content.pm.PackageManager;
5 |
6 | import sophix.pro.base.BaseApplication;
7 |
8 | /**
9 | * detail: App(Android 工具类)
10 | * Created by Ttt
11 | */
12 | public final class AppUtils {
13 |
14 | private AppUtils() {
15 | }
16 |
17 | /**
18 | * 获取app 包名
19 | * @return
20 | */
21 | public static String getAppPackageName() {
22 | return BaseApplication.getContext().getPackageName();
23 | }
24 |
25 | /**
26 | * 获取app 名
27 | * @return
28 | */
29 | public static String getAppName() {
30 | return getAppName(BaseApplication.getContext().getPackageName());
31 | }
32 |
33 | /**
34 | * 获取app 名
35 | * @param packageName
36 | * @return
37 | */
38 | public static String getAppName(final String packageName) {
39 | if (isSpace(packageName)) return null;
40 | try {
41 | PackageManager pm = BaseApplication.getContext().getPackageManager();
42 | PackageInfo pi = pm.getPackageInfo(packageName, 0);
43 | return pi == null ? null : pi.applicationInfo.loadLabel(pm).toString();
44 | } catch (Exception e) {
45 | e.printStackTrace();
46 | return null;
47 | }
48 | }
49 |
50 | /**
51 | * 获取app版本名 - 对外显示
52 | * @return
53 | */
54 | public static String getAppVersionName() {
55 | return getAppVersionName(BaseApplication.getContext().getPackageName());
56 | }
57 |
58 | /**
59 | * 获取app版本名 - 对外显示
60 | * @param packageName The name of the package.
61 | * @return
62 | */
63 | public static String getAppVersionName(final String packageName) {
64 | if (isSpace(packageName)) return null;
65 | try {
66 | PackageInfo pi = BaseApplication.getContext().getPackageManager().getPackageInfo(packageName, 0);
67 | return pi == null ? null : pi.versionName;
68 | } catch (Exception e) {
69 | e.printStackTrace();
70 | return null;
71 | }
72 | }
73 |
74 | /**
75 | * 获取app版本号 - 内部判断
76 | * @return
77 | */
78 | public static int getAppVersionCode() {
79 | return getAppVersionCode(BaseApplication.getContext().getPackageName());
80 | }
81 |
82 | /**
83 | * 获取app版本号 - 内部判断
84 | * @param packageName The name of the package.
85 | * @return
86 | */
87 | public static int getAppVersionCode(final String packageName) {
88 | if (isSpace(packageName)) return -1;
89 | try {
90 | PackageInfo pi = BaseApplication.getContext().getPackageManager().getPackageInfo(packageName, 0);
91 | return pi == null ? -1 : pi.versionCode;
92 | } catch (Exception e) {
93 | e.printStackTrace();
94 | return -1;
95 | }
96 | }
97 |
98 | /**
99 | * 判断字符串是否为 null 或全为空白字符
100 | * @param str 待校验字符串
101 | * @return
102 | */
103 | private static boolean isSpace(final String str) {
104 | if (str == null) return true;
105 | for (int i = 0, len = str.length(); i < len; ++i) {
106 | if (!Character.isWhitespace(str.charAt(i))) {
107 | return false;
108 | }
109 | }
110 | return true;
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/SophixPro/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
16 |
17 |
22 |
23 |
29 |
30 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/SophixPro/app/src/main/res/mipmap-xxhdpi/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/SophixPro/app/src/main/res/mipmap-xxhdpi/logo.png
--------------------------------------------------------------------------------
/SophixPro/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/SophixPro/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Sophix热修复
3 |
4 |
--------------------------------------------------------------------------------
/SophixPro/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/SophixPro/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 |
5 | repositories {
6 | google()
7 | jcenter()
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.0.0'
11 |
12 |
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | google()
21 | jcenter()
22 |
23 | // 热修复
24 | maven {
25 | url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
26 | }
27 | }
28 | }
29 |
30 | task clean(type: Delete) {
31 | delete rootProject.buildDir
32 | }
33 |
--------------------------------------------------------------------------------
/SophixPro/demo.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/SophixPro/demo.jks
--------------------------------------------------------------------------------
/SophixPro/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/SophixPro/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/SophixPro/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/SophixPro/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Jun 04 19:06:51 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
7 |
--------------------------------------------------------------------------------
/SophixPro/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/SophixPro/mdFile/hint.txt:
--------------------------------------------------------------------------------
1 | 每次热修复, 是和发布的版本对比,而不是已经第xx次后的修复对比
2 |
3 | 可以比作是, 每次都当做新的补丁
--------------------------------------------------------------------------------
/SophixPro/mdFile/img1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/SophixPro/mdFile/img1.png
--------------------------------------------------------------------------------
/SophixPro/mdFile/包.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/afkT/Android/891160774d3c0bb1e38634144facc0ccff27e0c1/SophixPro/mdFile/包.zip
--------------------------------------------------------------------------------
/SophixPro/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------