├── .gitignore
├── .idea
├── .gitignore
├── codeStyles
│ ├── Project.xml
│ └── codeStyleConfig.xml
├── compiler.xml
├── gradle.xml
├── inspectionProfiles
│ └── Project_Default.xml
├── jarRepositories.xml
├── kotlinc.xml
├── misc.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── jks
│ └── basicLibrary
├── proguard-rules.pro
├── release
│ ├── app-release.apk
│ └── output-metadata.json
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── peakmain
│ │ └── basiclibary
│ │ ├── App.kt
│ │ ├── MainActivity.kt
│ │ ├── activity
│ │ └── BehaviorActivity.kt
│ │ ├── adapter
│ │ └── TestAdapter.kt
│ │ ├── fragment
│ │ ├── HomeFragment.kt
│ │ └── MineFragment.kt
│ │ ├── network
│ │ ├── DataResponse.java
│ │ ├── ProjectTree.java
│ │ ├── WanAndroidApi.kt
│ │ └── status
│ │ │ ├── ApiBaseStatus.kt
│ │ │ └── BaseEntityDataRetrofitData.kt
│ │ ├── utils
│ │ ├── AtPermissionUtils.kt
│ │ └── PermissionUtils.kt
│ │ └── viewModel
│ │ ├── HomeFragmentViewModel.kt
│ │ └── MainViewModel.kt
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ ├── ic_bottom_navigation_home.xml
│ ├── ic_bottom_navigation_me.xml
│ ├── ic_launcher_background.xml
│ ├── logo.jpg
│ └── selector_tab_color.xml
│ ├── layout
│ ├── activity_behavior.xml
│ ├── activity_main.xml
│ ├── fragment_home.xml
│ ├── fragment_mine.xml
│ └── recycler_adpter_test.xml
│ ├── menu
│ └── bottom_navigation_main.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-night
│ └── colors.xml
│ └── values
│ ├── colors.xml
│ ├── strings.xml
│ └── styles.xml
├── basicLibrary
├── .gitignore
├── build.gradle
├── consumer-rules.pro
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── peakmain
│ │ └── basiclibrary
│ │ ├── BasicLibraryProvider.kt
│ │ ├── adapter
│ │ ├── CommonRecyclerDataBindingAdapter.kt
│ │ ├── holder
│ │ │ ├── BaseLibraryFooterViewHolder.kt
│ │ │ └── BaseLibraryViewHolder.kt
│ │ └── listener
│ │ │ ├── BaseLibraryOnScrollListener.kt
│ │ │ ├── OnItemClickListener.kt
│ │ │ └── OnLongClickListener.kt
│ │ ├── ainimator
│ │ ├── SimpleAnimationListener.kt
│ │ └── SimpleAnimatorListener.kt
│ │ ├── base
│ │ ├── BaseSingleton.kt
│ │ ├── IApp.kt
│ │ ├── activity
│ │ │ └── BaseActivity.kt
│ │ ├── fragment
│ │ │ └── BaseFragment.kt
│ │ └── viewmodel
│ │ │ └── BaseViewModel.kt
│ │ ├── bean
│ │ └── BasicLibraryBeanKt.kt
│ │ ├── config
│ │ ├── BaseAdapterFooterConfig.kt
│ │ ├── BasicLibraryConfig.kt
│ │ ├── DefaultAdapterFooterConfig.kt
│ │ └── ImageRequestConfig.kt
│ │ ├── constants
│ │ ├── AndroidVersion.kt
│ │ ├── ImageSelectConstants.kt
│ │ ├── PermissionConstants.kt
│ │ └── PermissionMapConstants.kt
│ │ ├── dialog
│ │ ├── CustomCenterDialog.kt
│ │ └── SubmitLoading.kt
│ │ ├── extend
│ │ ├── CheckUtils.kt
│ │ ├── ClickExtensions.kt
│ │ ├── EmptyHandleUtils.kt
│ │ ├── RxExtensions.kt
│ │ ├── StringExtensions.kt
│ │ ├── ThreadExtensions.kt
│ │ ├── UtilsExtensions.kt
│ │ └── ViewExtensions.kt
│ │ ├── helper
│ │ ├── AppManagerHelper.kt
│ │ ├── BehaviorHelper.kt
│ │ ├── ImageSelectorHelper.kt
│ │ ├── PermissionHelper.kt
│ │ └── RetrofitHelper.kt
│ │ ├── image
│ │ ├── ImageSelectorFragment.kt
│ │ ├── PkImageSelector.kt
│ │ ├── SimpleImageSelectorCallback.kt
│ │ └── contract
│ │ │ ├── SelectMultipleContract.kt
│ │ │ ├── SelectSinglePhotoContract.kt
│ │ │ └── TakePictureContract.kt
│ │ ├── interfaces
│ │ ├── IBehaviorHelperCallback.kt
│ │ ├── IPermissionPopupListener.kt
│ │ ├── IPermissionSetting.kt
│ │ ├── OnImageSelectorCallback.kt
│ │ └── OnPermissionCallback.kt
│ │ ├── manager
│ │ ├── AnimationManager.kt
│ │ ├── PermissionHandlerManager.kt
│ │ └── PhoneStateManager.kt
│ │ ├── network
│ │ ├── HttpDns.kt
│ │ ├── MyX509.java
│ │ ├── RetrofitManager.kt
│ │ ├── entity
│ │ │ └── BaseEntity.java
│ │ ├── error
│ │ │ └── ErrorEnum.kt
│ │ ├── status
│ │ │ ├── AbstractRetrofitData.kt
│ │ │ ├── ApiStatus.kt
│ │ │ ├── BaseApiStatus.kt
│ │ │ └── CommonRetrofitData.kt
│ │ └── strategy
│ │ │ ├── CommonRetrofitStrategy.kt
│ │ │ └── IRetrofitStrategy.kt
│ │ ├── permission
│ │ ├── PermissionSettingFactory.kt
│ │ ├── PkPermission.kt
│ │ ├── PkPermissionFragment.kt
│ │ ├── RequestPermissionContract.kt
│ │ ├── interfaces
│ │ │ ├── ICall.kt
│ │ │ └── IPermissionVersion.kt
│ │ ├── setting
│ │ │ ├── DefaultPermissionSetting.kt
│ │ │ └── NotificationPermissionSetting.kt
│ │ └── version
│ │ │ ├── AndroidOtherPermissionVersion.kt
│ │ │ ├── AndroidPermissionVersionImpl29.kt
│ │ │ ├── AndroidPermissionVersionImpl30.kt
│ │ │ ├── AndroidPermissionVersionImpl31.kt
│ │ │ ├── AndroidPermissionVersionImpl33.kt
│ │ │ ├── PermissionRequest.kt
│ │ │ ├── RealPermissionVersionCall.kt
│ │ │ └── RealPermissionVersionChain.kt
│ │ ├── utils
│ │ ├── ArithmeticUtils.kt
│ │ ├── BasicLibraryUtils.kt
│ │ ├── BitmapUtils.kt
│ │ ├── FoldableDeviceUtils.kt
│ │ ├── GlobalCoroutineExceptionHandler.kt
│ │ ├── NotchScreenUtil.kt
│ │ ├── OSUtils.kt
│ │ ├── StatusBarUtils.java
│ │ ├── SystemUtils.kt
│ │ ├── ThreadUtils.kt
│ │ ├── TimeUtils.kt
│ │ ├── WindowUtils.kt
│ │ ├── bus
│ │ │ └── RxBus.kt
│ │ ├── keyboard
│ │ │ ├── KeyboardUtils.kt
│ │ │ └── OnKeyboardListener.kt
│ │ ├── log
│ │ │ └── LogFileUtils.kt
│ │ ├── mmkv
│ │ │ ├── BaseSharedPreferences.kt
│ │ │ ├── DefaultSharedPreferencesFactory.kt
│ │ │ └── PreferencesUtils.kt
│ │ ├── reflect
│ │ │ └── ReflectUtils.kt
│ │ └── toast
│ │ │ ├── PkToastUtils.kt
│ │ │ └── TopToastLinearLayout.kt
│ │ ├── view
│ │ └── BindingView.kt
│ │ ├── viewmodel
│ │ ├── EmptyViewModel.kt
│ │ ├── ImageSelectViewModel.kt
│ │ ├── PkPermissionViewModel.kt
│ │ └── SameViewModel.kt
│ │ └── viewpage
│ │ ├── DepthPageTransformer.kt
│ │ ├── DepthPageTransformer2.kt
│ │ ├── ZoomOutPageTransformer.kt
│ │ └── ZoomOutPageTransformer2.kt
│ ├── res
│ ├── anim
│ │ ├── slide_in_from_top.xml
│ │ └── slide_out_to_top.xml
│ ├── drawable
│ │ ├── library_clear_black_24dp.xml
│ │ ├── library_done_black_24dp.xml
│ │ ├── library_ic_left_black_back.xml
│ │ └── library_rotate_progressbar.xml
│ ├── layout-v21
│ │ └── layout_submit_loading.xml
│ ├── layout
│ │ ├── layout_submit_loading.xml
│ │ ├── library_dialog_top_toast.xml
│ │ ├── library_recycler_foot_layout.xml
│ │ └── same_layout.xml
│ ├── values
│ │ ├── colors.xml
│ │ ├── ids.xml
│ │ ├── string.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── xml
│ │ └── basic_library_provider_paths.xml
│ └── resources
│ └── META-INF.services
│ └── kotlinx.coroutines.CoroutineExceptionHandler
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── jitpack.yml
└── settings.gradle.kts
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/caches
5 | /.idea/libraries
6 | /.idea/modules.xml
7 | /.idea/workspace.xml
8 | /.idea/navEditor.xml
9 | /.idea/assetWizardSettings.xml
10 | .DS_Store
11 | /build
12 | /captures
13 | .externalNativeBuild
14 | .cxx
15 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/.idea/codeStyles/codeStyleConfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
19 |
20 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.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 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.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 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/.idea/kotlinc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BasicLibrary
2 | - BasicLibrary是基于kotlin+jetpack+mvvm封装的一套框架,提高Android开发效率
3 | - 项目地址:https://github.com/Peakmain/BasicLibrary
4 | - **使用文档链接:** https://github.com/Peakmain/BasicLibrary/wiki
5 |
6 | ### 功能介绍
7 | - Activity Results API实现权限封装
8 | - MMKV的封装
9 | - 防止多次事件的处理
10 | - Retrofit封装实现网络解耦
11 | - 线程的切换,View的抖动效果
12 | - LiveData实现事件分发总线
13 |
14 |
15 | ### 怎样使用
16 | #### Step 1. Add the JitPack repository to your build file
17 |
18 | Add it in your root build.gradle at the end of repositories:
19 | ```
20 | allprojects {
21 | repositories {
22 | ...
23 | maven { url 'https://jitpack.io' }
24 | }
25 | }
26 | ```
27 | but If it is a new version of Android studio,Add it in your root setting.gradle at the end of repositories:
28 | ```
29 | dependencyResolutionManagement {
30 | repositories {
31 | ...
32 | maven { url 'https://jitpack.io' }
33 | }
34 | }
35 | ```
36 | #### Step 2. Add the dependency
37 | ```
38 | dependencies {
39 | implementation 'com.github.Peakmain:BasicLibrary:+'
40 | }
41 | ```
42 | #### 混淆
43 | ```
44 | -keep class com.peakmain.basiclibrary.permission.PkPermissionFragment {
45 | *;
46 | }
47 |
48 | -keep class com.peakmain.basiclibrary.image.ImageSelectorFragment {
49 | *;
50 | }
51 | ```
52 |
53 | #### Screenshot
54 |
55 | 
56 |
57 |
58 | #### 关于我
59 | - 简书([https://www.jianshu.com/u/3ff32f5aea98](https://www.jianshu.com/u/3ff32f5aea98))
60 | - 我的GitHub地址([https://github.com/Peakmain](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2FPeakmain))
61 |
62 | #### Donations
63 | 如果您觉得我的开源库帮您节省了大量的开发时间,请扫描下方的二维码随意打赏,您的支持将激励我不断前进
64 | 
65 | 
66 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-kapt'
4 | android {
5 | compileSdkVersion 33
6 |
7 | defaultConfig {
8 | applicationId "com.peakmain.basiclibary"
9 | minSdkVersion 16
10 | targetSdkVersion 33
11 | versionCode 1
12 | versionName "1.0"
13 | // 设置支持multidex
14 | multiDexEnabled true
15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled true
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 | debug{
24 | minifyEnabled false
25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
26 | }
27 | }
28 | dataBinding {
29 | enabled = true
30 | }
31 | compileOptions {
32 | sourceCompatibility JavaVersion.VERSION_1_8
33 | targetCompatibility JavaVersion.VERSION_1_8
34 | }
35 | }
36 |
37 | dependencies {
38 | implementation fileTree(dir: "libs", include: ["*.jar"])
39 | implementation 'androidx.core:core-ktx:1.8.0'
40 | implementation 'androidx.appcompat:appcompat:1.5.0'
41 | implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
42 | implementation project(path: ':basicLibrary')
43 | implementation 'com.github.Peakmain:BasicUI:1.2.9'
44 | //implementation 'com.github.Peakmain:BasicLibrary:1.1.7'
45 | }
46 |
--------------------------------------------------------------------------------
/app/jks/basicLibrary:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/jks/basicLibrary
--------------------------------------------------------------------------------
/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 |
23 | # ------------------------1.基本不用动区域--------------------------
24 | # 保持哪些类不被混淆
25 | -keep public class * extends android.app.Fragment
26 | -keep public class * extends android.app.Activity
27 | -keep public class * extends android.app.Application
28 | -keep public class * extends android.app.Service
29 | -keep public class * extends android.content.BroadcastReceiver
30 | -keep public class * extends android.content.ContentProvider
31 | -keep public class * extends android.preference.Preference
32 |
33 | -keep class com.peakmain.basiclibrary.permission.PkPermissionFragment {
34 | *;
35 | }
36 |
37 | -keep class com.peakmain.basiclibrary.image.ImageSelectorFragment {
38 | *;
39 | }
40 |
41 | -assumenosideeffects class android.util.Log {
42 | public static boolean isLoggable(java.lang.String, int);
43 | public static int v(...);
44 | public static int i(...);
45 | public static int w(...);
46 | public static int d(...);
47 | public static int e(...);
48 | }
49 | # AndroidX
50 | -keep class com.google.android.material.**{*;}
51 | -keep class androidx.**{*;}
52 | -keep public class * extends androidx.**
53 | -keep interface androidx.**{*;}
54 | -keep @androidx.annotation.Keep class *
55 | -keepclassmembers class *{
56 | @androidx.annotation.Keep *;
57 | }
58 |
59 | -dontwarn com.google.android.material.**
60 | -dontnote com.google.android.material.**
61 | -dontwarn androidx.**
62 |
63 |
--------------------------------------------------------------------------------
/app/release/app-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/release/app-release.apk
--------------------------------------------------------------------------------
/app/release/output-metadata.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 1,
3 | "artifactType": {
4 | "type": "APK",
5 | "kind": "Directory"
6 | },
7 | "applicationId": "com.peakmain.basiclibary",
8 | "variantName": "release",
9 | "elements": [
10 | {
11 | "type": "SINGLE",
12 | "filters": [],
13 | "properties": [],
14 | "versionCode": 1,
15 | "versionName": "1.0",
16 | "enabled": true,
17 | "outputFile": "app-release.apk"
18 | }
19 | ]
20 | }
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
25 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/basiclibary/App.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibary
2 |
3 | import android.app.Application
4 | import android.content.Context
5 | import androidx.multidex.MultiDex
6 | import com.peakmain.basiclibrary.helper.AppManagerHelper
7 |
8 | /**
9 | * author :Peakmain
10 | * createTime:2021/12/23
11 | * mail:2726449200@qq.com
12 | * describe:
13 | */
14 | class App : Application() {
15 | override fun attachBaseContext(base: Context?) {
16 | super.attachBaseContext(base)
17 | MultiDex.install(this)
18 | }
19 | override fun onCreate() {
20 | super.onCreate()
21 | }
22 |
23 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/basiclibary/adapter/TestAdapter.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibary.adapter
2 |
3 | import androidx.recyclerview.widget.LinearLayoutManager
4 | import com.peakmain.basiclibary.R
5 | import com.peakmain.basiclibary.databinding.RecyclerAdpterTestBinding
6 | import com.peakmain.basiclibrary.adapter.CommonRecyclerDataBindingAdapter
7 | import com.peakmain.basiclibrary.adapter.holder.BaseLibraryViewHolder
8 | import com.peakmain.basiclibrary.config.DefaultAdapterFooterConfig
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2022/2/17
13 | * mail:2726449200@qq.com
14 | * describe:
15 | */
16 | class TestAdapter(data: MutableList) :
17 | CommonRecyclerDataBindingAdapter(
18 | data,
19 | R.layout.recycler_adpter_test,
20 | null//DefaultAdapterFooterConfig(layoutManager).item
21 | ) {
22 | override fun convert(
23 | holder: BaseLibraryViewHolder,
24 | itemData: String,
25 | position: Int
26 | ) {
27 | val binding = holder.itemDataBinding
28 | binding.vm = itemData
29 | }
30 |
31 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/basiclibary/fragment/MineFragment.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibary.fragment
2 |
3 | import android.view.View
4 | import com.peakmain.basiclibary.R
5 | import com.peakmain.basiclibary.databinding.FragmentMineBinding
6 | import com.peakmain.basiclibrary.base.fragment.BaseFragment
7 | import com.peakmain.basiclibrary.viewmodel.EmptyViewModel
8 | import com.peakmain.ui.navigationbar.DefaultNavigationBar
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2020/3/9
13 | * mail:2726449200@qq.com
14 | * describe:
15 | */
16 | class MineFragment(override val layoutId: Int = R.layout.fragment_mine) :
17 | BaseFragment() {
18 | override fun initView(fragmentView: View) {
19 | DefaultNavigationBar.Builder(context, fragmentView.findViewById(R.id.view_root))
20 | .hideLeftText()
21 | .hideRightView()
22 | .setTitleText("我的")
23 | .setToolbarBackgroundColor(R.color.ui_color_01a8e3)
24 | .create()
25 | }
26 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/basiclibary/network/DataResponse.java:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibary.network;
2 |
3 | /**
4 | * @author :Peakmain
5 | * version :1.0
6 | * createTime :2018/10/20 0020 上午 10:28
7 | * mail : 2726449200@qq.com
8 | * describe :
9 | */
10 | public class DataResponse {
11 | /**
12 | * data : ...
13 | * errorCode : 0
14 | * errorMsg :
15 | */
16 | private T data;
17 | private int errorCode;
18 | private String errorMsg;
19 |
20 | public T getData() {
21 | return data;
22 | }
23 |
24 | public void setData(T data) {
25 | this.data = data;
26 | }
27 |
28 | public int getErrorCode() {
29 | return errorCode;
30 | }
31 |
32 | public void setErrorCode(int errorCode) {
33 | this.errorCode = errorCode;
34 | }
35 |
36 | public String getErrorMsg() {
37 | return errorMsg;
38 | }
39 |
40 | public void setErrorMsg(String errorMsg) {
41 | this.errorMsg = errorMsg;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/basiclibary/network/ProjectTree.java:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibary.network;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2021/12/23
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | public class ProjectTree {
12 |
13 | /**
14 | * children : []
15 | * courseId : 13
16 | * id : 294
17 | * name : 完整项目
18 | * order : 145000
19 | * parentChapterId : 293
20 | * userControlSetTop : false
21 | * visible : 0
22 | */
23 |
24 | private int courseId;
25 | private int id;
26 | private String name;
27 | private int order;
28 | private int parentChapterId;
29 | private boolean userControlSetTop;
30 | private int visible;
31 | private List> children;
32 |
33 | public int getCourseId() {
34 | return courseId;
35 | }
36 |
37 | public void setCourseId(int courseId) {
38 | this.courseId = courseId;
39 | }
40 |
41 | public int getId() {
42 | return id;
43 | }
44 |
45 | public void setId(int id) {
46 | this.id = id;
47 | }
48 |
49 | public String getName() {
50 | return name;
51 | }
52 |
53 | public void setName(String name) {
54 | this.name = name;
55 | }
56 |
57 | public int getOrder() {
58 | return order;
59 | }
60 |
61 | public void setOrder(int order) {
62 | this.order = order;
63 | }
64 |
65 | public int getParentChapterId() {
66 | return parentChapterId;
67 | }
68 |
69 | public void setParentChapterId(int parentChapterId) {
70 | this.parentChapterId = parentChapterId;
71 | }
72 |
73 | public boolean isUserControlSetTop() {
74 | return userControlSetTop;
75 | }
76 |
77 | public void setUserControlSetTop(boolean userControlSetTop) {
78 | this.userControlSetTop = userControlSetTop;
79 | }
80 |
81 | public int getVisible() {
82 | return visible;
83 | }
84 |
85 | public void setVisible(int visible) {
86 | this.visible = visible;
87 | }
88 |
89 | public List> getChildren() {
90 | return children;
91 | }
92 |
93 | public void setChildren(List> children) {
94 | this.children = children;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/basiclibary/network/WanAndroidApi.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibary.network
2 |
3 | import com.peakmain.basiclibrary.network.entity.BaseEntity
4 | import io.reactivex.Observable
5 | import kotlinx.coroutines.flow.Flow
6 | import retrofit2.http.GET
7 |
8 | /**
9 | * @author :Peakmain
10 | * version :1.0
11 | * createTime :2018/11/13 0013 下午 3:59
12 | * mail : 2726449200@qq.com
13 | * describe :
14 | */
15 | interface WanAndroidApi {
16 | /**
17 | * https://www.wanandroid.com/project/tree/json
18 | */
19 | @get:GET("project/tree/json")
20 | val projectTree: Observable>
21 |
22 | @get:GET("project/tree/json")
23 | val projectTree1: Observable>
24 |
25 | @get:GET("project/tree/json")
26 | val projectTree2: Flow>
27 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/basiclibary/network/status/ApiBaseStatus.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibary.network.status
2 |
3 | import com.peakmain.basiclibrary.network.entity.BaseEntity
4 | import com.peakmain.basiclibrary.network.status.BaseApiStatus
5 | import io.reactivex.Observable
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2021/12/23
10 | * mail:2726449200@qq.com
11 | * describe:
12 | */
13 | abstract class ApiBaseStatus: BaseApiStatus {
14 | abstract fun baseData(entity: T)
15 |
16 | fun tokenError(observable: Observable>?, apiStatus: ApiBaseStatus>) {
17 |
18 | }
19 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/basiclibary/network/status/BaseEntityDataRetrofitData.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibary.network.status
2 |
3 | import com.peakmain.basiclibrary.extend.ktxRunOnUiThread
4 | import com.peakmain.basiclibrary.network.entity.BaseEntity
5 | import com.peakmain.basiclibrary.network.error.ErrorEnum
6 | import com.peakmain.basiclibrary.network.status.AbstractRetrofitData
7 | import io.reactivex.Observable
8 | import io.reactivex.android.schedulers.AndroidSchedulers
9 | import io.reactivex.disposables.Disposable
10 | import io.reactivex.schedulers.Schedulers
11 |
12 | /**
13 | * author :Peakmain
14 | * createTime:2022/08/03
15 | * mail:2726449200@qq.com
16 | * describe:
17 | */
18 | class BaseEntityDataRetrofitData(val apiStatus: ApiBaseStatus>) :
19 | AbstractRetrofitData>(apiStatus) {
20 | override fun createData(observable: Observable>): Disposable {
21 | apiStatus.before()
22 | return observable.subscribeOn(Schedulers.io())
23 | .observeOn(AndroidSchedulers.mainThread()).subscribe({ t ->
24 | checkResult(observable, t, apiStatus)
25 | }, { exception ->
26 | checkError(exception, apiStatus)
27 | })
28 | }
29 |
30 | private fun checkError(exception: Throwable, apiStatus: ApiBaseStatus>) {
31 | exception.printStackTrace()
32 | apiStatus.error(Exception(exception))
33 | }
34 |
35 | private fun checkResult(
36 | observable: Observable>,
37 | t: BaseEntity,
38 | apiStatus: ApiBaseStatus>
39 | ) {
40 | apiStatus.baseData(t)
41 | when (t.result) {
42 | ErrorEnum.SUCCESS -> {
43 | if (t.data != null) {
44 | apiStatus.success(t)
45 | } else {
46 | apiStatus.isEmpty()
47 | }
48 | }
49 | ErrorEnum.TOKEN_ERROR -> {
50 | //token失效
51 | apiStatus.tokenError(observable, apiStatus)
52 | }
53 | else -> {
54 | apiStatus.ktxRunOnUiThread {
55 | error(Exception(t.detail))
56 | }
57 | }
58 |
59 | }
60 | }
61 |
62 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/basiclibary/utils/AtPermissionUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibary.utils
2 |
3 | import android.app.Activity
4 | import com.peakmain.basiclibrary.interfaces.IPermissionPopupListener
5 | import com.peakmain.basiclibrary.utils.toast.PkToastUtils
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2024/11/21
10 | * mail:2726449200@qq.com
11 | * describe:
12 | */
13 | class AtPermissionUtils(val activity: Activity?) {
14 |
15 | val locationListener = createRequestListener(
16 | "位置权限使用说明",
17 | "开启定位权限,为您提供酒店推荐服务。"
18 | )
19 |
20 | val photoListener = createRequestListener(
21 | "相册权限使用说明",
22 | "开启相册权限,为您提供个人信息头像上传、随手拍、竹居借书、在线客服上传照片与视频、申请差旅合作提供营业执照和联系人证件、上传酒店和零售商品点评照片服务。"
23 | )
24 | val cameraListener = createRequestListener(
25 | "相机权限使用说明",
26 | "开启相机权限,为您提供个人信息头像上传、随手拍、竹居借书、在线客服上传照片与视频、申请差旅合作提供营业执照和联系人证件、上传酒店和零售商品点评照片服务。"
27 | )
28 | val storageListener = createRequestListener(
29 | "存储权限说明",
30 | "开启存储权限,帮组您实现更换头像、上传图片、客服沟通服务"
31 | )
32 | val blueListener = createRequestListener(
33 | "蓝牙权限使用说明",
34 | "开启蓝牙权限,为您识别您周围的门锁设备。"
35 | )
36 |
37 | private fun createRequestListener(title: String, message: String): IPermissionPopupListener {
38 | return object : IPermissionPopupListener {
39 | private val utils by lazy {
40 | PkToastUtils.build(activity).apply {
41 | setTitle(title)
42 | .setMessage(message)
43 | }
44 | }
45 |
46 | override fun onShowPermissionPopup() {
47 | utils
48 | .show()
49 | }
50 |
51 | override fun onHidePermissionPopup() {
52 | utils.dismiss()
53 | }
54 |
55 | }
56 | }
57 |
58 | }
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/basiclibary/viewModel/HomeFragmentViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibary.viewModel
2 |
3 | import android.util.Log
4 | import android.view.View
5 | import com.peakmain.basiclibary.network.DataResponse
6 | import com.peakmain.basiclibary.network.ProjectTree
7 | import com.peakmain.basiclibary.network.WanAndroidApi
8 | import com.peakmain.basiclibrary.base.viewmodel.BaseViewModel
9 | import com.peakmain.basiclibrary.network.RetrofitManager
10 | import com.peakmain.basiclibrary.network.entity.BaseEntity
11 | import com.peakmain.basiclibary.network.status.ApiBaseStatus
12 | import com.peakmain.basiclibrary.network.status.ApiStatus
13 | import com.peakmain.basiclibary.network.status.BaseEntityDataRetrofitData
14 |
15 | /**
16 | * author :Peakmain
17 | * createTime:2021/12/27
18 | * mail:2726449200@qq.com
19 | * describe:
20 | */
21 | class HomeFragmentViewModel : BaseViewModel() {
22 | private lateinit var api: WanAndroidApi
23 | val REQUEST_BASE_URL = "https://wanandroid.com/"
24 | val delayTime = 1000L
25 | override fun initModel() {
26 | api = RetrofitManager.createService(WanAndroidApi::class.java, REQUEST_BASE_URL)
27 | }
28 |
29 | val isShow = false
30 | fun getProjectTree() {
31 |
32 | RetrofitManager.createData(api.projectTree,
33 | object : ApiStatus>() {
34 |
35 | override fun success(t: DataResponse) {
36 | Log.e("TAG", t.toString())
37 | }
38 |
39 | override fun error(exception: Exception) {
40 | }
41 |
42 |
43 | })
44 | /* RetrofitManager.createData(api.projectTree1, BaseEntityDataRetrofitData(object :
45 | ApiBaseStatus>(){
46 | override fun baseData(entity: BaseEntity) {
47 | TODO("Not yet implemented")
48 | }
49 |
50 | override fun before() {
51 | TODO("Not yet implemented")
52 | }
53 |
54 | override fun success(t: BaseEntity) {
55 | TODO("Not yet implemented")
56 | }
57 |
58 | override fun isEmpty() {
59 | TODO("Not yet implemented")
60 | }
61 |
62 | override fun loadMore(t: BaseEntity, isRefresh: Boolean) {
63 | TODO("Not yet implemented")
64 | }
65 |
66 | override fun error(exception: java.lang.Exception) {
67 | TODO("Not yet implemented")
68 | }
69 |
70 | }) )
71 | RetrofitManager.createData(api.projectTree, {
72 | //todo before()
73 | }, {
74 | //todo success(
75 | }, {
76 | //todo error()
77 | })*/
78 | }
79 |
80 |
81 | fun clickListener(view: View) {
82 | }
83 |
84 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/peakmain/basiclibary/viewModel/MainViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibary.viewModel
2 |
3 | import com.peakmain.basiclibrary.base.viewmodel.BaseViewModel
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2022/09/02
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | class MainViewModel:BaseViewModel() {
12 | override fun initModel() {
13 |
14 | }
15 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
15 |
18 |
21 |
22 |
23 |
24 |
30 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_bottom_navigation_home.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_bottom_navigation_me.xml:
--------------------------------------------------------------------------------
1 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/src/main/res/drawable/logo.jpg
--------------------------------------------------------------------------------
/app/src/main/res/drawable/selector_tab_color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_behavior.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
21 |
22 |
23 |
32 |
33 |
39 |
40 |
49 |
50 |
59 |
60 |
69 |
70 |
87 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
20 |
21 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_home.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
12 |
17 |
18 |
25 |
26 |
37 |
38 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_mine.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
14 |
15 |
21 |
22 |
31 |
32 |
41 |
42 |
51 |
52 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/recycler_adpter_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
13 |
14 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/bottom_navigation_main.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values-night/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ffffff
4 | #ffffff
5 | #ffffff
6 | #ffffff
7 | #FFFFFF
8 | #ffffff
9 | #ffffff
10 | #ffffff
11 | #ffffff
12 | #ffffff
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #008577
4 | #00574B
5 | #921241
6 | #D81B60
7 | #FFFFFF
8 | #F117D4
9 | #d1d1d1
10 | #F5F5F5
11 | #7D7D7D
12 | #999999
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | BasicLibary
3 | Peakmain
4 | Github:https://github.com/Peakmain
5 | 简书:https://www.jianshu.com/u/3ff32f5aea98
6 |
7 | 首页
8 |
9 | 我的
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
--------------------------------------------------------------------------------
/basicLibrary/.gitignore:
--------------------------------------------------------------------------------
1 | /build
--------------------------------------------------------------------------------
/basicLibrary/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'kotlin-android'
3 | apply plugin: 'kotlin-kapt'
4 | android {
5 | compileSdkVersion 33
6 |
7 | defaultConfig {
8 | minSdkVersion 16
9 | targetSdkVersion 33
10 | versionCode 1
11 | versionName "1.0"
12 |
13 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
14 | consumerProguardFiles "consumer-rules.pro"
15 |
16 | }
17 |
18 | buildTypes {
19 | release {
20 | minifyEnabled false
21 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
22 | }
23 |
24 | }
25 | buildFeatures {
26 | dataBinding true
27 | }
28 | packagingOptions {
29 | exclude 'AndroidManifest.xml'
30 | }
31 | }
32 | dependencies {
33 | implementation fileTree(dir: "libs", include: ["*.jar"])
34 | implementation('androidx.core:core-ktx:1.8.0') {
35 | transitive false
36 | }
37 | implementation 'androidx.appcompat:appcompat:1.5.0'
38 | api('org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1') {
39 | transitive false
40 | }
41 | api('org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1') {
42 | transitive false
43 | }
44 |
45 | //OkHttp3
46 | api 'com.squareup.okhttp3:logging-interceptor:3.12.0'
47 | //Retrofit网络请求
48 | api("com.squareup.retrofit2:converter-gson:2.6.2") {
49 | exclude group: "com.squareup.okhttp3", module: "okhttp"
50 | }
51 | api('com.squareup.retrofit2:adapter-rxjava2:2.4.0') {
52 | exclude group: "com.squareup.retrofit2", module: "retrofit"
53 | }
54 | api("com.jakewharton.retrofit:retrofit2-kotlin-coroutines-adapter:0.9.2") {
55 | transitive false
56 | }
57 | api "io.reactivex.rxjava2:rxandroid:2.1.1"
58 | api 'com.tencent:mmkv:1.2.11'
59 | implementation 'androidx.cardview:cardview:1.0.0'
60 |
61 | kapt "com.android.databinding:compiler:3.1.4"
62 | api 'androidx.recyclerview:recyclerview:1.2.1'
63 | api 'com.google.android.material:material:1.6.1'
64 | implementation 'com.github.Peakmain:BasicUI:1.2.11'
65 | api 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0'
66 | implementation 'com.qiniu:happy-dns:0.2.13'
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/basicLibrary/consumer-rules.pro:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/basicLibrary/consumer-rules.pro
--------------------------------------------------------------------------------
/basicLibrary/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
--------------------------------------------------------------------------------
/basicLibrary/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
10 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/BasicLibraryProvider.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary
2 |
3 | import android.app.Application
4 | import androidx.core.content.FileProvider
5 | import androidx.lifecycle.ViewModelStore
6 | import com.peakmain.basiclibrary.base.IApp
7 | import com.peakmain.basiclibrary.config.BasicLibraryConfig
8 |
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2021/12/27
13 | * mail:2726449200@qq.com
14 | * describe:
15 | */
16 | class BasicLibraryProvider : FileProvider(), IApp {
17 | private lateinit var viewModelStore: ViewModelStore
18 | override fun onCreate(): Boolean {
19 | BasicLibraryConfig.getInstance()?.setApp(this)
20 | viewModelStore = ViewModelStore()
21 | return true
22 | }
23 |
24 | override fun getApplication(): Application {
25 | return context?.applicationContext as Application
26 | }
27 |
28 | override fun getViewModelStore(): ViewModelStore {
29 | return viewModelStore
30 | }
31 |
32 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/adapter/holder/BaseLibraryFooterViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.adapter.holder
2 |
3 | import androidx.databinding.ViewDataBinding
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2022/2/17
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | open class BaseLibraryFooterViewHolder constructor(itemDataBinding: E) :
12 | BaseLibraryViewHolder(itemDataBinding)
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/adapter/holder/BaseLibraryViewHolder.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.adapter.holder
2 |
3 | import androidx.databinding.ViewDataBinding
4 | import androidx.recyclerview.widget.RecyclerView
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2022/2/17
9 | * mail:2726449200@qq.com
10 | * describe:
11 | */
12 | open class BaseLibraryViewHolder constructor(var itemDataBinding: E) :
13 | RecyclerView.ViewHolder(itemDataBinding.root)
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/adapter/listener/BaseLibraryOnScrollListener.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.adapter.listener
2 |
3 | import androidx.recyclerview.widget.LinearLayoutManager
4 | import androidx.recyclerview.widget.RecyclerView
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2022/2/17
9 | * mail:2726449200@qq.com
10 | * describe:
11 | */
12 | abstract class BaseLibraryOnScrollListener constructor() : RecyclerView.OnScrollListener(),OnScrollCallback {
13 |
14 | private var mLinearLayoutManager: LinearLayoutManager? = null
15 |
16 | constructor(
17 | linearLayoutManager: LinearLayoutManager
18 | ) : this() {
19 | this.mLinearLayoutManager = linearLayoutManager
20 | }
21 |
22 | override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
23 | super.onScrolled(recyclerView, dx, dy)
24 | if (dy > 0) {
25 | onScrolledUp()
26 | mLinearLayoutManager?.apply {
27 | val findLastVisibleItemPosition = findLastVisibleItemPosition()
28 | val itemCount = itemCount
29 | if(findLastVisibleItemPosition==itemCount-1){
30 | onLoadMore()
31 | }
32 | }
33 | }else{
34 | onScrolledDown()
35 | }
36 | }
37 | abstract fun onLoadMore()
38 | override fun onScrolledUp() {
39 |
40 | }
41 |
42 | override fun onScrolledDown() {
43 |
44 | }
45 | }
46 |
47 | interface OnScrollCallback {
48 | fun onScrolledUp()
49 | fun onScrolledDown()
50 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/adapter/listener/OnItemClickListener.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.adapter.listener
2 |
3 | /**
4 | * author :Peakmain
5 | * version : 1.0
6 | * createTime:2019/2/25
7 | * mail:2726449200@qq.com
8 | * describe:Adapter条目的点击事件
9 | */
10 | interface OnItemClickListener {
11 | fun onItemClick(position: Int)
12 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/adapter/listener/OnLongClickListener.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.adapter.listener
2 |
3 | /**
4 | * author :Peakmain
5 | * version : 1.0
6 | * createTime:2019/2/25
7 | * mail:2726449200@qq.com
8 | * describe:Adapter条目的长按事件
9 | */
10 | interface OnLongClickListener {
11 | fun onLongClick(position: Int): Boolean
12 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/ainimator/SimpleAnimationListener.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.ainimator
2 |
3 | import android.view.animation.Animation
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2023/9/19
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | open class SimpleAnimationListener : Animation.AnimationListener {
12 | override fun onAnimationStart(animation: Animation?) {
13 |
14 | }
15 |
16 | override fun onAnimationEnd(animation: Animation?) {
17 | }
18 |
19 | override fun onAnimationRepeat(animation: Animation?) {
20 | }
21 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/ainimator/SimpleAnimatorListener.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.ainimator
2 |
3 | import android.animation.Animator
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2023/9/19
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | open class SimpleAnimatorListener : Animator.AnimatorListener {
12 | override fun onAnimationStart(animation: Animator) {
13 |
14 | }
15 |
16 | override fun onAnimationEnd(animation: Animator) {
17 | }
18 |
19 | override fun onAnimationCancel(animation: Animator) {
20 | }
21 |
22 | override fun onAnimationRepeat(animation: Animator) {
23 | }
24 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/base/BaseSingleton.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.base
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/4/22
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 |
10 | abstract class BaseEmptySingleton {
11 | @Volatile
12 | private var sInstance: T? = null
13 | protected abstract val createSingleton :()->T
14 | fun getInstance(): T? {
15 | sInstance ?: synchronized(this) {
16 | sInstance ?: createSingleton().also {
17 | sInstance = it
18 | }
19 | }
20 | return sInstance
21 | }
22 | }
23 |
24 | abstract class BaseOneSingleton {
25 | @Volatile
26 | private var sInstance: T? = null
27 | protected abstract fun createSingleton(params:P):T
28 | fun getInstance(params: P): T? {
29 | sInstance ?: synchronized(this) {
30 | sInstance ?: createSingleton(params).also {
31 | sInstance = it
32 | }
33 | }
34 | return sInstance
35 | }
36 | }
37 |
38 | abstract class BaseTwoSingleton {
39 | @Volatile
40 | private var sInstance: T? = null
41 | protected abstract fun createSingleton(params1: P1, params2: P2): T?
42 | fun getInstance(params1: P1, params2: P2): T? {
43 | sInstance ?: synchronized(this) {
44 | sInstance ?: createSingleton(params1, params2).also {
45 | sInstance = it
46 | }
47 | }
48 | return sInstance
49 | }
50 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/base/IApp.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.base
2 |
3 | import android.app.Application
4 | import androidx.lifecycle.ViewModelProvider
5 | import androidx.lifecycle.ViewModelStore
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2021/12/24
10 | * mail:2726449200@qq.com
11 | * describe:
12 | */
13 | interface IApp {
14 | fun getViewModelProvider(): ViewModelProvider {
15 | val factory = ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())
16 | return ViewModelProvider(getViewModelStore(), factory)
17 | }
18 |
19 | fun getApplication(): Application
20 | fun getViewModelStore(): ViewModelStore
21 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/base/activity/BaseActivity.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.base.activity
2 |
3 | import android.os.Bundle
4 | import androidx.appcompat.app.AppCompatActivity
5 | import androidx.databinding.DataBindingUtil
6 | import androidx.databinding.ViewDataBinding
7 | import androidx.lifecycle.ViewModel
8 | import com.peakmain.basiclibrary.BR
9 | import com.peakmain.basiclibrary.base.IApp
10 | import com.peakmain.basiclibrary.base.viewmodel.BaseViewModel
11 | import com.peakmain.basiclibrary.config.BasicLibraryConfig
12 | import java.lang.reflect.ParameterizedType
13 |
14 | /**
15 | * author :Peakmain
16 | * createTime:2021/12/24
17 | * mail:2726449200@qq.com
18 | * describe:
19 | */
20 | abstract class BaseActivity :
21 | AppCompatActivity() {
22 | abstract val layoutId: Int
23 | protected lateinit var mBinding: T
24 | protected lateinit var mViewModel: E
25 | private var app: IApp? = BasicLibraryConfig.getInstance()?.getApp()
26 |
27 |
28 | override fun onCreate(savedInstanceState: Bundle?) {
29 | super.onCreate(savedInstanceState)
30 | initBefore()
31 | mBinding = DataBindingUtil.setContentView(this, layoutId)
32 | initViewModel()
33 | mViewModel.initModel()
34 | mBinding.setVariable(BR.vm, mViewModel)
35 | mBinding.lifecycleOwner = this
36 | initView()
37 | }
38 |
39 | private fun initViewModel() {
40 | val superClass = javaClass.genericSuperclass
41 | if (superClass is ParameterizedType) {
42 | val type = superClass.actualTypeArguments[1]
43 | val clazz = type as Class
44 | mViewModel = getViewModel(clazz)
45 | }else{
46 | throw IllegalArgumentException("ParameterizedType error")
47 | }
48 |
49 | }
50 |
51 |
52 | abstract fun initView()
53 |
54 |
55 | open fun initBefore() {
56 | }
57 |
58 | protected fun getViewModel(modelClass: Class): E {
59 | if (app == null) {
60 | throw NullPointerException("app must not be null")
61 | }
62 | return app!!.getViewModelProvider()[modelClass]
63 | }
64 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/base/fragment/BaseFragment.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.base.fragment
2 |
3 | import android.os.Bundle
4 | import android.util.Log
5 | import android.view.LayoutInflater
6 | import android.view.View
7 | import android.view.ViewGroup
8 | import androidx.databinding.DataBindingUtil
9 | import androidx.databinding.ViewDataBinding
10 | import androidx.fragment.app.Fragment
11 | import androidx.lifecycle.ViewModel
12 | import com.peakmain.basiclibrary.BR
13 | import com.peakmain.basiclibrary.base.IApp
14 | import com.peakmain.basiclibrary.base.viewmodel.BaseViewModel
15 | import com.peakmain.basiclibrary.config.BasicLibraryConfig
16 | import java.lang.reflect.ParameterizedType
17 |
18 | /**
19 | * author :Peakmain
20 | * createTime:2021/12/27
21 | * mail:2726449200@qq.com
22 | * describe:
23 | */
24 | abstract class BaseFragment :
25 | Fragment() {
26 | companion object {
27 | private val TAG =
28 | BaseFragment::class.java.superclass?.simpleName ?: BaseFragment::class.java.simpleName
29 | }
30 |
31 | protected lateinit var mViewModel: E
32 | protected lateinit var mBinding: T
33 | private var app: IApp? = BasicLibraryConfig.getInstance()?.getApp()
34 | override fun onCreateView(
35 | inflater: LayoutInflater,
36 | container: ViewGroup?,
37 | savedInstanceState: Bundle?
38 | ): View? {
39 | val fragmentView = inflater.inflate(layoutId, container, false)
40 | initViewModel(fragmentView)
41 |
42 | initView(fragmentView)
43 | return fragmentView
44 | }
45 |
46 | private fun initViewModel(fragmentView: View) {
47 | val genericSuperclass = javaClass.genericSuperclass
48 | var modelClass: Class? = null
49 | if (genericSuperclass is ParameterizedType) {
50 | val type = genericSuperclass.actualTypeArguments[1]
51 | modelClass = type as Class
52 | } else {
53 | Log.e(TAG, "initViewModel init error!!")
54 | }
55 | if (modelClass != null) {
56 | mViewModel = getViewModel(modelClass)
57 | mBinding = DataBindingUtil.bind(fragmentView)!!
58 | mBinding.setVariable(BR.vm, mViewModel)
59 | mBinding.lifecycleOwner=this
60 | mViewModel.initModel()
61 | }
62 | }
63 |
64 | protected fun getViewModel(modelClass: Class): T {
65 | if (app == null) {
66 | throw NullPointerException("app must not be null")
67 | }
68 | return app!!.getViewModelProvider()[modelClass]
69 | }
70 |
71 | abstract val layoutId: Int
72 | abstract fun initView(fragmentView: View)
73 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/base/viewmodel/BaseViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.base.viewmodel
2 |
3 | import androidx.lifecycle.ViewModel
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2021/12/24
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | abstract class BaseViewModel: ViewModel() {
12 | abstract fun initModel()
13 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/bean/BasicLibraryBeanKt.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.bean
2 |
3 | import android.graphics.drawable.Drawable
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2022/3/8
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | data class AppManagerBean(
12 | val packageName: String,
13 | val appName: String,
14 | val appIcon: Drawable,
15 | val firstRunName: String,
16 | val isSystemApp: Boolean
17 | )
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/config/BaseAdapterFooterConfig.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.config
2 |
3 | import android.view.ViewGroup
4 | import androidx.databinding.ViewDataBinding
5 | import androidx.recyclerview.widget.LinearLayoutManager
6 | import com.peakmain.basiclibrary.adapter.holder.BaseLibraryFooterViewHolder
7 |
8 | /**
9 | * author :Peakmain
10 | * createTime:2022/2/17
11 | * mail:2726449200@qq.com
12 | * describe:显示更多的Config
13 | */
14 | interface BaseAdapterFooterConfig {
15 | fun footerDataBinding(parent: ViewGroup): E
16 | fun footerViewHolder(holder: BaseLibraryFooterViewHolder,data:MutableList,loadStatus:Int)
17 | fun layoutManager(): LinearLayoutManager
18 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/config/BasicLibraryConfig.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.config
2 |
3 | import com.peakmain.basiclibrary.base.BaseEmptySingleton
4 | import com.peakmain.basiclibrary.base.IApp
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2021/12/27
9 | * mail:2726449200@qq.com
10 | * describe:全局的配置
11 | */
12 | class BasicLibraryConfig private constructor() {
13 | private var mApp: IApp? = null
14 |
15 | companion object:BaseEmptySingleton(){
16 | override val createSingleton=::BasicLibraryConfig
17 | }
18 |
19 | fun setApp(app: IApp) {
20 | this.mApp = app
21 | }
22 |
23 | fun getApp(): IApp? {
24 | return mApp
25 | }
26 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/config/DefaultAdapterFooterConfig.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.config
2 |
3 | import android.view.LayoutInflater
4 | import android.view.ViewGroup
5 | import androidx.databinding.DataBindingUtil
6 | import androidx.databinding.ViewDataBinding
7 | import androidx.recyclerview.widget.LinearLayoutManager
8 | import com.peakmain.basiclibrary.R
9 | import com.peakmain.basiclibrary.adapter.CommonRecyclerDataBindingAdapter
10 | import com.peakmain.basiclibrary.adapter.holder.BaseLibraryFooterViewHolder
11 | import com.peakmain.basiclibrary.databinding.LibraryRecyclerFootLayoutBinding
12 |
13 | /**
14 | * author :Peakmain
15 | * createTime:2022/2/17
16 | * mail:2726449200@qq.com
17 | * describe:
18 | */
19 | class DefaultAdapterFooterConfig(
20 | var layoutManager: LinearLayoutManager,
21 | var loadContent: String = "正在加载中...",
22 | var loadCompleteContent: String = "加载完成",
23 | var loadNoMoreContent: String = "没有更多了",
24 | var emptyContent: String = "暂无内容"
25 | ) {
26 |
27 | val item = object : BaseAdapterFooterConfig {
28 | override fun footerDataBinding(parent: ViewGroup): E {
29 | return DataBindingUtil.inflate(
30 | LayoutInflater.from(parent.context),
31 | R.layout.library_recycler_foot_layout,
32 | parent,
33 | false
34 | )
35 | }
36 |
37 | override fun footerViewHolder(
38 | holder: BaseLibraryFooterViewHolder,
39 | data: MutableList,
40 | loadStatus: Int
41 | ) {
42 | val dataBinding = holder.itemDataBinding as LibraryRecyclerFootLayoutBinding
43 | when (loadStatus) {
44 | CommonRecyclerDataBindingAdapter.STATUS_LOADING -> {
45 | dataBinding.progress = true
46 | dataBinding.content = loadContent
47 | }
48 | CommonRecyclerDataBindingAdapter.STATUS_COMPLETE -> {
49 | dataBinding.progress = false
50 | dataBinding.content = loadCompleteContent
51 | }
52 | CommonRecyclerDataBindingAdapter.STATUS_NO_MORE -> {
53 | dataBinding.progress = false
54 | dataBinding.content = if (data.isEmpty()) emptyContent else loadNoMoreContent
55 | }
56 | }
57 | }
58 |
59 | override fun layoutManager(): LinearLayoutManager {
60 | return layoutManager
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/config/ImageRequestConfig.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.config
2 |
3 | import androidx.fragment.app.Fragment
4 | import androidx.fragment.app.FragmentActivity
5 | import com.peakmain.basiclibrary.constants.ImageSelectConstants
6 | import com.peakmain.basiclibrary.interfaces.OnImageSelectorCallback
7 | import java.io.Serializable
8 |
9 | /**
10 | * author :Peakmain
11 | * createTime:2022/08/18
12 | * mail:2726449200@qq.com
13 | * describe:
14 | */
15 | class ImageRequestConfig : Serializable {
16 | //最多选择图片的数量
17 | var maxNum: Int = 1
18 |
19 | //默认是单选
20 | var isSingle: Boolean = true
21 |
22 | //默认是图片类型
23 | var imageType: Int = ImageSelectConstants.IMAGE_TYPE
24 | }
25 |
26 | internal data class ImageContext(
27 | var fragment: Fragment? = null,
28 | var activity: FragmentActivity? = null,
29 | var onImageSelectorCallback: OnImageSelectorCallback? = null
30 | )
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/constants/ImageSelectConstants.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.constants
2 |
3 | import androidx.annotation.IntDef
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2022/08/18
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | object ImageSelectConstants {
12 | const val REQUEST_CONFIG: String = "requestConfig"
13 | const val TAKE_PHOTO_TYPE = 0
14 | const val IMAGE_TYPE = 1
15 | const val VIDEO_TYPE = 2
16 | const val ALL_TYPE = 3
17 |
18 | @IntDef(TAKE_PHOTO_TYPE, IMAGE_TYPE, VIDEO_TYPE, ALL_TYPE)
19 | @Retention(AnnotationRetention.SOURCE)
20 | annotation class ImageSelectType
21 |
22 |
23 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/constants/PermissionMapConstants.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.constants
2 |
3 | import android.Manifest
4 | import androidx.annotation.StringDef
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2024/11/21
9 | * mail:2726449200@qq.com
10 | * describe:
11 | */
12 | object PermissionMapConstants {
13 | val dangerousPermissionTagMap = mapOf(
14 | // 日历权限
15 | Manifest.permission.READ_CALENDAR to "calendar",
16 | Manifest.permission.WRITE_CALENDAR to "calendar",
17 |
18 | // 相机权限
19 | Manifest.permission.CAMERA to "camera",
20 |
21 | // 联系人权限
22 | Manifest.permission.READ_CONTACTS to "contacts",
23 | Manifest.permission.WRITE_CONTACTS to "contacts",
24 | Manifest.permission.GET_ACCOUNTS to "contacts",
25 |
26 | // 位置权限
27 | Manifest.permission.ACCESS_FINE_LOCATION to "location",
28 | Manifest.permission.ACCESS_COARSE_LOCATION to "location",
29 |
30 | // 麦克风权限
31 | Manifest.permission.RECORD_AUDIO to "microphone",
32 |
33 | // 电话权限
34 | Manifest.permission.READ_PHONE_STATE to "phone",
35 | Manifest.permission.CALL_PHONE to "phone",
36 | Manifest.permission.READ_CALL_LOG to "phone",
37 | Manifest.permission.WRITE_CALL_LOG to "phone",
38 | Manifest.permission.ADD_VOICEMAIL to "phone",
39 | Manifest.permission.USE_SIP to "phone",
40 | Manifest.permission.PROCESS_OUTGOING_CALLS to "phone",
41 |
42 | // 传感器权限
43 | Manifest.permission.BODY_SENSORS to "sensors",
44 |
45 | // 短信权限
46 | Manifest.permission.SEND_SMS to "sms",
47 | Manifest.permission.RECEIVE_SMS to "sms",
48 | Manifest.permission.READ_SMS to "sms",
49 | Manifest.permission.RECEIVE_WAP_PUSH to "sms",
50 | Manifest.permission.RECEIVE_MMS to "sms",
51 |
52 | // 存储权限
53 | Manifest.permission.READ_EXTERNAL_STORAGE to "storage",
54 | Manifest.permission.WRITE_EXTERNAL_STORAGE to "storage",
55 |
56 | //蓝牙
57 | Manifest.permission.BLUETOOTH_CONNECT to "blue",
58 | Manifest.permission.BLUETOOTH_SCAN to "blue",
59 | )
60 |
61 | @StringDef(
62 | PermissionTag.CALENDAR,
63 | PermissionTag.CAMERA,
64 | PermissionTag.CONTACTS,
65 | PermissionTag.LOCATION,
66 | PermissionTag.MICROPHONE,
67 | PermissionTag.PHONE,
68 | PermissionTag.SENSORS,
69 | PermissionTag.SMS,
70 | PermissionTag.STORAGE,
71 | PermissionTag.BLUE,
72 | )
73 | @Retention(AnnotationRetention.SOURCE)
74 | annotation class PermissionTag {
75 | companion object {
76 | const val CALENDAR = "calendar"
77 | const val CAMERA = "camera"
78 | const val CONTACTS = "contacts"
79 | const val LOCATION = "location"
80 | const val MICROPHONE = "microphone"
81 | const val PHONE = "phone"
82 | const val SENSORS = "sensors"
83 | const val SMS = "sms"
84 | const val STORAGE = "storage"
85 | const val BLUE = "blue"
86 | }
87 | }
88 |
89 |
90 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/dialog/CustomCenterDialog.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.dialog
2 |
3 | import android.app.Dialog
4 | import android.content.Context
5 | import android.view.Gravity
6 | import android.view.View
7 | import com.peakmain.basiclibrary.R
8 |
9 | /**
10 | * author :Peakmain
11 | * createTime:2021/12/27
12 | * mail:2726449200@qq.com
13 | * describe:
14 | */
15 | class CustomCenterDialog(context: Context, layout: View, style: Int=R.style.CustomDialogThemes) : Dialog(context, style) {
16 |
17 | init {
18 |
19 | setContentView(layout)
20 |
21 | val window = window
22 |
23 | val params = window!!.attributes
24 |
25 | params.gravity = Gravity.CENTER
26 |
27 | window.attributes = params
28 | }
29 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/extend/CheckUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.extend
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2023/9/8
6 | * mail:2726449200@qq.com
7 | * describe:检测工具
8 | */
9 | fun List?.indexOfBound(index: Int): Boolean {
10 | if (this.isNullOrEmpty()) return true
11 | return index >= this.size
12 | }
13 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/extend/ClickExtensions.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.extend
2 |
3 | import android.view.MotionEvent
4 | import android.view.View
5 | import android.widget.TextView
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2021/12/27
10 | * mail:2726449200@qq.com
11 | * describe:点击事件的扩展类
12 | */
13 | private var T.lastClickTime: Long
14 | get() = if (getTag(1638288000) != null) getTag(1638288000) as Long else -1
15 | set(value) {
16 | setTag(1638288000, value)
17 | }
18 | private var T.delayTime: Long
19 | get() = if (getTag(1638288600) != null) getTag(1638288600) as Long else -1
20 | set(value) {
21 | setTag(1638288600, value)
22 | }
23 |
24 | private fun T.clickEnable(): Boolean {
25 | var isClickEnable = false
26 | val currentTimeMillis = System.currentTimeMillis()
27 | if (currentTimeMillis - lastClickTime >= delayTime) {
28 | isClickEnable = true
29 | }
30 | lastClickTime = currentTimeMillis
31 | return isClickEnable
32 | }
33 |
34 |
35 | fun T.click(block: (T) -> Unit) = setOnClickListener {
36 | if (clickEnable()) {
37 | block(it as T)
38 | }
39 | }
40 |
41 |
42 | /**
43 | * @param time:延迟时间,默认750
44 | * @param block:事件处理函数
45 | */
46 | fun T.clickViewDelay(time: Long = 750, block: (T) -> Unit) {
47 | delayTime = time
48 | setOnClickListener {
49 | if (clickEnable()) {
50 | block(it as T)
51 | }
52 | }
53 | }
54 |
55 | /**
56 | * TextView点击事件拆分
57 | */
58 | fun T.clickClipListener(
59 | leftClick: (View) -> Unit = {},
60 | rightClick: (View) -> Unit = {}
61 | ) {
62 | this.run {
63 | setOnTouchListener(object : View.OnTouchListener {
64 | override fun onTouch(v: View, event: MotionEvent): Boolean {
65 | when (event.action) {
66 | MotionEvent.ACTION_DOWN -> {
67 | val drawableLeft = compoundDrawables[0]
68 | if (drawableLeft != null && event.rawX <= left + drawableLeft.bounds.width()) {
69 | leftClick(this@run)
70 | return true
71 | }
72 | val drawableRight = compoundDrawables[2]
73 | return if (drawableRight != null && event.rawX >= width-paddingRight-drawableRight.intrinsicWidth) { // 增加了宽度,该方向+当前icon宽度
74 | rightClick(this@run)
75 | true
76 | } else {
77 | false
78 | }
79 | }
80 | else -> return false
81 | }
82 | }
83 | })
84 | }
85 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/extend/EmptyHandleUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.extend
2 |
3 | import android.content.Context
4 | import androidx.fragment.app.FragmentActivity
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2024/11/14
9 | * mail:2726449200@qq.com
10 | * describe:空逻辑处理
11 | */
12 | fun Context?.handleEmpty(block: ((Context) -> Unit)? = null) {
13 | this?.let {
14 | block?.invoke(it)
15 | }
16 | }
17 | fun FragmentActivity?.handleEmptyActivity(block: ((FragmentActivity) -> Unit)? = null) {
18 | this?.let {
19 | block?.invoke(it)
20 | }
21 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/extend/RxExtensions.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.extend
2 |
3 | import io.reactivex.disposables.Disposable
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2022/10/24
8 | * mail:2726449200@qq.com
9 | * describe:Rx 扩展工具类
10 | */
11 | /**
12 | * Rxjava Disposable取消
13 | */
14 | fun Disposable?.cancel() {
15 | if (this == null) return
16 | if (!this.isDisposed) this.dispose()
17 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/extend/StringExtensions.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.extend
2 |
3 | import java.text.DecimalFormat
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:1/22/22
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | fun T.isSpace(): Boolean {
12 | if (this == null) return true
13 | var i = 0
14 | val len = length
15 | while (i < len) {
16 | if (!Character.isWhitespace(get(i))) {
17 | return false
18 | }
19 | i++
20 | }
21 | return true
22 | }
23 |
24 | fun Number.formatToMoney(): String? {
25 | return DecimalFormat("#,###.00").format(this)
26 | }
27 |
28 | fun String?.replaceZero(): String? {
29 | if (this == null) return this
30 | var s = this
31 | s.replace("0+?$".toRegex(), "").also { s = it }
32 | s?.replace("[.]$".toRegex(), "").also { s = it }
33 | return s
34 | }
35 | /**
36 | * 判断两个字符是否改变
37 | */
38 | fun CharSequence?.haveContentsChanged(str:CharSequence?):Boolean{
39 | if (this == null != (str == null)) {
40 | return true
41 | } else if (this == null) {
42 | return false
43 | }
44 | val length: Int = this.length
45 | if (length != str?.length) {
46 | return true
47 | }
48 | for (i in 0 until length) {
49 | if (this[i] != str[i]) {
50 | return true
51 | }
52 | }
53 | return false
54 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/extend/ThreadExtensions.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.extend
2 |
3 | import android.os.Handler
4 | import android.os.Looper
5 | import io.reactivex.Observable
6 | import io.reactivex.android.schedulers.AndroidSchedulers
7 | import io.reactivex.disposables.Disposable
8 | import io.reactivex.schedulers.Schedulers
9 | import java.util.concurrent.ExecutorService
10 | import java.util.concurrent.Executors
11 | import java.util.concurrent.TimeUnit
12 |
13 | /**
14 | * author :Peakmain
15 | * createTime:2021/12/23
16 | * mail:2726449200@qq.com
17 | * describe:线程扩展类
18 | */
19 | private val mHandler = Handler(Looper.getMainLooper())
20 |
21 | private val mSingleService: ExecutorService = Executors.newSingleThreadExecutor()
22 |
23 | /**
24 | * 切换到主线程
25 | */
26 | fun T.ktxRunOnUiThread(block: T.() -> Unit) {
27 | mHandler.post {
28 | block()
29 | }
30 | }
31 |
32 | /**
33 | * 延迟delayMills切换到主线程,默认是600ms
34 | */
35 | fun T.ktxRunOnUiThreadDelay(delayMills: Long=600, block: T.() -> Unit) {
36 | mHandler.postDelayed({
37 | block()
38 | }, delayMills)
39 | }
40 |
41 | /**
42 | * 子线程执行
43 | */
44 | fun T.ktxRunOnThreadSingle(block: T.() -> Unit) {
45 | mSingleService.execute {
46 | block()
47 | }
48 | }
49 |
50 | /**
51 | * 延迟加载
52 | */
53 | fun T.wait(delay: Long = 500L, block: T.() -> Unit): Disposable {
54 | return wait(delay, TimeUnit.MILLISECONDS, block)
55 | }
56 | /**
57 | * 延迟加载
58 | */
59 | fun T.wait(delay: Long = 500L, unit: TimeUnit, block: T.() -> Unit): Disposable {
60 | return Observable.timer(delay, unit).subscribeOn(Schedulers.io())
61 | .observeOn(AndroidSchedulers.mainThread()).subscribe { block() }
62 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/extend/ViewExtensions.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.extend
2 |
3 | import android.text.Spanned
4 | import android.view.View
5 | import android.view.animation.CycleInterpolator
6 | import android.view.animation.TranslateAnimation
7 | import android.widget.TextView
8 |
9 | /**
10 | * author :Peakmain
11 | * createTime:2022/1/5
12 | * mail:2726449200@qq.com
13 | * describe:View的扩展
14 | */
15 |
16 |
17 | /**
18 | * View的抖动动画
19 | * @param fromXDelta Change in X coordinate to apply at the start of the
20 | * animation
21 | * @param toXDelta Change in X coordinate to apply at the end of the
22 | * animation
23 | * @param fromYDelta Change in Y coordinate to apply at the start of the
24 | * animation
25 | * @param toYDelta Change in Y coordinate to apply at the end of the
26 | * animation
27 | * @param duration durationMillis Duration in milliseconds
28 | */
29 | fun T.shakeAnimation(
30 | fromXDelta: Float = 0f,
31 | toXDelta: Float = 5f,
32 | fromYDelta: Float = 0f,
33 | toYDelta: Float = 0f,
34 | duration: Long = 500
35 | ) {
36 | TranslateAnimation(fromXDelta, toXDelta, fromYDelta, toYDelta).also {
37 | it.duration = duration
38 | it.interpolator = CycleInterpolator(3f)
39 | startAnimation(it)
40 | }
41 | }
42 |
43 | fun View.visible() {
44 | visibility = View.VISIBLE
45 | }
46 |
47 | fun View.gone() {
48 | visibility = View.GONE
49 | }
50 |
51 | fun View.inVisible() {
52 | visibility = View.INVISIBLE
53 | }
54 |
55 | fun View.setPadding(left: Int, top: Int, right: Int, bottom: Int) {
56 | setPadding(left, top, right, bottom)
57 | }
58 |
59 | fun TextView.setText(text: CharSequence?) {
60 | val oldText = this.text
61 | if (text === oldText || text == null && oldText.isEmpty()) {
62 | return
63 | }
64 | if (text is Spanned) {
65 | if (text == oldText) {
66 | return // No change in the spans, so don't set anything.
67 | }
68 | } else if (!text.haveContentsChanged(oldText)) {
69 | return // No content changes, so don't set anything.
70 | }
71 | this.text = text
72 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/helper/BehaviorHelper.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.helper
2 |
3 | import android.graphics.Color
4 | import android.view.View
5 | import android.view.ViewGroup
6 | import android.widget.FrameLayout
7 | import androidx.annotation.ColorInt
8 | import com.google.android.material.bottomsheet.BottomSheetBehavior
9 | import com.peakmain.basiclibrary.R
10 | import com.peakmain.basiclibrary.interfaces.IBehaviorHelperCallback
11 |
12 | /**
13 | * author :Peakmain
14 | * createTime:2022/11/14
15 | * mail:2726449200@qq.com
16 | * describe:
17 | */
18 | class BehaviorHelper
19 | /**
20 | * @param target 设置阴影的根布局
21 | * @param backgroundColor 阴影背景颜色
22 | * @param peekHeight 折叠的时候 底部显示高度
23 | * @param isHide false 表示用户将能通过向下滑动完全隐藏的BottomSheet ,默认无此状态
24 | * @param isCancelable 点击空白是否可以取消,false表示可以取消,true表示不可取消
25 | */
26 | constructor(
27 | private val target: ViewGroup? = null,
28 | content: ViewGroup? = null,
29 | listener: IBehaviorHelperCallback? = null,
30 | @ColorInt val backgroundColor: Int = Color.parseColor("#66000000"),
31 | peekHeight: Int = 0,
32 | isHide: Boolean = false,
33 | private val isCancelable: Boolean = false
34 | ) {
35 | private var behavior: BottomSheetBehavior? = null
36 |
37 | init {
38 | content?.let {
39 | behavior = BottomSheetBehavior.from(it)
40 | behavior?.isHideable = isHide
41 | behavior?.peekHeight = peekHeight
42 | behavior?.addBottomSheetCallback(object : BottomSheetBehavior.BottomSheetCallback() {
43 | override fun onStateChanged(bottomSheet: View, newState: Int) {
44 | if (newState == BottomSheetBehavior.STATE_COLLAPSED) {
45 | removeShadow()
46 | listener?.close(bottomSheet, newState)
47 | } else if (newState == BottomSheetBehavior.STATE_EXPANDED) {
48 | listener?.open(bottomSheet, newState)
49 | }
50 | }
51 |
52 | override fun onSlide(bottomSheet: View, slideOffset: Float) {
53 | }
54 |
55 | })
56 | }
57 | }
58 |
59 | fun toggle() {
60 | if (behavior?.state == BottomSheetBehavior.STATE_COLLAPSED) {
61 | behavior?.state = BottomSheetBehavior.STATE_EXPANDED
62 | showShadow()
63 | } else {
64 | behavior?.state = BottomSheetBehavior.STATE_COLLAPSED
65 | }
66 | }
67 |
68 | private fun showShadow() {
69 | if (target == null) return
70 | if (target.findViewById(R.id.basic_library_shadow) != null) return
71 | val shadow = FrameLayout(target.context)
72 | shadow.apply {
73 | layoutParams = FrameLayout.LayoutParams(
74 | FrameLayout.LayoutParams.MATCH_PARENT,
75 | FrameLayout.LayoutParams.MATCH_PARENT
76 | )
77 | setBackgroundColor(backgroundColor)
78 | if (!isCancelable) {
79 | setOnClickListener {
80 | target.removeView(this)
81 | behavior?.state = BottomSheetBehavior.STATE_COLLAPSED
82 | }
83 | }
84 | id = R.id.basic_library_shadow
85 | }
86 | target.addView(shadow, 0)
87 | }
88 |
89 | fun removeShadow() {
90 | val shadowFrameLayout = target?.findViewById(R.id.basic_library_shadow) ?: return
91 | target.removeView(shadowFrameLayout)
92 | }
93 |
94 | fun getBehavior(): BottomSheetBehavior? {
95 | return behavior
96 | }
97 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/helper/ImageSelectorHelper.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.helper
2 |
3 | import android.os.Bundle
4 | import androidx.fragment.app.FragmentManager
5 | import com.peakmain.basiclibrary.config.ImageContext
6 | import com.peakmain.basiclibrary.image.PkImageSelector
7 | import com.peakmain.basiclibrary.image.ImageSelectorFragment
8 | import com.peakmain.basiclibrary.config.ImageRequestConfig
9 | import com.peakmain.basiclibrary.constants.ImageSelectConstants
10 |
11 | /**
12 | * author :Peakmain
13 | * createTime:2022/08/18
14 | * mail:2726449200@qq.com
15 | * describe:
16 | */
17 | internal class ImageSelectorHelper private constructor() {
18 | companion object {
19 | val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
20 | ImageSelectorHelper()
21 | }
22 | private val TAG = PkImageSelector::class.simpleName
23 | }
24 |
25 | fun getPictureSelectFragment(
26 | config: ImageRequestConfig,
27 | imageContext: ImageContext
28 | ): ImageSelectorFragment {
29 | val fragmentManager = getFragmentManager(imageContext)
30 | var imageSelectorFragment = findPictureSelectFragment(fragmentManager)
31 | if (imageSelectorFragment == null) {
32 | imageSelectorFragment = ImageSelectorFragment()
33 | val bundle = Bundle()
34 | bundle.putSerializable(ImageSelectConstants.REQUEST_CONFIG, config)
35 | imageSelectorFragment.arguments = bundle
36 |
37 | fragmentManager?.beginTransaction()
38 | ?.add(imageSelectorFragment, TAG)
39 | ?.commitAllowingStateLoss()
40 | } else
41 | initFragmentBundle(config, imageSelectorFragment)
42 |
43 | return imageSelectorFragment
44 | }
45 |
46 | private fun initFragmentBundle(
47 | config: ImageRequestConfig,
48 | imageSelectorFragment: ImageSelectorFragment
49 | ) {
50 | val bundle = Bundle()
51 | bundle.putSerializable(ImageSelectConstants.REQUEST_CONFIG, config)
52 | imageSelectorFragment.arguments = bundle
53 | }
54 |
55 | private fun findPictureSelectFragment(fragmentManager: FragmentManager?): ImageSelectorFragment? {
56 | return fragmentManager?.findFragmentByTag(TAG) as ImageSelectorFragment?
57 | }
58 |
59 |
60 | private fun getFragmentManager(imageContext: ImageContext): FragmentManager? {
61 | return if (imageContext.activity != null) {
62 | imageContext.activity!!.supportFragmentManager
63 | } else if (imageContext.fragment != null) {
64 | imageContext.fragment!!.childFragmentManager
65 | } else {
66 | null
67 | }
68 | }
69 |
70 |
71 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/helper/RetrofitHelper.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.helper
2 |
3 | import android.os.Build
4 | import com.peakmain.basiclibrary.network.HttpDns
5 | import com.peakmain.basiclibrary.network.MyX509
6 | import com.peakmain.basiclibrary.network.status.ApiStatus
7 | import com.peakmain.basiclibrary.network.status.CommonRetrofitData
8 | import okhttp3.OkHttpClient
9 | import okhttp3.logging.HttpLoggingInterceptor
10 | import java.util.concurrent.TimeUnit
11 | import javax.net.ssl.SSLContext
12 | import javax.net.ssl.SSLSocketFactory
13 | import javax.net.ssl.TrustManager
14 | import javax.net.ssl.X509ExtendedTrustManager
15 |
16 | /**
17 | * author :Peakmain
18 | * createTime:2022/08/04
19 | * mail:2726449200@qq.com
20 | * describe:
21 | */
22 | object RetrofitHelper {
23 | //连接超时
24 | private const val CONNECT_TIMEOUT = 60L
25 |
26 | //阅读超时
27 | private const val READ_TIMEOUT = 10L
28 |
29 | //写入超时
30 | private const val WRITE_TIMEOUT = 10L
31 | private const val DNS_TIMEOUT = 5L
32 |
33 | /**
34 | * @param prevBuildOkHttpClient 在构建okHttpClient之前可设置一些参数
35 | */
36 | fun buildOkHttpClient(prevBuildOkHttpClient: ((OkHttpClient.Builder) -> Unit)? = null): OkHttpClient {
37 | val builder = OkHttpClient.Builder()
38 | .connectTimeout(CONNECT_TIMEOUT, TimeUnit.SECONDS)//设置连接超时
39 | .dns(HttpDns(DNS_TIMEOUT, TimeUnit.MILLISECONDS))
40 | .readTimeout(READ_TIMEOUT, TimeUnit.SECONDS)//读取超时
41 | .writeTimeout(WRITE_TIMEOUT, TimeUnit.SECONDS)//写入超时
42 | builder.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))
43 | .hostnameVerifier { _, _ -> true }
44 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
45 | val x509 = MyX509()
46 | builder.sslSocketFactory(getSSLFactory(x509), x509)
47 | }
48 | prevBuildOkHttpClient?.invoke(builder)
49 | return builder.build()
50 | }
51 |
52 | private fun getSSLFactory(x509TrustManager: X509ExtendedTrustManager): SSLSocketFactory {
53 | val trustAllCerts = arrayOf(x509TrustManager)
54 | val sslContext = SSLContext.getInstance("SSL")
55 | sslContext.init(null, trustAllCerts, java.security.SecureRandom())
56 | return sslContext.socketFactory
57 | }
58 |
59 |
60 | fun function2RetrofitData(
61 | before: () -> Unit,
62 | success: T.() -> Unit,
63 | error: (Exception) -> Unit
64 | ): CommonRetrofitData {
65 | return CommonRetrofitData(object : ApiStatus() {
66 | override fun before() {
67 | super.before()
68 | before()
69 | }
70 |
71 | override fun success(t: T) {
72 | success(t)
73 | }
74 |
75 | override fun error(exception: Exception) {
76 | error(exception)
77 | }
78 |
79 | })
80 | }
81 |
82 |
83 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/image/ImageSelectorFragment.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.image
2 |
3 | import android.os.Bundle
4 | import androidx.fragment.app.Fragment
5 | import com.peakmain.basiclibrary.config.ImageRequestConfig
6 | import com.peakmain.basiclibrary.constants.AndroidVersion
7 | import com.peakmain.basiclibrary.constants.ImageSelectConstants
8 | import com.peakmain.basiclibrary.extend.launchImage
9 | import com.peakmain.basiclibrary.image.contract.SelectMultipleContract
10 | import com.peakmain.basiclibrary.image.contract.SelectSinglePhotoContract
11 | import com.peakmain.basiclibrary.image.contract.TakePictureContract
12 | import com.peakmain.basiclibrary.interfaces.OnImageSelectorCallback
13 | import com.peakmain.basiclibrary.viewmodel.ImageSelectViewModel
14 |
15 | /**
16 | * author :Peakmain
17 | * createTime:2022/08/18
18 | * mail:2726449200@qq.com
19 | * describe:
20 | */
21 | internal class ImageSelectorFragment : Fragment() {
22 |
23 | private var mImageSelectViewModel: ImageSelectViewModel = ImageSelectViewModel()
24 | var selectMultipleContract = SelectMultipleContract()
25 | private val mSelectPhotoLauncher =
26 | registerForActivityResult(SelectSinglePhotoContract()) { uri ->
27 | mImageSelectViewModel.registerSingleLauncher(uri)
28 | }
29 |
30 |
31 | private val takePictureLauncher =
32 | registerForActivityResult(TakePictureContract()) {
33 | mImageSelectViewModel.registerTakePicture(it)
34 | }
35 |
36 | private val mSelectMultiPhotoLauncher =
37 | registerForActivityResult(selectMultipleContract) { lists ->
38 | mImageSelectViewModel.registerMultiLauncher(lists)
39 | }
40 |
41 | override fun onCreate(savedInstanceState: Bundle?) {
42 | super.onCreate(savedInstanceState)
43 | mImageSelectViewModel.mStart.observe(
44 | this,
45 | mImageSelectViewModel.imageSelectorObserver( {
46 | mSelectPhotoLauncher.launchImage(mImageSelectViewModel.mConfig)
47 | }, {
48 | mSelectMultiPhotoLauncher.launchImage(mImageSelectViewModel.mConfig)
49 | }) {
50 | takePictureLauncher.launch(null)
51 | }
52 | )
53 | selectMultipleContract.maxNum = mImageSelectViewModel.mConfig?.maxNum ?: 9
54 | }
55 |
56 |
57 | fun start(onImageSelectorCallback: OnImageSelectorCallback?) {
58 | getConfig()
59 | mImageSelectViewModel.mStart.value = true
60 | mImageSelectViewModel.mOnImageSelectorCallback = onImageSelectorCallback
61 | }
62 |
63 | private fun getConfig() {
64 | mImageSelectViewModel.mConfig = if (AndroidVersion.isAndroid13()) {
65 | arguments?.getSerializable(
66 | ImageSelectConstants.REQUEST_CONFIG,
67 | ImageRequestConfig::class.java
68 | )
69 | } else {
70 | arguments?.get(ImageSelectConstants.REQUEST_CONFIG) as ImageRequestConfig?
71 | }
72 | }
73 |
74 | override fun onDestroy() {
75 | super.onDestroy()
76 | mImageSelectViewModel.clearImage()
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/image/PkImageSelector.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.image
2 |
3 | import androidx.fragment.app.Fragment
4 | import androidx.fragment.app.FragmentActivity
5 | import com.peakmain.basiclibrary.config.ImageContext
6 | import com.peakmain.basiclibrary.helper.ImageSelectorHelper
7 | import com.peakmain.basiclibrary.config.ImageRequestConfig
8 | import com.peakmain.basiclibrary.constants.ImageSelectConstants
9 | import com.peakmain.basiclibrary.interfaces.OnImageSelectorCallback
10 |
11 | /**
12 | * author :Peakmain
13 | * createTime:2022/08/18
14 | * mail:2726449200@qq.com
15 | * describe:
16 | */
17 | class PkImageSelector private constructor(mConfig: ImageRequestConfig, imageContext: ImageContext) {
18 | private var mPictureSelectorFragment: ImageSelectorFragment? = null
19 |
20 | init {
21 | mPictureSelectorFragment = ImageSelectorHelper.instance
22 | .getPictureSelectFragment(mConfig, imageContext)
23 | mPictureSelectorFragment?.start(imageContext.onImageSelectorCallback)
24 | }
25 |
26 | companion object {
27 |
28 | fun builder(fragment: Fragment): Builder {
29 | return Builder(fragment)
30 | }
31 |
32 | fun builder(activity: FragmentActivity): Builder {
33 | return Builder(activity)
34 | }
35 |
36 | class Builder private constructor() {
37 | private val mConfig: ImageRequestConfig = ImageRequestConfig()
38 | private val imageContext = ImageContext()
39 |
40 | constructor(activity: FragmentActivity) : this() {
41 | imageContext.activity = activity
42 | }
43 |
44 | constructor(fragment: Fragment) : this() {
45 | imageContext.fragment = fragment
46 | }
47 |
48 |
49 | fun setSingle(isSingle: Boolean): Builder {
50 | mConfig.isSingle = isSingle
51 | return this
52 | }
53 |
54 | /**
55 | * 设置多选最多的数量
56 | * android 13及以上才生效
57 | */
58 | fun setMaxNum(num: Int = 1):Builder {
59 | mConfig.maxNum = num
60 | return this
61 | }
62 |
63 | fun setType(@ImageSelectConstants.ImageSelectType type: Int): Builder {
64 | mConfig.imageType = type
65 | return this
66 | }
67 |
68 | fun forResult(onImageSelectorCallback: OnImageSelectorCallback? = null): PkImageSelector {
69 | imageContext.onImageSelectorCallback = onImageSelectorCallback
70 | return PkImageSelector(mConfig, imageContext)
71 | }
72 |
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/image/SimpleImageSelectorCallback.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.image
2 |
3 | import android.graphics.Bitmap
4 | import com.peakmain.basiclibrary.interfaces.OnImageSelectorCallback
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2022/08/22
9 | * mail:2726449200@qq.com
10 | * describe:接口适配器设计模式
11 | */
12 | abstract class SimpleImageSelectorCallback : OnImageSelectorCallback {
13 | //拍照的空方法
14 | override fun onImageSelect(bitmap: Bitmap?) {
15 |
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/image/contract/SelectMultipleContract.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.image.contract
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.net.Uri
7 | import android.provider.MediaStore
8 | import androidx.activity.result.contract.ActivityResultContract
9 | import com.peakmain.basiclibrary.constants.AndroidVersion
10 |
11 | /**
12 | * author :Peakmain
13 | * createTime:2022/08/18
14 | * mail:2726449200@qq.com
15 | * describe:
16 | */
17 | class SelectMultipleContract(var maxNum: Int = 9) : ActivityResultContract>() {
18 | override fun createIntent(context: Context, input: String): Intent {
19 | val intent = if (AndroidVersion.isAndroid13()) {
20 | Intent(MediaStore.ACTION_PICK_IMAGES)
21 | .putExtra(MediaStore.EXTRA_PICK_IMAGES_MAX, maxNum)
22 | .setType(input)
23 | } else {
24 | Intent(Intent.ACTION_GET_CONTENT)
25 | .addCategory(Intent.CATEGORY_OPENABLE)
26 | .setType(input)
27 | }
28 | if (AndroidVersion.isAndroid4_3()) {
29 | intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
30 | }
31 | return intent
32 |
33 | }
34 |
35 | override fun parseResult(resultCode: Int, intent: Intent?): List {
36 | return if (intent == null || resultCode != Activity.RESULT_OK) {
37 | emptyList()
38 | } else getClipDataUris(intent)
39 | }
40 |
41 | companion object {
42 | fun getClipDataUris(intent: Intent): List {
43 | // Use a LinkedHashSet to maintain any ordering that may be
44 | // present in the ClipData
45 | val resultSet = LinkedHashSet()
46 | if (intent.data != null) {
47 | resultSet.add(intent.data)
48 | }
49 | val clipData = intent.clipData
50 | if (clipData == null && resultSet.isEmpty()) {
51 | return emptyList()
52 | } else if (clipData != null) {
53 | for (i in 0 until clipData.itemCount) {
54 | val uri = clipData.getItemAt(i).uri
55 | if (uri != null) {
56 | resultSet.add(uri)
57 | }
58 | }
59 | }
60 | return ArrayList(resultSet)
61 | }
62 | }
63 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/image/contract/SelectSinglePhotoContract.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.image.contract
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.net.Uri
7 | import androidx.activity.result.contract.ActivityResultContract
8 | import androidx.annotation.CallSuper
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2022/08/18
13 | * mail:2726449200@qq.com
14 | * describe:
15 | */
16 | class SelectSinglePhotoContract : ActivityResultContract() {
17 | @CallSuper
18 | override fun createIntent(context: Context, input: String?): Intent {
19 | return Intent(Intent.ACTION_PICK)
20 | .setType(input)
21 | }
22 |
23 | override fun parseResult(resultCode: Int, intent: Intent?): Uri? {
24 | return if (intent == null || resultCode != Activity.RESULT_OK) null else intent.data
25 | }
26 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/image/contract/TakePictureContract.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.image.contract
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.graphics.Bitmap
7 | import android.net.Uri
8 | import android.provider.MediaStore
9 | import androidx.activity.result.contract.ActivityResultContract
10 | import androidx.annotation.CallSuper
11 |
12 | /**
13 | * author :Peakmain
14 | * createTime:2022/08/18
15 | * mail:2726449200@qq.com
16 | * describe:
17 | */
18 | internal class TakePictureContract : ActivityResultContract>() {
19 |
20 | @CallSuper
21 | override fun createIntent(context: Context, input: Uri?): Intent {
22 | return Intent(MediaStore.ACTION_IMAGE_CAPTURE)
23 | .putExtra(MediaStore.EXTRA_OUTPUT, input)
24 | }
25 |
26 | override fun parseResult(resultCode: Int, intent: Intent?): Pair {
27 | val data=intent?.getParcelableExtra("data")
28 | return (resultCode == Activity.RESULT_OK) to data
29 | }
30 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/interfaces/IBehaviorHelperCallback.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.interfaces
2 |
3 | import android.view.View
4 | import com.google.android.material.bottomsheet.BottomSheetBehavior
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2022/11/14
9 | * mail:2726449200@qq.com
10 | * describe:
11 | */
12 | interface IBehaviorHelperCallback {
13 | fun open(bottomSheet: View?, @BottomSheetBehavior.State newState:Int)
14 | fun close(bottomSheet: View?, @BottomSheetBehavior.State newState:Int)
15 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/interfaces/IPermissionPopupListener.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.interfaces
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2024/11/19
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | interface IPermissionPopupListener {
10 | fun onShowPermissionPopup()
11 | fun onHidePermissionPopup()
12 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/interfaces/IPermissionSetting.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.interfaces
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2022/08/12
9 | * mail:2726449200@qq.com
10 | * describe:
11 | */
12 | internal interface IPermissionSetting {
13 | fun getAppSetting(context:Context): Intent
14 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/interfaces/OnImageSelectorCallback.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.interfaces
2 |
3 | import android.graphics.Bitmap
4 | import android.net.Uri
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2022/08/18
9 | * mail:2726449200@qq.com
10 | * describe:
11 | */
12 | interface OnImageSelectorCallback {
13 | //图片选择的回调
14 | fun onImageSelect(uris: List)
15 | //相机拍照的回调
16 | fun onImageSelect(bitmap: Bitmap?)
17 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/interfaces/OnPermissionCallback.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.interfaces
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/08/11
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | interface OnPermissionCallback {
10 | /**
11 | * 权限被授予时回调
12 | * @param permissions 权限组
13 | */
14 | fun onGranted(permissions: Array)
15 |
16 | /**
17 | * 权限被拒绝的时候回调
18 | * @param permissions 权限组
19 | * @param never 权限是否被永久拒绝
20 | */
21 | fun onDenied(permissions: Array, never: Boolean)
22 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/manager/AnimationManager.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.manager
2 |
3 | import android.animation.Animator
4 | import android.animation.AnimatorListenerAdapter
5 | import android.view.View
6 | import com.peakmain.basiclibrary.config.BasicLibraryConfig
7 |
8 | /**
9 | * author :Peakmain
10 | * createTime:2022/1/27
11 | * mail:2726449200@qq.com
12 | * describe:
13 | */
14 | object AnimationManager {
15 | /**
16 | * 显示淡入淡出动画
17 | */
18 | fun showCrossFadeLoadingView(contentView: View, loadingView: View) {
19 | contentView.visibility = View.GONE
20 | loadingView.visibility = View.VISIBLE
21 | }
22 |
23 | /**
24 | * 隐藏淡入淡出动画
25 | */
26 | fun hideCrossFadeLoadingView(contentView: View, loadingView: View) {
27 | if (BasicLibraryConfig.getInstance()?.getApp()?.getApplication() == null) {
28 | return
29 | }
30 | val animationDuration: Int = BasicLibraryConfig.getInstance()?.getApp()
31 | ?.getApplication()!!.resources.getInteger(android.R.integer.config_shortAnimTime)
32 | contentView.apply {
33 | alpha = 0f
34 | visibility = View.VISIBLE
35 | animate()
36 | .alpha(1f)
37 | .setDuration(animationDuration.toLong())
38 | .setListener(null)
39 | }
40 | loadingView.animate()
41 | .alpha(0f)
42 | .setDuration(animationDuration.toLong())
43 | .setListener(object : AnimatorListenerAdapter() {
44 | override fun onAnimationEnd(animation: Animator) {
45 | loadingView.visibility = View.GONE
46 | }
47 | })
48 | }
49 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/manager/PermissionHandlerManager.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.manager
2 |
3 | import android.os.Handler
4 | import android.os.Looper
5 | import android.os.Message
6 | import com.peakmain.basiclibrary.constants.PermissionMapConstants
7 | import com.peakmain.basiclibrary.interfaces.IPermissionPopupListener
8 |
9 | /**
10 | * author :Peakmain
11 | * createTime:2024/11/19
12 | * mail:2726449200@qq.com
13 | * describe:
14 | */
15 | class PermissionHandlerManager private constructor() {
16 | companion object {
17 | @JvmStatic
18 | val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
19 | PermissionHandlerManager()
20 | }
21 | }
22 |
23 | // 使用弱引用的静态内部 Handler 类,防止内存泄漏
24 | private val mHandler = object : Handler(Looper.getMainLooper()) {}
25 | private val listeners = mutableMapOf>()
26 | private var permission: Array? = null
27 |
28 | // 权限与标签的映射表
29 | fun registerListener(
30 | @PermissionMapConstants.PermissionTag tag: String,
31 | listener: IPermissionPopupListener
32 | ) {
33 | val tagListeners = listeners[tag] ?: mutableListOf()
34 | if (!tagListeners.contains(listener)) {
35 | tagListeners.add(listener)
36 | listeners[tag] = tagListeners
37 | }
38 | }
39 |
40 | // 注销监听器
41 | fun unregisterListener(
42 | @PermissionMapConstants.PermissionTag tag: String,
43 | listener: IPermissionPopupListener
44 | ) {
45 | listeners[tag]?.remove(listener)
46 | if (listeners[tag]?.isEmpty() == true) {
47 | listeners.remove(tag)
48 | }
49 | }
50 |
51 | // 通知显示监听器(遍历所有监听器)
52 | private fun notifyShowListeners(permission: Array) {
53 | // 检查 permission 数组是否为空
54 | if (permission.isEmpty() || listeners.isEmpty()) return
55 |
56 |
57 | // 从映射表获取 tag
58 | val tag = PermissionMapConstants.dangerousPermissionTagMap[permission[0]] ?: return
59 | this.permission = permission
60 | // 安全获取 listeners[tag] 列表
61 | val listenerList = listeners[tag]
62 | if (listenerList.isNullOrEmpty()) return
63 |
64 | // 通知最后一个注册的监听器
65 | listenerList.last().onShowPermissionPopup()
66 | }
67 |
68 | private fun notifyHideListeners() {
69 | if (permission?.isEmpty() == true || listeners.isEmpty()) return
70 | this.permission?.let {
71 | if (it.isEmpty()) return
72 | val tag = PermissionMapConstants.dangerousPermissionTagMap[it[0]] ?: return
73 | val listenerList = listeners[tag]
74 | if (listenerList.isNullOrEmpty()) return
75 |
76 | // 通知最后一个注册的监听器
77 | listenerList.last().onHidePermissionPopup()
78 | }
79 | }
80 |
81 | /**
82 | * 发送延时消息
83 | */
84 | fun sendMessage(permission: Array) {
85 | mHandler.sendMessageDelayed(createMessage {
86 | showPermissionPopup(permission)
87 | }, 100)
88 | }
89 |
90 | /**
91 | * 创建一个消息,封装 Runnable 动作
92 | */
93 | private fun createMessage(action: () -> Unit): Message {
94 | return Message.obtain(this.mHandler) {
95 | action()
96 | }
97 | }
98 |
99 | /**
100 | * 展示权限弹窗说明
101 | */
102 | private fun showPermissionPopup(permission: Array) {
103 | notifyShowListeners(permission)
104 | }
105 |
106 | /**
107 | * 移除所有消息和回调,防止任务继续执行
108 | */
109 | fun removeAllMessages() {
110 | mHandler.removeCallbacksAndMessages(null)
111 | notifyHideListeners()
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/manager/PhoneStateManager.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.manager
2 |
3 | import android.content.Context
4 | import android.os.Build
5 | import android.telephony.PhoneStateListener
6 | import android.telephony.TelephonyCallback
7 | import android.telephony.TelephonyManager
8 | import androidx.annotation.RequiresApi
9 | import com.peakmain.basiclibrary.config.BasicLibraryConfig
10 | import com.peakmain.basiclibrary.constants.AndroidVersion
11 | import com.peakmain.basiclibrary.utils.ThreadUtils
12 | import java.util.concurrent.CopyOnWriteArrayList
13 |
14 | /**
15 | * author :Peakmain
16 | * createTime:1/25/22
17 | * mail:2726449200@qq.com
18 | * describe:电话状态工具类
19 | */
20 | class PhoneStateManager private constructor() {
21 | companion object {
22 | val instance: PhoneStateManager by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
23 | PhoneStateManager()
24 | }
25 | }
26 |
27 | private var mStateCallbacks: MutableList = CopyOnWriteArrayList()
28 | private val phoneStateListener: PhoneStateListener = object : PhoneStateListener() {
29 | override fun onCallStateChanged(state: Int, incomingNumber: String) {
30 | super.onCallStateChanged(state, incomingNumber)
31 | for (callback in mStateCallbacks) {
32 | callback.onPhoneStateCallback(state, incomingNumber)
33 | }
34 | }
35 | }
36 |
37 | @RequiresApi(Build.VERSION_CODES.S)
38 | private class PhoneStateCallBack(stateCallbacks: MutableList) :
39 | TelephonyCallback(), TelephonyCallback.CallStateListener {
40 | private var mStateCallbacks: MutableList = stateCallbacks
41 | override fun onCallStateChanged(state: Int) {
42 | for (callback in mStateCallbacks) {
43 | callback.onPhoneStateCallback(state, "")
44 | }
45 | }
46 |
47 | }
48 |
49 | interface OnPhoneStateCallback {
50 | fun onPhoneStateCallback(state: Int, incomingPhoneNumber: String)
51 | }
52 |
53 | private var telephonyManager: TelephonyManager? = null
54 |
55 |
56 | init {
57 | val application = BasicLibraryConfig.getInstance()?.getApp()?.getApplication()
58 | application?.let {
59 | telephonyManager =
60 | it.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager?
61 | val mainExecutor = ThreadUtils.getMainExecutor() ?: return@let
62 | if (AndroidVersion.isAndroid12()) {
63 | telephonyManager?.registerTelephonyCallback(
64 | mainExecutor,
65 | PhoneStateCallBack(mStateCallbacks)
66 | )
67 | } else {
68 | telephonyManager?.listen(
69 | phoneStateListener,
70 | PhoneStateListener.LISTEN_CALL_STATE
71 | )
72 | }
73 | }
74 |
75 | }
76 |
77 | fun addStateCallback(phoneStateCallback: OnPhoneStateCallback) {
78 | if (!mStateCallbacks.contains(phoneStateCallback)) {
79 | mStateCallbacks.add(phoneStateCallback)
80 | }
81 | }
82 |
83 | fun removeStateCallback(phoneStateCallback: OnPhoneStateCallback) {
84 | if (mStateCallbacks.contains(phoneStateCallback)) {
85 | mStateCallbacks.remove(phoneStateCallback)
86 | }
87 | }
88 |
89 |
90 | @Throws(Throwable::class)
91 | protected fun finalize() {
92 | telephonyManager?.let {
93 | if (AndroidVersion.isAndroid12()) {
94 | it.unregisterTelephonyCallback(
95 | PhoneStateCallBack(mStateCallbacks)
96 | )
97 | } else {
98 | it.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)
99 | }
100 | }
101 | }
102 |
103 |
104 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/network/HttpDns.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.network
2 |
3 | import android.os.Build
4 | import com.qiniu.android.dns.DnsManager
5 | import com.qiniu.android.dns.IResolver
6 | import com.qiniu.android.dns.NetworkInfo
7 | import com.qiniu.android.dns.local.Resolver
8 | import okhttp3.Dns
9 | import java.net.InetAddress
10 | import java.net.InterfaceAddress
11 | import java.net.UnknownHostException
12 | import java.util.*
13 | import java.util.concurrent.Callable
14 | import java.util.concurrent.CompletableFuture
15 | import java.util.concurrent.FutureTask
16 | import java.util.concurrent.TimeUnit
17 | import kotlin.collections.ArrayList
18 |
19 | /**
20 | * author :Peakmain
21 | * createTime:2023/06/15
22 | * mail:2726449200@qq.com
23 | * describe:
24 | */
25 | class HttpDns constructor(val timeout: Long, val unit: TimeUnit) : Dns {
26 | private val mDnsManager: DnsManager
27 |
28 | init {
29 | val resolver = InetAddress.getByName("119.29.29.29")
30 | val resolvers = arrayOf(Resolver(resolver))
31 | mDnsManager = DnsManager(NetworkInfo.normal, resolvers)
32 | }
33 |
34 | override fun lookup(hostname: String): MutableList {
35 | val future = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
36 | CompletableFuture.supplyAsync {
37 | val ips = mDnsManager.query(hostname)
38 | if (ips == null || ips.isEmpty()) return@supplyAsync Dns.SYSTEM.lookup(hostname)
39 | val result = ArrayList()
40 | for (ip in ips) {
41 | try {
42 | result.add(InetAddress.getByName(ip))
43 | } catch (e: UnknownHostException) {
44 | e.printStackTrace()
45 | }
46 | }
47 | return@supplyAsync result
48 | }
49 | } else {
50 | FutureTask(object : Callable> {
51 | override fun call(): List {
52 | val ips = mDnsManager.query(hostname)
53 | if (ips == null || ips.isEmpty()) return Dns.SYSTEM.lookup(hostname)
54 | val result = ArrayList()
55 | for (ip in ips) {
56 | try {
57 | result.add(InetAddress.getByName(ip))
58 | } catch (e: UnknownHostException) {
59 | e.printStackTrace()
60 | }
61 | }
62 | return result
63 | }
64 | })
65 | }
66 | return try {
67 | future.get(timeout, unit).toMutableList()
68 | } catch (e: Exception) {
69 | Dns.SYSTEM.lookup(hostname).toMutableList()
70 | }
71 |
72 | }
73 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/network/MyX509.java:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.network;
2 |
3 | import android.annotation.SuppressLint;
4 | import android.os.Build;
5 |
6 | import androidx.annotation.RequiresApi;
7 |
8 | import java.net.Socket;
9 | import java.security.cert.CertificateException;
10 | import java.security.cert.X509Certificate;
11 |
12 | import javax.net.ssl.SSLEngine;
13 | import javax.net.ssl.X509ExtendedTrustManager;
14 |
15 |
16 | /**
17 | * author :Peakmain
18 | * createTime:2021/12/23
19 | * mail:2726449200@qq.com
20 | * describe:
21 | */
22 | @RequiresApi(api = Build.VERSION_CODES.N)
23 | public class MyX509 extends X509ExtendedTrustManager {
24 |
25 | @SuppressLint("TrustAllX509TrustManager")
26 | @Override
27 | public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) throws CertificateException {
28 |
29 | }
30 |
31 | @SuppressLint("TrustAllX509TrustManager")
32 | @Override
33 | public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) {
34 |
35 | }
36 |
37 | @SuppressLint("TrustAllX509TrustManager")
38 | @Override
39 | public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {
40 |
41 | }
42 |
43 | @SuppressLint("TrustAllX509TrustManager")
44 | @Override
45 | public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) throws CertificateException {
46 |
47 | }
48 |
49 | @SuppressLint("TrustAllX509TrustManager")
50 | @Override
51 | public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
52 |
53 | }
54 |
55 | @SuppressLint("TrustAllX509TrustManager")
56 | @Override
57 | public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
58 |
59 | }
60 |
61 | @Override
62 | public X509Certificate[] getAcceptedIssuers() {
63 | return new X509Certificate[0];
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/network/RetrofitManager.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.network
2 |
3 | import android.text.TextUtils
4 | import com.peakmain.basiclibrary.network.status.AbstractRetrofitData
5 | import com.peakmain.basiclibrary.network.status.ApiStatus
6 | import com.peakmain.basiclibrary.network.status.CommonRetrofitData
7 | import com.peakmain.basiclibrary.network.strategy.CommonRetrofitStrategy
8 | import com.peakmain.basiclibrary.network.strategy.IRetrofitStrategy
9 | import com.peakmain.basiclibrary.helper.RetrofitHelper
10 | import io.reactivex.Observable
11 | import io.reactivex.disposables.Disposable
12 | import java.lang.NullPointerException
13 |
14 | /**
15 | * author :Peakmain
16 | * createTime:2021/12/23
17 | * mail:2726449200@qq.com
18 | * describe:Retrofit的管理类
19 | */
20 | class RetrofitManager {
21 | companion object {
22 | private var mStrategy: IRetrofitStrategy = CommonRetrofitStrategy()
23 | private var mBaseUrl: String? = null
24 |
25 | fun setBaseUrl(baseUrl: String?): Companion {
26 | this.mBaseUrl = baseUrl
27 | return this
28 | }
29 |
30 | fun executeStrategy(strategy: IRetrofitStrategy) {
31 | this.mStrategy = strategy
32 | }
33 |
34 | fun createService(service: Class, block: (service: Class) -> T): T {
35 | return block(service)
36 | }
37 |
38 | fun createService(service: Class):T {
39 | if(TextUtils.isEmpty(mBaseUrl)){
40 | throw NullPointerException("baseurl must not be null")
41 | }
42 | return createService(service, mBaseUrl!!)
43 | }
44 |
45 | fun createService(service: Class, baseUrl: String): T {
46 | return mStrategy.createService(service, baseUrl)
47 | }
48 |
49 | fun createData(
50 | observable: Observable,
51 | retrofitData: AbstractRetrofitData
52 | ): Disposable {
53 | return retrofitData.createData(observable)
54 | }
55 |
56 | fun createData(
57 | observable: Observable,
58 | apiStatus: ApiStatus,
59 | retrofitData: AbstractRetrofitData = CommonRetrofitData(apiStatus)
60 | ): Disposable {
61 | return retrofitData.createData(observable)
62 | }
63 |
64 | fun createData(
65 | observable: Observable,
66 | before: () -> Unit,
67 | success: T.() -> Unit,
68 | error: (Exception) -> Unit = {},
69 | retrofitData: AbstractRetrofitData? = null
70 | ): Disposable {
71 | if (retrofitData == null) {
72 | val tempRetrofitData = RetrofitHelper.function2RetrofitData(before, success, error)
73 | return tempRetrofitData.createData(observable)
74 | }
75 | return retrofitData.createData(observable)
76 | }
77 |
78 |
79 | }
80 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/network/entity/BaseEntity.java:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.network.entity;
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2021/12/23
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | public class BaseEntity {
10 | private int result;
11 | private String detail;
12 | private T data;
13 |
14 | public String getDetail() {
15 | return detail;
16 | }
17 |
18 | public void setDetail(String detail) {
19 | this.detail = detail;
20 | }
21 |
22 | public T getData() {
23 | return data;
24 | }
25 |
26 | public void setData(T data) {
27 | this.data = data;
28 | }
29 |
30 | public int getResult() {
31 | return result;
32 | }
33 |
34 | public void setResult(int result) {
35 | this.result = result;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/network/error/ErrorEnum.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.network.error
2 |
3 | import androidx.annotation.IntDef
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2021/12/23
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | class ErrorEnum{
12 | companion object{
13 | const val SUCCESS=0
14 | const val TOKEN_ERROR=401
15 | }
16 | @IntDef(value=[SUCCESS,TOKEN_ERROR])
17 | @Retention(AnnotationRetention.SOURCE)
18 | annotation class Error
19 |
20 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/network/status/AbstractRetrofitData.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.network.status
2 |
3 | import io.reactivex.Observable
4 | import io.reactivex.android.schedulers.AndroidSchedulers
5 | import io.reactivex.disposables.Disposable
6 | import io.reactivex.schedulers.Schedulers
7 |
8 | /**
9 | * author :Peakmain
10 | * createTime:2022/08/02
11 | * mail:2726449200@qq.com
12 | * describe:
13 | */
14 | abstract class AbstractRetrofitData(apiStatus: BaseApiStatus) {
15 | protected var mBaseApiStatus: BaseApiStatus = apiStatus
16 | abstract fun createData(
17 | observable: Observable
18 | ): Disposable
19 |
20 | open fun createData(
21 | observable: Observable,
22 | before: () -> Unit,
23 | success: T.() -> Unit,
24 | error: (Exception) -> Unit = {}
25 | ): Disposable {
26 | before()
27 | return observable.subscribeOn(Schedulers.io())
28 | .observeOn(AndroidSchedulers.mainThread()).subscribe({ t ->
29 | success(t)
30 | }, { throwable ->
31 | error(Exception(throwable))
32 | })
33 | }
34 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/network/status/ApiStatus.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.network.status
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2021/12/23
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | abstract class ApiStatus:BaseApiStatus{
10 | override fun before() {
11 | }
12 | override fun isEmpty() {
13 | }
14 |
15 | override fun loadMore(t: T, isRefresh: Boolean) {
16 | }
17 |
18 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/network/status/BaseApiStatus.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.network.status
2 |
3 | import java.lang.Exception
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2021/12/23
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | interface BaseApiStatus {
12 | fun before()
13 |
14 | fun success(t: T)
15 |
16 | fun isEmpty()
17 |
18 | fun loadMore(t: T, isRefresh: Boolean)
19 |
20 | fun error(exception: Exception)
21 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/network/status/CommonRetrofitData.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.network.status
2 |
3 | import io.reactivex.Observable
4 | import io.reactivex.android.schedulers.AndroidSchedulers
5 | import io.reactivex.disposables.Disposable
6 | import io.reactivex.schedulers.Schedulers
7 |
8 | /**
9 | * author :Peakmain
10 | * createTime:2022/08/02
11 | * mail:2726449200@qq.com
12 | * describe:
13 | */
14 | class CommonRetrofitData(private val apiStatus: ApiStatus) :
15 | AbstractRetrofitData(apiStatus) {
16 |
17 | override fun createData(observable: Observable): Disposable {
18 | apiStatus.before()
19 | return observable.subscribeOn(Schedulers.io())
20 | .observeOn(AndroidSchedulers.mainThread()).subscribe({ t ->
21 | apiStatus.success(t)
22 | }, { exception ->
23 | exception.printStackTrace()
24 | apiStatus.error(Exception(exception))
25 | })
26 | }
27 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/network/strategy/CommonRetrofitStrategy.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.network.strategy
2 |
3 | import com.peakmain.basiclibrary.helper.RetrofitHelper.buildOkHttpClient
4 | import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
5 | import retrofit2.converter.gson.GsonConverterFactory
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2022/08/02
10 | * mail:2726449200@qq.com
11 | * describe:
12 | */
13 | class CommonRetrofitStrategy : IRetrofitStrategy {
14 | override fun createService(service: Class, baseUrl: String): T {
15 | val retrofit = retrofit2.Retrofit.Builder().baseUrl(baseUrl)
16 | .client(buildOkHttpClient())
17 | .addConverterFactory(GsonConverterFactory.create())
18 | .addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build()
19 | return retrofit.create(service)
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/network/strategy/IRetrofitStrategy.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.network.strategy
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/08/02
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | interface IRetrofitStrategy {
10 | fun createService(service: Class, baseUrl: String): T
11 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/PermissionSettingFactory.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import com.peakmain.basiclibrary.permission.setting.DefaultPermissionSetting
6 | import com.peakmain.basiclibrary.permission.setting.NotificationPermissionSetting
7 |
8 |
9 | /**
10 | * author :Peakmain
11 | * createTime:2022/08/12
12 | * mail:2726449200@qq.com
13 | * describe:
14 | */
15 | internal object PermissionSettingFactory {
16 | /**
17 | * Build.MANUFACTURER
18 | */
19 | private const val MANUFACTURER_HUAWEI = "HUAWEI" //华为
20 |
21 | private const val MANUFACTURER_MEIZU = "Meizu" //魅族
22 |
23 | private const val MANUFACTURER_XIAOMI = "Xiaomi" //小米
24 |
25 | private const val MANUFACTURER_SONY = "Sony" //索尼
26 |
27 | private const val MANUFACTURER_OPPO = "OPPO" //oppo
28 |
29 | private const val MANUFACTURER_LG = "LG"
30 |
31 | private const val MANUFACTURER_VIVO = "vivo" //vivo
32 |
33 | fun toAppSetting(context: Context?) {
34 | toAppSetting(context, false)
35 | }
36 |
37 | /**
38 | * @param isNotification 是否跳转系统的消息通知,true则表示想要跳转消息通知
39 | */
40 | fun toAppSetting(context: Context?, isNotification: Boolean) {
41 | if (context == null) return
42 | if (!isNotification) {
43 | context.startActivity(getAppSettingIntent(context))
44 | return
45 | }
46 | context.startActivity(NotificationPermissionSetting().getAppSetting(context))
47 | }
48 |
49 | fun getAppSettingIntent(context: Context): Intent {
50 | /* return when (Build.MANUFACTURER) {
51 | MANUFACTURER_HUAWEI -> HuaWeiPermissionSetting().getAppSetting(context)
52 | MANUFACTURER_MEIZU -> MeiZuPermissionSetting().getAppSetting(context)
53 | MANUFACTURER_XIAOMI -> XiaomiPermissionSetting().getAppSetting(context)
54 | MANUFACTURER_SONY -> SonyPermissionSetting().getAppSetting(context)
55 | MANUFACTURER_OPPO -> OPPOPermissionSetting().getAppSetting(context)
56 | MANUFACTURER_VIVO -> VIVOPermissionSetting().getAppSetting(context)
57 | MANUFACTURER_LG -> LGPermissionSetting().getAppSetting(context)
58 | else -> DefaultPermissionSetting().getAppSetting(context)
59 | }*/
60 | return DefaultPermissionSetting().getAppSetting(context)
61 | }
62 |
63 |
64 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/PkPermissionFragment.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission
2 |
3 | import android.Manifest
4 | import android.os.Bundle
5 | import androidx.activity.result.contract.ActivityResultContracts
6 | import androidx.fragment.app.Fragment
7 | import com.peakmain.basiclibrary.constants.AndroidVersion
8 | import com.peakmain.basiclibrary.helper.PermissionHelper
9 | import com.peakmain.basiclibrary.interfaces.OnPermissionCallback
10 | import com.peakmain.basiclibrary.viewmodel.PkPermissionViewModel
11 |
12 |
13 | /**
14 | * author :Peakmain
15 | * createTime:2022/08/11
16 | * mail:2726449200@qq.com
17 | * describe:
18 | */
19 | internal class PkPermissionFragment : Fragment() {
20 |
21 | private val mViewModel = PkPermissionViewModel()
22 | private var mSinglePermissionLauncher =
23 | registerForActivityResult(RequestPermissionContract()) {
24 | mViewModel.registerSingleForActivityResult(
25 | it,
26 | shouldShowRequestPermissionRationale(it.first)
27 | )
28 | }
29 | private val mMultiPermissionLauncher =
30 | registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
31 | mViewModel.registerMultiForActivityResult(it, { permission ->
32 | shouldShowRequestPermissionRationale(permission)
33 | }) {
34 | requestPermission(
35 | Manifest.permission.ACCESS_BACKGROUND_LOCATION,
36 | mViewModel.mOnPermissionCallback
37 | )
38 | }
39 |
40 | }
41 |
42 | /**
43 | * 是否授予了某个权限
44 | */
45 | fun isGranted(permission: String): Boolean {
46 | return PermissionHelper.instance.isGranted(permission)
47 | }
48 |
49 | fun isGranted(permissions: Array): Boolean {
50 | return PermissionHelper.instance.isGranted(permissions)
51 | }
52 |
53 |
54 | fun isRevoked(permission: String): Boolean {
55 | val fragmentActivity = activity ?: return false
56 | return !AndroidVersion.isAndroid6() || fragmentActivity.packageManager.isPermissionRevokedByPolicy(
57 | permission,
58 | fragmentActivity.packageName
59 | )
60 | }
61 |
62 | override fun onCreate(savedInstanceState: Bundle?) {
63 | super.onCreate(savedInstanceState)
64 | mViewModel.mOnPermissionCallbackLiveData.observe(this,
65 | mViewModel.requestPermissionObserver(
66 | mSinglePermissionLauncher,
67 | mMultiPermissionLauncher
68 | ) {
69 | mViewModel.sBackgroundLocationPermission = true
70 | }
71 | )
72 | }
73 |
74 | fun requestPermission(permission: String, block: OnPermissionCallback?) {
75 | mViewModel.mOnPermissionCallback = block
76 | mViewModel.mOnPermissionCallbackLiveData.value = arrayOf(permission) to block
77 | }
78 |
79 | /**
80 | * 申请权限
81 | */
82 | fun requestPermissions(permissions: Array, block: OnPermissionCallback) {
83 | mViewModel.mOnPermissionCallback = block
84 | mViewModel.mOnPermissionCallbackLiveData.value = permissions to block
85 | }
86 |
87 | override fun onDestroy() {
88 | super.onDestroy()
89 | mViewModel.clearData()
90 | }
91 |
92 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/RequestPermissionContract.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission
2 |
3 | import android.app.Activity
4 | import android.content.Context
5 | import android.content.Intent
6 | import android.content.pm.PackageManager
7 | import androidx.activity.result.contract.ActivityResultContract
8 | import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
9 | import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions.Companion.ACTION_REQUEST_PERMISSIONS
10 | import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions.Companion.EXTRA_PERMISSIONS
11 | import com.peakmain.basiclibrary.helper.PermissionHelper
12 |
13 | /**
14 | * author :Peakmain
15 | * createTime:2022/08/15
16 | * mail:2726449200@qq.com
17 | * describe:
18 | */
19 | class RequestPermissionContract : ActivityResultContract>() {
20 | private var mPermission: String = ""
21 | override fun createIntent(context: Context, input: String): Intent {
22 | mPermission = input
23 | return Intent(ACTION_REQUEST_PERMISSIONS).putExtra(EXTRA_PERMISSIONS, arrayOf(input))
24 | }
25 |
26 | override fun parseResult(resultCode: Int, intent: Intent?): Pair {
27 | if (intent == null || resultCode != Activity.RESULT_OK) return mPermission to false
28 | val grantResults =
29 | intent.getIntArrayExtra(RequestMultiplePermissions.EXTRA_PERMISSION_GRANT_RESULTS)
30 | return mPermission to
31 | if (grantResults == null || grantResults.isEmpty()) false
32 | else grantResults[0] == PackageManager.PERMISSION_GRANTED
33 | }
34 |
35 | override fun getSynchronousResult(
36 | context: Context,
37 | input: String
38 | ): SynchronousResult>? = when {
39 | PermissionHelper.instance.isGranted(input) -> SynchronousResult(input to true)
40 | else -> null
41 | }
42 |
43 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/interfaces/ICall.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.interfaces
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/10/31
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | interface ICall: Cloneable {
10 | fun call()
11 |
12 | override fun clone():ICall
13 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/interfaces/IPermissionVersion.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.interfaces
2 |
3 | import com.peakmain.basiclibrary.permission.version.PermissionRequest
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2022/10/31
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | interface IPermissionVersion {
12 | fun permissionVersion(chain: Chain): IPermissionVersion?
13 | interface Chain {
14 | fun request(): PermissionRequest
15 | fun proceed(request: PermissionRequest): IPermissionVersion
16 | }
17 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/setting/DefaultPermissionSetting.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.setting
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.net.Uri
6 | import android.provider.Settings
7 | import com.peakmain.basiclibrary.interfaces.IPermissionSetting
8 |
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2022/08/12
13 | * mail:2726449200@qq.com
14 | * describe:
15 | */
16 | internal class DefaultPermissionSetting : IPermissionSetting {
17 | override fun getAppSetting(context: Context): Intent {
18 | try {
19 | val intent = Intent()
20 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
21 | intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
22 | intent.data = Uri.fromParts("package", context.packageName, null)
23 | return intent
24 | } catch (e: Exception) {
25 | e.printStackTrace()
26 | }
27 | //系统设置权限
28 | return Intent(Settings.ACTION_SETTINGS)
29 | }
30 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/setting/NotificationPermissionSetting.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.setting
2 |
3 | import android.content.Context
4 | import android.content.Intent
5 | import android.provider.Settings
6 | import com.peakmain.basiclibrary.constants.AndroidVersion
7 | import com.peakmain.basiclibrary.interfaces.IPermissionSetting
8 |
9 | /**
10 | * author :Peakmain
11 | * createTime:2022/10/25
12 | * mail:2726449200@qq.com
13 | * describe:android 13消息通知设置界面
14 | */
15 | class NotificationPermissionSetting : IPermissionSetting {
16 | override fun getAppSetting(context: Context): Intent {
17 | if (AndroidVersion.isAndroid13()) {
18 | val applicationInfo = context.applicationInfo
19 | try {
20 | val intent = Intent()
21 | intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
22 | intent.action = Settings.ACTION_APP_NOTIFICATION_SETTINGS
23 | intent.putExtra("app_package", applicationInfo.packageName)
24 | intent.putExtra(Settings.EXTRA_APP_PACKAGE, applicationInfo.packageName)
25 | intent.putExtra("app_uid", applicationInfo.uid)
26 | return intent
27 | } catch (t: Throwable) {
28 | t.printStackTrace()
29 | }
30 | }
31 | return DefaultPermissionSetting().getAppSetting(context)
32 | }
33 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/version/AndroidOtherPermissionVersion.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.version
2 |
3 | import android.Manifest
4 | import androidx.activity.result.ActivityResultLauncher
5 | import com.peakmain.basiclibrary.constants.AndroidVersion
6 | import com.peakmain.basiclibrary.extend.launchMulti
7 | import com.peakmain.basiclibrary.manager.PermissionHandlerManager
8 | import com.peakmain.basiclibrary.permission.interfaces.IPermissionVersion
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2022/10/31
13 | * mail:2726449200@qq.com
14 | * describe:
15 | */
16 | class AndroidOtherPermissionVersion(
17 | private val launcher: ActivityResultLauncher>,
18 | private val permissions: Array,
19 | private val block: (() -> Unit)? = null
20 | ) :
21 | IPermissionVersion {
22 | override fun permissionVersion(chain: IPermissionVersion.Chain): IPermissionVersion {
23 | val request = chain.request()
24 | val permissionList = request.permissionList
25 | if (!permissionList.contains(Manifest.permission.ACCESS_BACKGROUND_LOCATION)) {
26 | PermissionHandlerManager.instance.sendMessage(permissionList.toTypedArray())
27 | launcher.launch(permissions)
28 | return this
29 | }
30 | if (permissionList.contains(Manifest.permission.ACCESS_COARSE_LOCATION)
31 | && !permissionList.contains(Manifest.permission.ACCESS_FINE_LOCATION)
32 | ) {
33 | permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION)
34 | }
35 | //后台定位权限不要和其他权限一起申请
36 | for (permission in permissions) {
37 | if (permission != Manifest.permission.ACCESS_FINE_LOCATION || permission != Manifest.permission.ACCESS_COARSE_LOCATION || permission == Manifest.permission.ACCESS_BACKGROUND_LOCATION) {
38 | continue
39 | }
40 | throw IllegalArgumentException("因为有background location 权限, 请不要申请与位置无关的权限!!")
41 | }
42 | if (AndroidVersion.isAndroid10() && permissionList.size >= 2) {
43 | permissionList.remove(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
44 | PermissionHandlerManager.instance.sendMessage(permissionList.toTypedArray())
45 | launcher.launchMulti(permissionList.toTypedArray())
46 | block?.invoke()
47 | return this
48 | }
49 | PermissionHandlerManager.instance.sendMessage(permissionList.toTypedArray())
50 | launcher.launch(permissions)
51 | return this
52 | }
53 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/version/AndroidPermissionVersionImpl29.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.version
2 |
3 | import android.Manifest
4 | import android.os.Build
5 | import android.os.Environment
6 | import androidx.activity.result.ActivityResultLauncher
7 | import com.peakmain.basiclibrary.constants.AndroidVersion
8 | import com.peakmain.basiclibrary.permission.interfaces.IPermissionVersion
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2022/10/31
13 | * mail:2726449200@qq.com
14 | * describe:android 10
15 | */
16 | class AndroidPermissionVersionImpl29(
17 | ) : IPermissionVersion {
18 | override fun permissionVersion(chain: IPermissionVersion.Chain): IPermissionVersion? {
19 | val request = chain.request()
20 | if (Build.VERSION.SDK_INT == AndroidVersion.ANDROID_10) {
21 | val permissionList = request.permissionList
22 | if (permissionList.contains(Manifest.permission.MANAGE_EXTERNAL_STORAGE)
23 | && !Environment.isExternalStorageLegacy()
24 | ) {
25 | //有MANAGE_EXTERNAL_STORAGE权限,必须设置 android:requestLegacyExternalStorage="true"
26 | throw IllegalArgumentException("Application中必须设置android:requestLegacyExternalStorage=\"true\"")
27 | }
28 | }
29 | return chain.proceed(request)
30 | }
31 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/version/AndroidPermissionVersionImpl30.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.version
2 |
3 | import android.Manifest
4 | import androidx.activity.result.ActivityResultLauncher
5 | import com.peakmain.basiclibrary.constants.AndroidVersion
6 | import com.peakmain.basiclibrary.manager.PermissionHandlerManager
7 | import com.peakmain.basiclibrary.permission.interfaces.IPermissionVersion
8 |
9 | /**
10 | * author :Peakmain
11 | * createTime:2022/10/31
12 | * mail:2726449200@qq.com
13 | * describe:android 11
14 | */
15 | class AndroidPermissionVersionImpl30(
16 | private val launcher: ActivityResultLauncher>,
17 | private val permissions: Array
18 | ) : IPermissionVersion {
19 | override fun permissionVersion(chain: IPermissionVersion.Chain): IPermissionVersion? {
20 | val request = chain.request()
21 | if (AndroidVersion.isAndroid11()) {
22 | val permissionList = request.permissionList
23 | if (permissionList.contains(Manifest.permission.MANAGE_EXTERNAL_STORAGE)) {
24 | PermissionHandlerManager.instance.sendMessage(permissionList.toTypedArray())
25 | launcher.launch(permissions)
26 | return this
27 | }
28 | }
29 | return chain.proceed(request)
30 | }
31 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/version/AndroidPermissionVersionImpl31.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.version
2 |
3 | import android.Manifest
4 | import androidx.activity.result.ActivityResultLauncher
5 | import com.peakmain.basiclibrary.constants.AndroidVersion
6 | import com.peakmain.basiclibrary.manager.PermissionHandlerManager
7 | import com.peakmain.basiclibrary.permission.PkPermission
8 | import com.peakmain.basiclibrary.permission.interfaces.IPermissionVersion
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2022/10/31
13 | * mail:2726449200@qq.com
14 | * describe:android 12 权限处理
15 | */
16 | class AndroidPermissionVersionImpl31(
17 | private val launcher: ActivityResultLauncher>,
18 | private val permissions: Array
19 | ) :
20 | IPermissionVersion {
21 | override fun permissionVersion(chain: IPermissionVersion.Chain): IPermissionVersion {
22 | val request = chain.request()
23 | if (AndroidVersion.isAndroid12()) {
24 | val permissionList = request.permissionList
25 | if (permissionList.contains(Manifest.permission.ACCESS_FINE_LOCATION) &&
26 | !permissionList.contains(Manifest.permission.ACCESS_COARSE_LOCATION) && !PkPermission.isGranted(
27 | Manifest.permission.ACCESS_COARSE_LOCATION
28 | )
29 | ) {
30 | //Android 12必须添加ACCESS_COARSE_LOCATION
31 | //官方适配文档:https://developer.android.google.cn/about/versions/12/approximate-location
32 | throw IllegalArgumentException(
33 | "在android 12或更高的版本中,请勿单独请求ACCESS_FINE_LOCATION权限," +
34 | "而应在单个运行时请求中同时请求ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION权限。"
35 | )
36 | }
37 | if (permissionList.contains(Manifest.permission.BLUETOOTH_SCAN)
38 | || permissionList.contains(Manifest.permission.BLUETOOTH_CONNECT)
39 | || permissionList.contains(Manifest.permission.BLUETOOTH_ADVERTISE)
40 | ) {
41 | PermissionHandlerManager.instance.sendMessage(permissionList.toTypedArray())
42 | launcher.launch(permissions)
43 | return this
44 | }
45 | }
46 | return chain.proceed(request)
47 | }
48 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/version/AndroidPermissionVersionImpl33.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.version
2 |
3 | import android.Manifest
4 | import androidx.activity.result.ActivityResultLauncher
5 | import com.peakmain.basiclibrary.constants.AndroidVersion
6 | import com.peakmain.basiclibrary.manager.PermissionHandlerManager
7 | import com.peakmain.basiclibrary.permission.interfaces.IPermissionVersion
8 |
9 | /**
10 | * author :Peakmain
11 | * createTime:2022/11/01
12 | * mail:2726449200@qq.com
13 | * describe:android 13权限
14 | */
15 | class AndroidPermissionVersionImpl33(
16 | private val launcher: ActivityResultLauncher>,
17 | private val permissions: Array
18 | ) :
19 | IPermissionVersion {
20 | override fun permissionVersion(chain: IPermissionVersion.Chain): IPermissionVersion? {
21 | val request = chain.request()
22 | if (AndroidVersion.isAndroid13()) {
23 | val permissionList = request.permissionList
24 | if (permissionList.contains(Manifest.permission.POST_NOTIFICATIONS)
25 | || permissionList.contains(Manifest.permission.READ_MEDIA_IMAGES)
26 | || permissionList.contains(Manifest.permission.READ_MEDIA_AUDIO)
27 | || permissionList.contains(Manifest.permission.READ_MEDIA_VIDEO)
28 | || permissionList.contains(Manifest.permission.NEARBY_WIFI_DEVICES)
29 | ) {
30 | PermissionHandlerManager.instance.sendMessage(permissionList.toTypedArray())
31 | launcher.launch(permissions)
32 | return this
33 | }
34 | }
35 | return chain.proceed(request)
36 | }
37 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/version/PermissionRequest.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.version
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:2022/10/31
6 | * mail:2726449200@qq.com
7 | * describe:权限的实体类
8 | */
9 | class PermissionRequest constructor(var permissionList: MutableList) {
10 |
11 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/version/RealPermissionVersionCall.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.version
2 |
3 | import androidx.activity.result.ActivityResultLauncher
4 | import com.peakmain.basiclibrary.permission.interfaces.ICall
5 | import com.peakmain.basiclibrary.permission.interfaces.IPermissionVersion
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2022/10/31
10 | * mail:2726449200@qq.com
11 | * describe:
12 | */
13 | class RealPermissionVersionCall(
14 | private val permissions: Array,
15 | private val launcher: ActivityResultLauncher>,
16 | val block: (() -> Unit)? = null
17 | ) : ICall {
18 |
19 | override fun call() {
20 | val permissionVersionList = ArrayList()
21 | permissionVersionList.add(AndroidPermissionVersionImpl33(launcher, permissions))
22 | permissionVersionList.add(AndroidPermissionVersionImpl31(launcher, permissions))
23 | permissionVersionList.add(AndroidPermissionVersionImpl30(launcher, permissions))
24 | permissionVersionList.add(AndroidPermissionVersionImpl29())
25 | permissionVersionList.add(AndroidOtherPermissionVersion(launcher, permissions, block))
26 | val permissionRequest = PermissionRequest(permissions.toMutableList())
27 | val realPermissionVersionChain = RealPermissionVersionChain(
28 | permissionVersionList, 0,
29 | permissionRequest
30 | )
31 | realPermissionVersionChain.proceed(permissionRequest)
32 | }
33 |
34 | override fun clone(): RealPermissionVersionCall {
35 | return RealPermissionVersionCall(permissions, launcher, block)
36 | }
37 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/permission/version/RealPermissionVersionChain.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.permission.version
2 |
3 | import com.peakmain.basiclibrary.permission.interfaces.IPermissionVersion
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2022/10/31
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | class RealPermissionVersionChain(
12 | private val permissionVersionList: MutableList,
13 | private val index: Int,
14 | val request: PermissionRequest
15 | ) : IPermissionVersion.Chain {
16 |
17 | override fun request(): PermissionRequest {
18 | return request
19 | }
20 |
21 | override fun proceed(request: PermissionRequest): IPermissionVersion {
22 | if (index >= permissionVersionList.size) throw AssertionError()
23 | val realPermissionVersionChain =
24 | RealPermissionVersionChain(permissionVersionList, index + 1, request)
25 | val iPermissionVersion = permissionVersionList[index]
26 | return iPermissionVersion.permissionVersion(realPermissionVersionChain)
27 | ?: throw NullPointerException("permissionVersion returned null")
28 | }
29 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/ArithmeticUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils
2 |
3 | import android.text.TextUtils
4 | import java.math.BigDecimal
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2022/3/1
9 | * mail:2726449200@qq.com
10 | * describe:算术工具类
11 | */
12 | object ArithmeticUtils {
13 | fun add(d1: Double, d2: Double): Double {
14 | val str1 = d1.toString()
15 | val str2 = d2.toString()
16 | return add(str1, str2)
17 | }
18 |
19 | /**
20 | * 相加
21 | */
22 | fun add(str1: String?, str2: String?): Double {
23 | val b1 = BigDecimal(str1)
24 | val b2 = BigDecimal(str2)
25 | return b1.add(b2).toDouble()
26 | }
27 |
28 | /**
29 | * 相减
30 | */
31 | fun sub(d1: Double, d2: Double): Double {
32 | val str1 = d1.toString()
33 | val str2 = d2.toString()
34 | return sub(str1, str2)
35 | }
36 |
37 | /**
38 | * 相减
39 | */
40 | fun sub(str1: String?, str2: String?): Double {
41 | val b1 = BigDecimal(str1)
42 | val b2 = BigDecimal(str2)
43 | return b1.subtract(b2).toDouble()
44 | }
45 |
46 | /**
47 | * 相乘
48 | */
49 | fun mul(d1: Double, d2: Double): Double {
50 | val str1 = d1.toString()
51 | val str2 = d2.toString()
52 | return mul(str1, str2)
53 | }
54 |
55 | /**
56 | * 相乘
57 | */
58 | fun mul(str1: String?, str2: String?): Double {
59 | val b1 = BigDecimal(str1)
60 | val b2 = BigDecimal(str2)
61 | return b1.multiply(b2).toDouble()
62 | }
63 |
64 | /**
65 | * 相除
66 | */
67 | fun div(d1: Double, d2: Double): Double {
68 | return div(d1, d2, 10)
69 | }
70 |
71 | fun div(d1: Double, d2: Double, scale: Int): Double {
72 | require(scale >= 0) { "The scale must be a positive integer or zero" }
73 | val b1 = BigDecimal(d1.toString())
74 | val b2 = BigDecimal(d2.toString())
75 | return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toDouble()
76 | }
77 |
78 | /**
79 | * num.compareTo(BigDecimal.ZERO)结果:
80 | * num小于0 例如:num=-10.00
81 | * num等于0,例如num=0.00
82 | * num大于0 例如:num=10.00
83 | *
84 | * @param strValue
85 | * @return 浮点型是否大于0
86 | */
87 | fun valueGreaterThanZero(strValue: String?): Boolean {
88 | // 为空时,认为大于0
89 | if (TextUtils.isEmpty(strValue)) {
90 | return false
91 | }
92 | val num = BigDecimal(strValue)
93 | val result = num.compareTo(BigDecimal.ZERO)
94 | return result == 1
95 | }
96 |
97 | /**
98 | * num.compareTo(BigDecimal.ZERO)结果:
99 | * num小于0 例如:num=-10.00
100 | * num等于0,例如num=0.00或 0
101 | * num大于0 例如:num=10.00
102 | *
103 | * @param strValue
104 | * @return 浮点型是否等于0
105 | */
106 | fun valueEqualsZero(strValue: String?): Boolean {
107 | // 为空认为是0
108 | if (TextUtils.isEmpty(strValue)) {
109 | return true
110 | }
111 | val num = BigDecimal(strValue)
112 | val result = num.compareTo(BigDecimal.ZERO)
113 | return result == 0
114 | }
115 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/BasicLibraryUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils
2 |
3 | import android.app.Application
4 | import com.peakmain.basiclibrary.config.BasicLibraryConfig
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2022/08/12
9 | * mail:2726449200@qq.com
10 | * describe:
11 | */
12 | internal object BasicLibraryUtils {
13 | /**
14 | * 获取全局上下文
15 | */
16 | @JvmStatic
17 | val application: Application?
18 | get() {
19 | return BasicLibraryConfig.getInstance()?.getApp()?.getApplication()
20 | }
21 |
22 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/BitmapUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils
2 |
3 | import android.graphics.Bitmap
4 | import android.graphics.BitmapFactory
5 | import android.net.Uri
6 | import java.io.File
7 | import java.io.FileOutputStream
8 | import kotlin.math.roundToInt
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2022/09/02
13 | * mail:2726449200@qq.com
14 | * describe:
15 | */
16 | object BitmapUtils {
17 | /**
18 | * Bitmap保存到sdk卡,并返回Uri
19 | */
20 | fun bitmap2Uri(bitmap: Bitmap, savePath: String): Uri? {
21 | val file = File(savePath)
22 | if (!file.exists()) {
23 | file.mkdir()
24 | }
25 | val img = File(file.absolutePath + TimeUtils.getCurrentTime() + ".png")
26 | return try {
27 | val fos = FileOutputStream(img)
28 | bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos)
29 | fos.flush()
30 | fos.close()
31 | Uri.fromFile(img)
32 | } catch (e: Exception) {
33 | e.printStackTrace()
34 | null
35 | }
36 | }
37 |
38 | /**
39 | * Bitmap保存到SD卡上,得到一个绝对路径
40 | */
41 | fun getBitmapPath(bitmap: Bitmap, savePath: String): String? {
42 | val file = File(savePath)
43 | if (!file.exists()) {
44 | file.mkdir()
45 | }
46 | val img = File(file.absolutePath + TimeUtils.getCurrentTime() + ".png")
47 | return try {
48 | val fos = FileOutputStream(img)
49 | bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos)
50 | fos.flush()
51 | fos.close()
52 | img.canonicalPath
53 | } catch (e: Exception) {
54 | e.printStackTrace()
55 | null
56 | }
57 | }
58 |
59 | /**
60 | * 计算图片的缩放值
61 | */
62 | fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
63 | val height: Int = options.outHeight
64 | val width: Int = options.outWidth
65 | var inSampleSize = 1
66 | if (height > reqHeight || width > reqWidth) {
67 | val heightRatio = (height.toFloat() / reqHeight.toFloat()).roundToInt()
68 | val widthRatio = (width.toFloat() / reqWidth.toFloat()).roundToInt()
69 | inSampleSize = if (heightRatio < widthRatio) heightRatio else widthRatio
70 | }
71 | return inSampleSize
72 | }
73 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/FoldableDeviceUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils
2 |
3 |
4 | /**
5 | * author :Peakmain
6 | * createTime:2023/9/12
7 | * mail:2726449200@qq.com
8 | * describe:
9 | */
10 | object FoldableDeviceUtils {
11 | /**
12 | * true表示是折叠状态
13 | * false表示展开状态
14 | */
15 | fun isFold(): Boolean {
16 | val screenWidth: Int? =
17 | BasicLibraryUtils.application?.resources?.displayMetrics?.widthPixels
18 |
19 | if (SystemUtils.isSamsungFold()) {
20 | return screenWidth != 1768
21 | }
22 | if (SystemUtils.isHuaWeiFoldDevice()||SystemUtils.isGoogleFoldDevice()) {
23 | return screenWidth != 2200
24 | }
25 | if (SystemUtils.isVivoFoldDevice()||SystemUtils.isXiaomiFoldDevice()) {
26 | return screenWidth != 1916
27 | }
28 | return true
29 | }
30 |
31 |
32 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/GlobalCoroutineExceptionHandler.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils
2 |
3 | import kotlinx.coroutines.CoroutineExceptionHandler
4 | import kotlin.coroutines.CoroutineContext
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2022/2/15
9 | * mail:2726449200@qq.com
10 | * describe:
11 | */
12 | class GlobalCoroutineExceptionHandler : CoroutineExceptionHandler {
13 | override val key = CoroutineExceptionHandler
14 |
15 | var coroutineExceptionCallback: ((context: CoroutineContext, exception: Throwable) -> Unit)? =
16 | null
17 |
18 | override fun handleException(context: CoroutineContext, exception: Throwable) {
19 | coroutineExceptionCallback?.let {
20 | it(context, exception)
21 | }
22 | }
23 |
24 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/ThreadUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils
2 |
3 | import android.os.Handler
4 | import android.os.Looper
5 | import com.peakmain.basiclibrary.config.BasicLibraryConfig
6 | import com.peakmain.basiclibrary.constants.AndroidVersion
7 | import java.util.concurrent.Executor
8 | import java.util.concurrent.RejectedExecutionException
9 |
10 | /**
11 | * author :Peakmain
12 | * createTime:2022/10/31
13 | * mail:2726449200@qq.com
14 | * describe:线程工具类
15 | */
16 | object ThreadUtils {
17 | private val handler: Handler = object : Handler(Looper.getMainLooper()) {
18 | }
19 | private var mExecutor = HandlerExecutor(handler)
20 |
21 | /**
22 | * 获得主线程的线程池
23 | */
24 | fun getMainExecutor(): Executor? {
25 | val application = BasicLibraryConfig.getInstance()?.getApp()?.getApplication()
26 | return if (AndroidVersion.isAndroid9())
27 | application?.mainExecutor
28 | else
29 | mExecutor
30 | }
31 |
32 | class HandlerExecutor(private val mHandler: Handler) : Executor {
33 | override fun execute(command: Runnable?) {
34 | if (command != null && !mHandler.post(command)) {
35 | throw RejectedExecutionException("$mHandler is shutting down")
36 | }
37 | }
38 |
39 | }
40 |
41 | fun assertMainThread(methodName: String) {
42 | check(!isMainThread()) {
43 | ("Cannot invoke " + methodName + " on a background"
44 | + " thread")
45 | }
46 | }
47 |
48 | fun isMainThread(): Boolean {
49 | return Looper.getMainLooper().thread === Thread.currentThread()
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/TimeUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils
2 |
3 | import com.peakmain.basiclibrary.constants.AndroidVersion
4 | import java.text.SimpleDateFormat
5 | import java.util.*
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2021/12/24
10 | * mail:2726449200@qq.com
11 | * describe:
12 | */
13 | object TimeUtils {
14 | const val yyyy_MM_dd = "yyyy-MM-dd"
15 | private const val yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss"
16 |
17 | fun getCurrentTime(pattern: String=yyyy_MM_dd_HH_mm_ss): String {
18 | val currentTime = Date()
19 | val formatter = if (AndroidVersion.isAndroid7()) {
20 | SimpleDateFormat(pattern,Locale.getDefault(Locale.Category.FORMAT))
21 | } else {
22 | SimpleDateFormat(pattern,Locale.CHINA)
23 | }
24 | return formatter.format(currentTime)
25 | }
26 | /**
27 | * 返回几就是周几
28 | */
29 | fun getDayOfWeek(date: Date): Int {
30 | val c = Calendar.getInstance().also {
31 | it.time = date
32 | }
33 | val weekDay = c.get(Calendar.DAY_OF_WEEK)
34 | val day = (weekDay - 1)
35 | return if (day == 0) 7 else day
36 | }
37 | /**
38 | * 将指定的毫秒数转换为 以pattern参数自定义的格式返回
39 | */
40 | fun ms2Date(_ms: Long, pattern: String): String {
41 | val date = Date(_ms)
42 | val format = SimpleDateFormat(pattern, Locale.getDefault())
43 | return format.format(date)
44 | }
45 | /**
46 | * 将指定以pattern参数自定义的格式的时间转换为毫秒值
47 | */
48 | fun date2Ms(_data: String, pattern: String): Long {
49 | val format = if(AndroidVersion.isAndroid7()){
50 | SimpleDateFormat(pattern,Locale.getDefault(Locale.Category.FORMAT))
51 | }else{
52 | SimpleDateFormat(pattern,Locale.CHINA)
53 | }
54 | return try {
55 | val date = format.parse(_data)
56 | date?.time ?: 0
57 | } catch (e: Exception) {
58 | 0
59 | }
60 | }
61 | /**
62 | * 获取当前时间段
63 | * [h] 小时数,24小时制
64 | */
65 | fun getCurrentTimeRange(h: String): String {
66 | var hour: Int
67 | try {
68 | hour = h.toInt()
69 | } catch (e: Exception) {
70 | hour = 0
71 | e.printStackTrace()
72 | }
73 | return when (hour) {
74 | 23, 0, 1 -> "半夜"
75 | in 2..5 -> "凌晨"
76 | in 6..9 -> "早上"
77 | in 9 until 12 -> "上午"
78 | in 12..13 -> "中午"
79 | in 14..18 -> "下午"
80 | in 19..22 -> "晚上"
81 | else -> ""
82 | }
83 | }
84 |
85 | /**
86 | * 获取[date2]比[date1]多的天数
87 | */
88 | fun dateDifference(date1: Date, date2: Date): Int {
89 | val cal1 = Calendar.getInstance()
90 | cal1.time = date1
91 | val cal2 = Calendar.getInstance()
92 | cal2.time = date2
93 | val day1 = cal1[Calendar.DAY_OF_YEAR]
94 | val day2 = cal2[Calendar.DAY_OF_YEAR]
95 | val year1 = cal1[Calendar.YEAR]
96 | val year2 = cal2[Calendar.YEAR]
97 | return if (year1 != year2) {
98 | var timeDistance = 0
99 | for (i in year1 until year2) {
100 | timeDistance += if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
101 | //闰年
102 | 366
103 | } else {//不是闰年
104 | 365
105 | }
106 | }
107 | timeDistance + (day2 - day1)
108 | } else {
109 | day2 - day1
110 | }
111 | }
112 |
113 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/bus/RxBus.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils.bus
2 |
3 | import androidx.lifecycle.*
4 | import com.peakmain.basiclibrary.utils.ThreadUtils
5 | import java.util.concurrent.ConcurrentHashMap
6 | import kotlin.collections.set
7 |
8 | /**
9 | * author :Peakmain
10 | * createTime:2021/5/12
11 | * mail:2726449200@qq.com
12 | * describe:LiveData实现事件分发总线
13 | */
14 | class RxBus private constructor() {
15 |
16 | companion object {
17 | private val eventMap = ConcurrentHashMap>()
18 | val instance: RxBus by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) {
19 | RxBus()
20 | }
21 | }
22 |
23 | /**
24 | * register bus
25 | */
26 | fun register(eventName: String): StickyLiveData {
27 | var liveData = eventMap[eventName]
28 | if (liveData == null) {
29 | liveData =
30 | StickyLiveData(
31 | eventName
32 | )
33 | eventMap[eventName] = liveData
34 | }
35 | return liveData as StickyLiveData
36 | }
37 |
38 | class StickyLiveData(private val eventName: String) : LiveData() {
39 | internal var mData: T? = null
40 | internal var mVersion = 0
41 | private var mSticky: Boolean = false
42 | fun setData(data: T) {
43 | setValue(data)
44 | }
45 |
46 | fun postData(data: T) {
47 | super.postValue(data)
48 | }
49 |
50 | /**
51 | * @param sticky true表示是粘性事件,默认是false
52 | */
53 | fun isSticky(sticky: Boolean) {
54 | mSticky = sticky
55 | }
56 |
57 | override fun setValue(value: T) {
58 | mData = value
59 | mVersion++
60 | super.setValue(value)
61 | }
62 |
63 | override fun observe(owner: LifecycleOwner, observer: Observer) {
64 | observerSticky(owner, mSticky, observer)
65 | }
66 |
67 | private fun observerSticky(
68 | owner: LifecycleOwner,
69 | sticky: Boolean,
70 | observer: Observer
71 | ) {
72 | owner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
73 | if (event == Lifecycle.Event.ON_DESTROY) {
74 | eventMap.remove(eventName)
75 | }
76 | })
77 | super.observe(
78 | owner,
79 | StickyObserver(
80 | this,
81 | sticky,
82 | observer
83 | )
84 | )
85 | }
86 | }
87 |
88 | /**
89 | * sticky不等于true,只能接收到注册之后发送的消息,如果想接受先发送后注册的消息需要设置sticky为true
90 | */
91 | class StickyObserver(
92 | private val stickyLiveData: StickyLiveData,
93 | private val sticky: Boolean,
94 | private val observer: Observer
95 | ) : Observer {
96 | private var lastVersion = stickyLiveData.mVersion
97 | override fun onChanged(t: T) {
98 | if (lastVersion >= stickyLiveData.mVersion) {
99 | if (sticky && stickyLiveData.mData != null) {
100 | observer.onChanged(t)
101 | }
102 | return
103 | }
104 | lastVersion = stickyLiveData.mVersion
105 | observer.onChanged(t)
106 | }
107 |
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/keyboard/OnKeyboardListener.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils.keyboard
2 |
3 | /**
4 | * author :Peakmain
5 | * createTime:1/22/22
6 | * mail:2726449200@qq.com
7 | * describe:
8 | */
9 | interface OnKeyboardListener {
10 | /**
11 | * 键盘变化
12 | * @param isPopup the is popup 是否弹出
13 | * @param keyboardHeight the keyboard height 软键盘高度
14 | */
15 | fun onKeyboardChange(isPopup: Boolean, keyboardHeight: Int)
16 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/mmkv/DefaultSharedPreferencesFactory.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils.mmkv
2 |
3 | import android.content.Context
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2021/12/23
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | class DefaultSharedPreferencesFactory(context: Context, override val key: String="basic_sp_key") :
12 | BaseSharedPreferencesFactory(context)
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/mmkv/PreferencesUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils.mmkv
2 |
3 | import android.content.Context
4 | import java.lang.ref.WeakReference
5 |
6 | /**
7 | * author :Peakmain
8 | * createTime:2021/12/23
9 | * mail:2726449200@qq.com
10 | * describe:
11 | */
12 |
13 | class PreferencesUtils private constructor(private val contextRef: WeakReference) {
14 | companion object {
15 | @Volatile
16 | private var instance: PreferencesUtils? = null
17 |
18 | @JvmStatic
19 | fun getInstance(context: Context): PreferencesUtils? {
20 | instance ?: synchronized(this) {
21 | instance ?: PreferencesUtils(WeakReference(context)).also {
22 | instance = it
23 | }
24 | }
25 | return instance
26 | }
27 | }
28 |
29 | private lateinit var mSharedPreferences: DefaultSharedPreferencesFactory
30 | fun getSharedPreferences(): DefaultSharedPreferencesFactory? {
31 | if (this::mSharedPreferences.isInitialized) {
32 | return mSharedPreferences
33 | } else {
34 | val context = contextRef.get()
35 | if (context != null) {
36 | return init(context)
37 | }
38 | }
39 | return null
40 | }
41 |
42 | private fun init(context: Context): DefaultSharedPreferencesFactory {
43 | mSharedPreferences =
44 | DefaultSharedPreferencesFactory(
45 | context
46 | )
47 | return mSharedPreferences
48 | }
49 |
50 | fun saveParams(key: String, objects: Any) {
51 | getSharedPreferences()?.saveParams(key, objects)
52 | }
53 |
54 | fun getParam(key: String, defaultObject: Any?): Any? {
55 | return getSharedPreferences()?.getParam(key, defaultObject)
56 | }
57 |
58 | fun clearData() {
59 | getSharedPreferences()?.clearData()
60 | }
61 | }
62 |
63 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/utils/reflect/ReflectUtils.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.utils.reflect
2 |
3 | import android.util.Log
4 | import java.lang.Exception
5 | import java.lang.reflect.Field
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2022/3/1
10 | * mail:2726449200@qq.com
11 | * describe:
12 | */
13 | object ReflectUtils {
14 | private const val TAG = "ReflectUtil"
15 | @JvmStatic
16 | fun invokeStaticMethod(
17 | clzName: String?,
18 | methodName: String?,
19 | methodParamTypes: Array?>,
20 | vararg methodParamValues: Any?
21 | ): Any? {
22 | if(clzName==null||methodName==null)return null
23 | try {
24 | val clz = Class.forName(clzName)
25 | val med = clz.getDeclaredMethod(methodName, *methodParamTypes)
26 | med.isAccessible = true
27 | return med.invoke(null, *methodParamValues)
28 | } catch (e: Exception) {
29 | Log.e(TAG, "invokeStaticMethod got Exception:", e)
30 | }
31 | return null
32 | }
33 |
34 | fun invokeMethod(
35 | clzName: String?,
36 | methodName: String?,
37 | methodReceiver: Any?,
38 | methodParamTypes: Array?>,
39 | vararg methodParamValues: Any?
40 | ): Any? {
41 | try {
42 | if (methodReceiver == null||clzName==null||methodName==null) {
43 | return null
44 | }
45 | val clz = Class.forName(clzName)
46 | val med = clz.getDeclaredMethod(methodName, *methodParamTypes)
47 | med.isAccessible = true
48 | return med.invoke(methodReceiver, *methodParamValues)
49 | } catch (e: Exception) {
50 | Log.e(TAG, "invokeStaticMethod got Exception:", e)
51 | }
52 | return null
53 | }
54 |
55 | fun getStaticField(clzName: String?, filedName: String?): Any? {
56 | if(clzName==null||filedName==null)return null
57 | try {
58 | var field: Field? = null
59 | val clz = Class.forName(clzName)
60 | field = clz.getField(filedName)
61 | if (field != null) {
62 | return field[""]
63 | }
64 | } catch (e: Exception) {
65 | Log.e(TAG, "getStaticField got Exception:", e)
66 | }
67 | return null
68 | }
69 |
70 | fun getField(clzName: String?, obj: Any?, filedName: String?): Any? {
71 | try {
72 | if (obj == null||clzName==null||filedName==null) {
73 | return null
74 | }
75 | val clz = Class.forName(clzName)
76 | val field = clz.getField(filedName)
77 | return field[obj]
78 | } catch (e: Exception) {
79 | Log.e(TAG, "getStaticField got Exception:", e)
80 | }
81 | return null
82 | }
83 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/view/BindingView.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.view
2 |
3 | import android.view.MotionEvent
4 | import android.view.View
5 | import android.widget.TextView
6 | import androidx.databinding.BindingAdapter
7 | import com.peakmain.basiclibrary.extend.clickViewDelay
8 |
9 | /**
10 | * author :Peakmain
11 | * createTime:2021/12/29
12 | * mail:2726449200@qq.com
13 | * describe:
14 | */
15 | object BindingView {
16 |
17 | /**
18 | * 设置view的visibility
19 | */
20 | @BindingAdapter(value = ["visibilityOrGone"])
21 | @JvmStatic
22 | fun setViewVisibleOrGone(view: View, showVisibility: Boolean) {
23 | view.visibility = if (showVisibility) View.VISIBLE else View.GONE
24 | }
25 |
26 | @BindingAdapter(value = ["visibilityOrInVisible"])
27 | @JvmStatic
28 | fun setViewVisibleOrInvisible(view: View, showVisibility: Boolean) {
29 | view.visibility = if (showVisibility) View.VISIBLE else View.INVISIBLE
30 | }
31 |
32 | /**
33 | * 防止多次重复点击
34 | */
35 | @BindingAdapter(value = ["clickDelayTime", "click"], requireAll = false)
36 | @JvmStatic
37 | fun setViewClick(view: View, delayTime: Long = 0, block: View.OnClickListener? = null) {
38 | if (delayTime == 0L) {
39 | view.setOnClickListener(block)
40 | } else {
41 | view.clickViewDelay(delayTime) {v->
42 | block?.let {
43 | block.onClick(v)
44 | }
45 | }
46 | }
47 | }
48 |
49 | /**
50 | * textView的drawableLeft和drawableRight的点击事件
51 | */
52 | @BindingAdapter(value = ["drawableLeftClick", "drawableRightClick"], requireAll = false)
53 | @JvmStatic
54 | fun setTextViewDrawableClick(
55 | view: TextView,
56 | drawableLeftClick: View.OnClickListener? = null,
57 | drawableRightClick: View.OnClickListener? = null
58 | ) {
59 | view.run {
60 | setOnTouchListener(object : View.OnTouchListener {
61 | override fun onTouch(v: View, event: MotionEvent): Boolean {
62 | when (event.action) {
63 | MotionEvent.ACTION_DOWN -> {
64 | val drawableLeft = compoundDrawables[0]
65 | if (drawableLeft != null && event.rawX <= left + drawableLeft.bounds.width()) {
66 | drawableLeftClick?.let {
67 | drawableLeftClick.onClick(view)
68 | }
69 | return true
70 | }
71 | val drawableRight = compoundDrawables[2]
72 | return if (drawableRight != null && event.rawX >= width-paddingRight-drawableRight.intrinsicWidth) { // 增加了宽度,该方向+当前icon宽度
73 | drawableRightClick?.let {
74 | drawableRightClick.onClick(view)
75 | }
76 | true
77 | } else {
78 | false
79 | }
80 | }
81 | else -> return false
82 | }
83 | }
84 | })
85 | }
86 | }
87 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/viewmodel/EmptyViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.viewmodel
2 |
3 | import com.peakmain.basiclibrary.base.viewmodel.BaseViewModel
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2022/09/02
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | class EmptyViewModel:BaseViewModel() {
12 | override fun initModel() {
13 |
14 | }
15 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/viewmodel/ImageSelectViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.viewmodel
2 |
3 | import android.graphics.Bitmap
4 | import android.net.Uri
5 | import androidx.lifecycle.MutableLiveData
6 | import androidx.lifecycle.Observer
7 | import com.peakmain.basiclibrary.base.viewmodel.BaseViewModel
8 | import com.peakmain.basiclibrary.config.ImageRequestConfig
9 | import com.peakmain.basiclibrary.interfaces.OnImageSelectorCallback
10 |
11 | /**
12 | * author :Peakmain
13 | * createTime:2022/08/18
14 | * mail:2726449200@qq.com
15 | * describe:
16 | */
17 | internal class ImageSelectViewModel : BaseViewModel() {
18 | var mStart = MutableLiveData(false)
19 | var mOnImageSelectorCallback: OnImageSelectorCallback? = null
20 | var mConfig: ImageRequestConfig? = null
21 | override fun initModel() {
22 |
23 | }
24 |
25 | fun clearImage() {
26 | mStart.value = null
27 | mOnImageSelectorCallback = null
28 | mConfig = null
29 | }
30 |
31 | fun registerSingleLauncher(uri: Uri?) {
32 | mStart.value = false
33 | mOnImageSelectorCallback?.onImageSelect(arrayListOf(uri))
34 | }
35 |
36 | fun registerMultiLauncher(lists: List) {
37 | mStart.value = false
38 | mOnImageSelectorCallback?.onImageSelect(lists)
39 | }
40 |
41 | fun registerTakePicture(pair: Pair) {
42 | if (pair.first) {
43 | val bitmap = pair.second
44 | mOnImageSelectorCallback?.onImageSelect(bitmap)
45 | }
46 | mOnImageSelectorCallback = null
47 | }
48 |
49 | fun imageSelectorObserver(
50 | selectPhotoLauncher: ((ImageRequestConfig) -> Unit)? = null,
51 | selectMultiPhotoLauncher: ((ImageRequestConfig) -> Unit)? = null,
52 | takePictureLauncher: (() -> Unit)? = null
53 | )
54 | : Observer = Observer { start ->
55 | mConfig?.also {
56 | if (!start) return@Observer
57 | if (it.imageType != 0 && it.isSingle) {
58 | selectPhotoLauncher?.invoke(it)
59 | } else if (it.imageType == 0) {
60 | takePictureLauncher?.invoke()
61 | } else {
62 | selectMultiPhotoLauncher?.invoke(it)
63 | }
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/viewmodel/SameViewModel.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.viewmodel
2 |
3 | import com.peakmain.basiclibrary.base.viewmodel.BaseViewModel
4 |
5 | /**
6 | * author :Peakmain
7 | * createTime:2021/12/27
8 | * mail:2726449200@qq.com
9 | * describe:
10 | */
11 | internal abstract class SameViewModel:BaseViewModel(){
12 | val content ="test"
13 |
14 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/viewpage/DepthPageTransformer.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.viewpage
2 |
3 | import android.view.View
4 | import androidx.viewpager.widget.ViewPager
5 | import kotlin.math.abs
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2022/1/27
10 | * mail:2726449200@qq.com
11 | * describe:深度页面转换器
12 | */
13 |
14 | class DepthPageTransformer : ViewPager.PageTransformer {
15 | companion object{
16 | private const val MIN_SCALE = 0.75f
17 |
18 | }
19 | override fun transformPage(view: View, position: Float) {
20 | view.apply {
21 | val pageWidth = width
22 | when {
23 | position < -1 -> { // [-Infinity,-1)
24 | // This page is way off-screen to the left.
25 | alpha = 0f
26 | }
27 | position <= 0 -> { // [-1,0]
28 | // Use the default slide transition when moving to the left page
29 | alpha = 1f
30 | translationX = 0f
31 | scaleX = 1f
32 | scaleY = 1f
33 | }
34 | position <= 1 -> { // (0,1]
35 | visibility=View.VISIBLE
36 | // Fade the page out.
37 | alpha = 1 - position
38 |
39 | // Counteract the default slide transition
40 | translationX = pageWidth * -position
41 |
42 | // Scale the page down (between MIN_SCALE and 1)
43 | val scaleFactor = (MIN_SCALE + (1 - MIN_SCALE) * (1 - abs(position)))
44 | scaleX = scaleFactor
45 | scaleY = scaleFactor
46 | if(position==1f){
47 | visibility=View.INVISIBLE
48 | }
49 | }
50 | else -> { // (1,+Infinity]
51 | // This page is way off-screen to the right.
52 | alpha = 0f
53 | }
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/viewpage/DepthPageTransformer2.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.viewpage
2 |
3 | import android.view.View
4 | import androidx.viewpager2.widget.ViewPager2
5 | import kotlin.math.abs
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2022/1/27
10 | * mail:2726449200@qq.com
11 | * describe:viewPager2->深度页面转换器
12 | */
13 |
14 | class DepthPageTransformer2 : ViewPager2.PageTransformer {
15 | companion object{
16 | private const val MIN_SCALE = 0.75f
17 |
18 | }
19 | override fun transformPage(view: View, position: Float) {
20 | view.apply {
21 | val pageWidth = width
22 | when {
23 | position < -1 -> { // [-Infinity,-1)
24 | // This page is way off-screen to the left.
25 | alpha = 0f
26 | }
27 | position <= 0 -> { // [-1,0]
28 | // Use the default slide transition when moving to the left page
29 | alpha = 1f
30 | translationX = 0f
31 | scaleX = 1f
32 | scaleY = 1f
33 | }
34 | position <= 1 -> { // (0,1]
35 | visibility=View.VISIBLE
36 | // Fade the page out.
37 | alpha = 1 - position
38 |
39 | // Counteract the default slide transition
40 | translationX = pageWidth * -position
41 |
42 | // Scale the page down (between MIN_SCALE and 1)
43 | val scaleFactor = (MIN_SCALE + (1 - MIN_SCALE) * (1 - abs(position)))
44 | scaleX = scaleFactor
45 | scaleY = scaleFactor
46 | if(position==1f){
47 | visibility=View.INVISIBLE
48 | }
49 | }
50 | else -> { // (1,+Infinity]
51 | // This page is way off-screen to the right.
52 | alpha = 0f
53 | }
54 | }
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/viewpage/ZoomOutPageTransformer.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.viewpage
2 |
3 | import android.view.View
4 | import androidx.viewpager.widget.ViewPager
5 | import kotlin.math.abs
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2022/1/27
10 | * mail:2726449200@qq.com
11 | * describe:缩小页面转换器
12 | */
13 | class ZoomOutPageTransformer : ViewPager.PageTransformer {
14 | companion object {
15 | private const val MIN_SCALE = 0.85f
16 | private const val MIN_ALPHA = 0.5f
17 | }
18 |
19 | override fun transformPage(view: View, position: Float) {
20 | view.apply {
21 | val pageWidth = width
22 | val pageHeight = height
23 | when {
24 | position < -1 -> {
25 | alpha = 0f
26 | }
27 | position <= 1 -> {
28 | val scaleFactor = MIN_SCALE.coerceAtLeast(1 - abs(position))
29 | val vertMargin = pageHeight * (1 - scaleFactor) / 2
30 | val horzMargin = pageWidth * (1 - scaleFactor) / 2
31 | translationX = if (position < 0) {
32 | horzMargin - vertMargin / 2
33 | } else {
34 | horzMargin + vertMargin / 2
35 | }
36 | scaleX = scaleFactor
37 | scaleY = scaleFactor
38 | alpha = MIN_ALPHA +
39 | (((scaleFactor - MIN_SCALE) / (1 - MIN_SCALE)) * (1 - MIN_ALPHA))
40 | }
41 | else -> {
42 | alpha = 0f
43 | }
44 | }
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/java/com/peakmain/basiclibrary/viewpage/ZoomOutPageTransformer2.kt:
--------------------------------------------------------------------------------
1 | package com.peakmain.basiclibrary.viewpage
2 |
3 | import android.view.View
4 | import androidx.viewpager2.widget.ViewPager2
5 | import kotlin.math.abs
6 |
7 | /**
8 | * author :Peakmain
9 | * createTime:2022/1/27
10 | * mail:2726449200@qq.com
11 | * describe:ViewPager2->缩小页面转换器
12 | */
13 | class ZoomOutPageTransformer2 : ViewPager2.PageTransformer {
14 | companion object {
15 | private const val MIN_SCALE = 0.85f
16 | private const val MIN_ALPHA = 0.5f
17 | }
18 |
19 | override fun transformPage(view: View, position: Float) {
20 | view.apply {
21 | val pageWidth = width
22 | val pageHeight = height
23 | when {
24 | position < -1 -> {
25 | alpha = 0f
26 | }
27 | position <= 1 -> {
28 | val scaleFactor = MIN_SCALE.coerceAtLeast(1 - abs(position))
29 | val vertMargin = pageHeight * (1 - scaleFactor) / 2
30 | val horzMargin = pageWidth * (1 - scaleFactor) / 2
31 | translationX = if (position < 0) {
32 | horzMargin - vertMargin / 2
33 | } else {
34 | horzMargin + vertMargin / 2
35 | }
36 | scaleX = scaleFactor
37 | scaleY = scaleFactor
38 | alpha = MIN_ALPHA +
39 | (((scaleFactor - MIN_SCALE) / (1 - MIN_SCALE)) * (1 - MIN_ALPHA))
40 | }
41 | else -> {
42 | alpha = 0f
43 | }
44 | }
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/anim/slide_in_from_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/anim/slide_out_to_top.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/drawable/library_clear_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/drawable/library_done_black_24dp.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/drawable/library_ic_left_black_back.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/drawable/library_rotate_progressbar.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
17 |
18 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/layout-v21/layout_submit_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
16 |
17 |
24 |
25 |
29 |
30 |
35 |
36 |
42 |
43 |
44 |
45 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/layout/layout_submit_loading.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
15 |
16 |
23 |
24 |
28 |
29 |
34 |
35 |
41 |
42 |
43 |
44 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/layout/library_dialog_top_toast.xml:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
24 |
25 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/layout/library_recycler_foot_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
25 |
26 |
31 |
32 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/layout/same_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
15 |
16 |
20 |
21 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #f3f3f3
4 | #77000000
5 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/values/ids.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/values/string.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 加载中…
4 |
5 |
6 |
7 |
8 | - com.android.vending
9 |
10 | - com.tencent.android.qqdownloader
11 |
12 | - com.qihoo.appstore
13 |
14 | - com.baidu.appsearch
15 |
16 | - com.xiaomi.market
17 |
18 | - com.wandoujia.phoenix2
19 |
20 | - com.huawei.appmarket
21 |
22 | - com.taobao.appcenter
23 |
24 | - com.hiapk.marketpho
25 |
26 | - cn.goapk.market
27 |
28 |
29 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | MEIZU_FLAG_DARK_STATUS_BAR_ICON
4 | meizuFlags
5 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
21 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/res/xml/basic_library_provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
9 |
12 |
13 |
16 |
17 |
20 |
21 |
24 |
25 |
28 |
--------------------------------------------------------------------------------
/basicLibrary/src/main/resources/META-INF.services/kotlinx.coroutines.CoroutineExceptionHandler:
--------------------------------------------------------------------------------
1 | com.peakmain.basiclibrary.utils.GlobalCoroutineExceptionHandler
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | ext.kotlin_version = '1.6.10'
4 | repositories {
5 | google()
6 | mavenCentral()
7 | maven {
8 | url "https://plugins.gradle.org/m2/"
9 | }
10 | }
11 | dependencies {
12 | classpath 'com.android.tools.build:gradle:4.2.2'
13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
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 | mavenCentral()
23 | maven { url "https://jitpack.io" }
24 | maven {
25 | url "https://plugins.gradle.org/m2/"
26 | }
27 | }
28 | }
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | org.gradle.jvmargs=-Xmx2048m
10 | # When configured, Gradle will run in incubating parallel mode.
11 | # This option should only be used with decoupled projects. More details, visit
12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13 | # org.gradle.parallel=true
14 | # AndroidX package structure to make it clearer which packages are bundled with the
15 | # Android operating system, and which are packaged with your app"s APK
16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
17 | android.useAndroidX=true
18 | # Automatically convert third-party libraries to use AndroidX
19 | android.enableJetifier=true
20 | # Kotlin code style for this project: "official" or "obsolete":
21 | kotlin.code.style=official
22 |
23 | android.useNewApkCreator=false
24 | android.injected.testOnly=false
25 | kapt.use.worker.api=false
26 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Peakmain/BasicLibrary/0a5979492abbada1e4802c2172f0286f1ddc072a/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Dec 23 10:17:40 CST 2021
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-6.7.1-all.zip
7 |
--------------------------------------------------------------------------------
/jitpack.yml:
--------------------------------------------------------------------------------
1 | jdk:
2 | - openjdk11
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | include (":app")
2 | include (":basicLibrary")
3 | rootProject.name = "BasicLibrary"
4 | rootProject.buildFileName="build.gradle"
5 |
--------------------------------------------------------------------------------