From 2c8a0c330a10177ab04879e0a7cea1a0d3575278 Mon Sep 17 00:00:00 2001
From: Invinciblelee <1760316362@qq.com>
Date: Fri, 24 May 2019 15:28:42 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=9D=83=E9=99=90=E8=AF=B7?=
=?UTF-8?q?=E6=B1=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
app/build.gradle | 1 -
app/src/main/AndroidManifest.xml | 3 +
.../app/help/permission/ActivitySource.kt | 20 ++
.../app/help/permission/FragmentSource.kt | 19 ++
.../permission/OnPermissionsDeniedCallback.kt | 5 +
.../OnPermissionsGrantedCallback.kt | 7 +
.../permission/OnPermissionsResultCallback.kt | 9 +
.../OnRequestPermissionsResultCallback.kt | 11 +
.../app/help/permission/PermissionActivity.kt | 77 +++++++
.../legado/app/help/permission/Permissions.kt | 72 +++++++
.../app/help/permission/PermissionsCompat.kt | 78 +++++++
.../io/legado/app/help/permission/Request.kt | 199 ++++++++++++++++++
.../app/help/permission/RequestManager.kt | 67 ++++++
.../app/help/permission/RequestPlugins.kt | 20 ++
.../app/help/permission/RequestSource.kt | 13 ++
.../io/legado/app/ui/main/MainActivity.kt | 78 ++++++-
.../java/io/legado/app/ui/widget/TitleBar.kt | 2 +-
app/src/main/res/layout/activity_search.xml | 6 +-
app/src/main/res/layout/app_bar_main.xml | 2 +-
app/src/main/res/values/strings.xml | 10 +-
app/src/main/res/values/styles.xml | 15 +-
21 files changed, 704 insertions(+), 10 deletions(-)
create mode 100644 app/src/main/java/io/legado/app/help/permission/ActivitySource.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/FragmentSource.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/OnPermissionsDeniedCallback.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/OnPermissionsGrantedCallback.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/OnPermissionsResultCallback.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/OnRequestPermissionsResultCallback.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/PermissionActivity.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/Permissions.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/PermissionsCompat.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/Request.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/RequestManager.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/RequestPlugins.kt
create mode 100644 app/src/main/java/io/legado/app/help/permission/RequestSource.kt
diff --git a/app/build.gradle b/app/build.gradle
index 966ba8516..215af4020 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -76,7 +76,6 @@ dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.2.1'
//规则相关
- implementation 'pub.devrel:easypermissions:3.0.0'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.jayway.jsonpath:json-path:2.4.0'
implementation 'org.jsoup:jsoup:1.12.1'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7c5e32f4a..3bef8cc80 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -40,6 +40,9 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/help/permission/ActivitySource.kt b/app/src/main/java/io/legado/app/help/permission/ActivitySource.kt
new file mode 100644
index 000000000..e0618067a
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/ActivitySource.kt
@@ -0,0 +1,20 @@
+package io.legado.app.help.permission
+
+import android.content.Context
+import android.content.Intent
+import androidx.appcompat.app.AppCompatActivity
+
+import java.lang.ref.WeakReference
+
+internal class ActivitySource(activity: AppCompatActivity) : RequestSource {
+
+ private val actRef: WeakReference = WeakReference(activity)
+
+ override val context: Context?
+ get() = actRef.get()
+
+ override fun startActivity(intent: Intent) {
+ actRef.get()?.startActivity(intent)
+ }
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/FragmentSource.kt b/app/src/main/java/io/legado/app/help/permission/FragmentSource.kt
new file mode 100644
index 000000000..b66e11b98
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/FragmentSource.kt
@@ -0,0 +1,19 @@
+package io.legado.app.help.permission
+
+import android.content.Context
+import android.content.Intent
+import androidx.fragment.app.Fragment
+
+import java.lang.ref.WeakReference
+
+internal class FragmentSource(fragment: Fragment) : RequestSource {
+
+ private val fragRef: WeakReference = WeakReference(fragment)
+
+ override val context: Context?
+ get() = fragRef.get()?.requireContext()
+
+ override fun startActivity(intent: Intent) {
+ fragRef.get()?.startActivity(intent)
+ }
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/OnPermissionsDeniedCallback.kt b/app/src/main/java/io/legado/app/help/permission/OnPermissionsDeniedCallback.kt
new file mode 100644
index 000000000..d6e81a68f
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/OnPermissionsDeniedCallback.kt
@@ -0,0 +1,5 @@
+package io.legado.app.help.permission
+
+interface OnPermissionsDeniedCallback {
+ fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array)
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/OnPermissionsGrantedCallback.kt b/app/src/main/java/io/legado/app/help/permission/OnPermissionsGrantedCallback.kt
new file mode 100644
index 000000000..59f6977d4
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/OnPermissionsGrantedCallback.kt
@@ -0,0 +1,7 @@
+package io.legado.app.help.permission
+
+interface OnPermissionsGrantedCallback {
+
+ fun onPermissionsGranted(requestCode: Int)
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/OnPermissionsResultCallback.kt b/app/src/main/java/io/legado/app/help/permission/OnPermissionsResultCallback.kt
new file mode 100644
index 000000000..3d7afa600
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/OnPermissionsResultCallback.kt
@@ -0,0 +1,9 @@
+package io.legado.app.help.permission
+
+interface OnPermissionsResultCallback {
+
+ fun onPermissionsGranted(requestCode: Int)
+
+ fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array)
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/help/permission/OnRequestPermissionsResultCallback.kt b/app/src/main/java/io/legado/app/help/permission/OnRequestPermissionsResultCallback.kt
new file mode 100644
index 000000000..b86983fd9
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/OnRequestPermissionsResultCallback.kt
@@ -0,0 +1,11 @@
+package io.legado.app.help.permission
+
+import android.content.Intent
+
+interface OnRequestPermissionsResultCallback {
+
+ fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray)
+
+
+ fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/PermissionActivity.kt b/app/src/main/java/io/legado/app/help/permission/PermissionActivity.kt
new file mode 100644
index 000000000..98ecf5b67
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/PermissionActivity.kt
@@ -0,0 +1,77 @@
+package io.legado.app.help.permission
+
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import android.provider.Settings
+import android.view.KeyEvent
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import io.legado.app.R
+import org.jetbrains.anko.toast
+
+class PermissionActivity : AppCompatActivity() {
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val intent = intent
+
+ when (intent.getIntExtra(KEY_INPUT_REQUEST_TYPE, Request.TYPE_REQUEST_PERMISSION)) {
+ Request.TYPE_REQUEST_PERMISSION//权限请求
+ -> {
+ val requestCode = intent.getIntExtra(KEY_INPUT_PERMISSIONS_CODE, 1000)
+ val permissions = intent.getStringArrayExtra(KEY_INPUT_PERMISSIONS)
+ if (permissions != null) {
+ ActivityCompat.requestPermissions(this, permissions, requestCode)
+ } else {
+ finish()
+ }
+ }
+ Request.TYPE_REQUEST_SETTING//跳转到设置界面
+ -> try {
+ val settingIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+ settingIntent.data = Uri.fromParts("package", packageName, null)
+ startActivityForResult(settingIntent, Request.TYPE_REQUEST_SETTING)
+ } catch (e: Exception) {
+ toast(R.string.tip_cannot_jump_setting_page)
+ finish()
+ }
+
+ }
+ }
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ RequestPlugins.sRequestCallback?.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ finish()
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ super.onActivityResult(requestCode, resultCode, data)
+ RequestPlugins.sRequestCallback?.onActivityResult(requestCode, resultCode, data)
+ finish()
+ }
+
+ override fun startActivity(intent: Intent) {
+ super.startActivity(intent)
+ overridePendingTransition(0, 0)
+ }
+
+ override fun finish() {
+ super.finish()
+ overridePendingTransition(0, 0)
+ }
+
+ override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
+ return if (keyCode == KeyEvent.KEYCODE_BACK) {
+ true
+ } else super.onKeyDown(keyCode, event)
+ }
+
+ companion object {
+
+ const val KEY_INPUT_REQUEST_TYPE = "KEY_INPUT_REQUEST_TYPE"
+ const val KEY_INPUT_PERMISSIONS_CODE = "KEY_INPUT_PERMISSIONS_CODE"
+ const val KEY_INPUT_PERMISSIONS = "KEY_INPUT_PERMISSIONS"
+ }
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/Permissions.kt b/app/src/main/java/io/legado/app/help/permission/Permissions.kt
new file mode 100644
index 000000000..e1c0893e3
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/Permissions.kt
@@ -0,0 +1,72 @@
+package io.legado.app.help.permission
+
+object Permissions {
+
+ const val READ_CALENDAR = "android.permission.READ_CALENDAR"
+ const val WRITE_CALENDAR = "android.permission.WRITE_CALENDAR"
+
+ const val CAMERA = "android.permission.CAMERA"
+
+ const val READ_CONTACTS = "android.permission.READ_CONTACTS"
+ const val WRITE_CONTACTS = "android.permission.WRITE_CONTACTS"
+ const val GET_ACCOUNTS = "android.permission.GET_ACCOUNTS"
+
+ const val ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION"
+ const val ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION"
+
+ const val RECORD_AUDIO = "android.permission.RECORD_AUDIO"
+
+ const val READ_PHONE_STATE = "android.permission.READ_PHONE_STATE"
+ const val CALL_PHONE = "android.permission.CALL_PHONE"
+ const val READ_CALL_LOG = "android.permission.READ_CALL_LOG"
+ const val WRITE_CALL_LOG = "android.permission.WRITE_CALL_LOG"
+ const val ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL"
+ const val USE_SIP = "android.permission.USE_SIP"
+ const val PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS"
+
+ const val BODY_SENSORS = "android.permission.BODY_SENSORS"
+
+ const val SEND_SMS = "android.permission.SEND_SMS"
+ const val RECEIVE_SMS = "android.permission.RECEIVE_SMS"
+ const val READ_SMS = "android.permission.READ_SMS"
+ const val RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH"
+ const val RECEIVE_MMS = "android.permission.RECEIVE_MMS"
+
+ const val READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE"
+ const val WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE"
+
+ object Group {
+ val CALENDAR = arrayOf(READ_CALENDAR, WRITE_CALENDAR)
+
+ val CAMERA = arrayOf(Permissions.CAMERA)
+
+ val CONTACTS = arrayOf(READ_CONTACTS, WRITE_CONTACTS, GET_ACCOUNTS)
+
+ val LOCATION = arrayOf(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION)
+
+ val MICROPHONE = arrayOf(RECORD_AUDIO)
+
+ val PHONE = arrayOf(
+ READ_PHONE_STATE,
+ CALL_PHONE,
+ READ_CALL_LOG,
+ WRITE_CALL_LOG,
+ ADD_VOICEMAIL,
+ USE_SIP,
+ PROCESS_OUTGOING_CALLS
+ )
+
+ val SENSORS = arrayOf(BODY_SENSORS)
+
+ val SMS = arrayOf(
+ SEND_SMS,
+ RECEIVE_SMS,
+ READ_SMS,
+ RECEIVE_WAP_PUSH,
+ RECEIVE_MMS
+ )
+
+ val STORAGE = arrayOf(READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE)
+ }
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/PermissionsCompat.kt b/app/src/main/java/io/legado/app/help/permission/PermissionsCompat.kt
new file mode 100644
index 000000000..45ef0f885
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/PermissionsCompat.kt
@@ -0,0 +1,78 @@
+package io.legado.app.help.permission
+
+import androidx.annotation.StringRes
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.Fragment
+
+class PermissionsCompat private constructor() {
+
+ private var mRequest: Request? = null
+
+ fun request() {
+ RequestManager.pushRequest(mRequest)
+ }
+
+ class Builder {
+ private val mRequest: Request
+
+ constructor(activity: AppCompatActivity) {
+ mRequest = Request(activity)
+ }
+
+ constructor(fragment: Fragment) {
+ mRequest = Request(fragment)
+ }
+
+ fun addPermissions(vararg permissions: String): Builder {
+ mRequest.addPermissions(*permissions)
+ return this
+ }
+
+ fun requestCode(requestCode: Int): Builder {
+ mRequest.setRequestCode(requestCode)
+ return this
+ }
+
+ fun onGranted(callback: (requestCode: Int) -> Unit): Builder {
+ mRequest.setOnGrantedCallback(object : OnPermissionsGrantedCallback {
+ override fun onPermissionsGranted(requestCode: Int) {
+ callback(requestCode)
+ }
+ })
+ return this
+ }
+
+ fun onDenied(callback: (requestCode: Int, deniedPermissions: Array) -> Unit): Builder {
+ mRequest.setOnDeniedCallback(object : OnPermissionsDeniedCallback {
+ override fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array) {
+ callback(requestCode, deniedPermissions)
+ }
+ })
+ return this
+ }
+
+ fun rationale(rationale: CharSequence): Builder {
+ mRequest.setRationale(rationale)
+ return this
+ }
+
+ fun rationale(@StringRes resId: Int): Builder {
+ mRequest.setRationale(resId)
+ return this
+ }
+
+ fun build(): PermissionsCompat {
+ val compat = PermissionsCompat()
+ compat.mRequest = mRequest
+ return compat
+ }
+
+ fun request(): PermissionsCompat {
+ val compat = build()
+ compat.mRequest = mRequest
+ compat.request()
+ return compat
+ }
+ }
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/Request.kt b/app/src/main/java/io/legado/app/help/permission/Request.kt
new file mode 100644
index 000000000..c5d389fa6
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/Request.kt
@@ -0,0 +1,199 @@
+package io.legado.app.help.permission
+
+import android.content.Intent
+import android.content.pm.PackageManager
+import android.os.Build
+import androidx.annotation.StringRes
+import androidx.appcompat.app.AlertDialog
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.content.ContextCompat
+import androidx.fragment.app.Fragment
+import io.legado.app.R
+import org.jetbrains.anko.startActivity
+import java.util.*
+
+internal class Request : OnRequestPermissionsResultCallback {
+
+ var startTime: Long = 0
+ private set
+ private var requestCode: Int = 0
+ private var source: RequestSource? = null
+ private var permissions: ArrayList? = null
+ private var grantedCallback: OnPermissionsGrantedCallback? = null
+ private var deniedCallback: OnPermissionsDeniedCallback? = null
+ private var rationaleResId: Int = 0
+ private var rationale: CharSequence? = null
+
+ private var rationaleDialog: AlertDialog? = null
+
+ private val deniedPermissions: Array?
+ get() {
+ val permissions: Array?
+ val size = this.permissions?.size ?: 0
+ if (size > 0) {
+ permissions = this.permissions?.toTypedArray()
+ } else {
+ permissions = null
+ }
+ return getDeniedPermissions(permissions)
+ }
+
+ constructor(activity: AppCompatActivity) {
+ source = ActivitySource(activity)
+ permissions = ArrayList()
+ }
+
+ constructor(fragment: Fragment) {
+ source = FragmentSource(fragment)
+ permissions = ArrayList()
+ }
+
+ fun addPermissions(vararg permissions: String) {
+ this.permissions?.addAll(Arrays.asList(*permissions))
+ }
+
+ fun setRequestCode(requestCode: Int) {
+ this.requestCode = requestCode
+ }
+
+ fun setOnGrantedCallback(callback: OnPermissionsGrantedCallback) {
+ grantedCallback = callback
+ }
+
+ fun setOnDeniedCallback(callback: OnPermissionsDeniedCallback) {
+ deniedCallback = callback
+ }
+
+ fun setRationale(@StringRes resId: Int) {
+ rationaleResId = resId
+ rationale = null
+ }
+
+ fun setRationale(rationale: CharSequence) {
+ this.rationale = rationale
+ rationaleResId = 0
+ }
+
+ fun start() {
+ RequestPlugins.setOnRequestPermissionsCallback(this)
+
+ val deniedPermissions = deniedPermissions
+
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+ if (deniedPermissions == null) {
+ onPermissionsGranted(requestCode)
+ } else {
+ val rationale = if (rationaleResId != 0) source?.context?.getText(rationaleResId) else rationale
+ if (rationale != null) {
+ showSettingDialog(rationale) { onPermissionsDenied(requestCode, deniedPermissions) }
+ } else {
+ onPermissionsDenied(requestCode, deniedPermissions)
+ }
+ }
+ } else {
+ if (deniedPermissions != null) {
+ source?.context?.startActivity(
+ Pair(PermissionActivity.KEY_INPUT_REQUEST_TYPE, TYPE_REQUEST_PERMISSION),
+ Pair(PermissionActivity.KEY_INPUT_PERMISSIONS_CODE, requestCode),
+ Pair(PermissionActivity.KEY_INPUT_PERMISSIONS, deniedPermissions)
+ )
+ } else {
+ onPermissionsGranted(requestCode)
+ }
+ }
+
+ startTime = System.currentTimeMillis()
+ }
+
+ fun clear() {
+ grantedCallback = null
+ deniedCallback = null
+ }
+
+ private fun getDeniedPermissions(permissions: Array?): Array? {
+ if (permissions != null) {
+ val deniedPermissionList = ArrayList()
+ for (permission in permissions) {
+ if (source?.context?.let {
+ ContextCompat.checkSelfPermission(
+ it,
+ permission
+ )
+ } != PackageManager.PERMISSION_GRANTED
+ ) {
+ deniedPermissionList.add(permission)
+ }
+ }
+ val size = deniedPermissionList.size
+ if (size > 0) {
+ return deniedPermissionList.toTypedArray()
+ }
+ }
+ return null
+ }
+
+ private fun showSettingDialog(rationale: CharSequence, cancel: () -> Unit) {
+ rationaleDialog?.dismiss()
+ source?.context?.let {
+ rationaleDialog = AlertDialog.Builder(it)
+ .setTitle(R.string.dialog_title)
+ .setMessage(rationale)
+ .setPositiveButton(R.string.dialog_setting) { _, _ ->
+ it.startActivity(
+ Pair(
+ PermissionActivity.KEY_INPUT_REQUEST_TYPE,
+ TYPE_REQUEST_SETTING
+ )
+ )
+ }
+ .setNegativeButton(R.string.dialog_cancel) { _, _ -> cancel() }
+ .show()
+ }
+ }
+
+ private fun onPermissionsGranted(requestCode: Int) {
+ try {
+ grantedCallback?.onPermissionsGranted(requestCode)
+ } catch (ignore: Exception) {
+ }
+
+ RequestPlugins.sResultCallback?.onPermissionsGranted(requestCode)
+ }
+
+ private fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array) {
+ try {
+ deniedCallback?.onPermissionsDenied(requestCode, deniedPermissions)
+ } catch (ignore: Exception) {
+ }
+
+ RequestPlugins.sResultCallback?.onPermissionsDenied(requestCode, deniedPermissions)
+ }
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
+ val deniedPermissions = getDeniedPermissions(permissions)
+ if (deniedPermissions != null) {
+ val rationale = if (rationaleResId != 0) source?.context?.getText(rationaleResId) else rationale
+ if (rationale != null) {
+ showSettingDialog(rationale) { onPermissionsDenied(requestCode, deniedPermissions) }
+ } else {
+ onPermissionsDenied(requestCode, deniedPermissions)
+ }
+ } else {
+ onPermissionsGranted(requestCode)
+ }
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ val deniedPermissions = deniedPermissions
+ if (deniedPermissions == null) {
+ onPermissionsGranted(this.requestCode)
+ } else {
+ onPermissionsDenied(this.requestCode, deniedPermissions)
+ }
+ }
+
+ companion object {
+ const val TYPE_REQUEST_PERMISSION = 1
+ const val TYPE_REQUEST_SETTING = 2
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/io/legado/app/help/permission/RequestManager.kt b/app/src/main/java/io/legado/app/help/permission/RequestManager.kt
new file mode 100644
index 000000000..e7f0eca52
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/RequestManager.kt
@@ -0,0 +1,67 @@
+package io.legado.app.help.permission
+
+import android.os.Handler
+import java.util.*
+
+internal object RequestManager : OnPermissionsResultCallback {
+
+ private var requests: Stack? = null
+ private var request: Request? = null
+
+ private val handler = Handler()
+
+ private val requestRunnable = Runnable {
+ request?.start()
+ }
+
+ private val isCurrentRequestInvalid: Boolean
+ get() = request?.let { System.currentTimeMillis() - it.startTime > 5 * 1000L } ?: true
+
+ init {
+ RequestPlugins.setOnPermissionsResultCallback(this)
+ }
+
+ fun pushRequest(request: Request?) {
+ if (request == null) return
+
+ if (requests == null) {
+ requests = Stack()
+ }
+
+ requests?.let {
+ val index = it.indexOf(request)
+ if (index >= 0) {
+ val to = it.size - 1
+ if (index != to) {
+ Collections.swap(requests, index, to)
+ }
+ } else {
+ it.push(request)
+ }
+
+ if (isCurrentRequestInvalid) {
+ this.request = it.pop()
+ handler.post(requestRunnable)
+ }
+ }
+ }
+
+ private fun startNextRequest() {
+ request?.clear()
+ request = null
+
+ requests?.let {
+ request = if (it.empty()) null else it.pop()
+ request?.let { handler.post(requestRunnable) }
+ }
+ }
+
+ override fun onPermissionsGranted(requestCode: Int) {
+ startNextRequest()
+ }
+
+ override fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array) {
+ startNextRequest()
+ }
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/RequestPlugins.kt b/app/src/main/java/io/legado/app/help/permission/RequestPlugins.kt
new file mode 100644
index 000000000..16370193f
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/RequestPlugins.kt
@@ -0,0 +1,20 @@
+package io.legado.app.help.permission
+
+internal object RequestPlugins {
+
+ @Volatile
+ var sRequestCallback: OnRequestPermissionsResultCallback? = null
+
+ @Volatile
+ var sResultCallback: OnPermissionsResultCallback? = null
+
+ fun setOnRequestPermissionsCallback(callback: OnRequestPermissionsResultCallback) {
+ sRequestCallback = callback
+ }
+
+ fun setOnPermissionsResultCallback(callback: OnPermissionsResultCallback) {
+ sResultCallback = callback
+ }
+
+
+}
diff --git a/app/src/main/java/io/legado/app/help/permission/RequestSource.kt b/app/src/main/java/io/legado/app/help/permission/RequestSource.kt
new file mode 100644
index 000000000..73c89df43
--- /dev/null
+++ b/app/src/main/java/io/legado/app/help/permission/RequestSource.kt
@@ -0,0 +1,13 @@
+package io.legado.app.help.permission
+
+import android.content.Context
+import android.content.Intent
+import androidx.fragment.app.FragmentManager
+
+interface RequestSource {
+
+ val context: Context?
+
+ fun startActivity(intent: Intent)
+
+}
diff --git a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt
index ce40a7e33..10bfe53c3 100644
--- a/app/src/main/java/io/legado/app/ui/main/MainActivity.kt
+++ b/app/src/main/java/io/legado/app/ui/main/MainActivity.kt
@@ -2,18 +2,32 @@ package io.legado.app.ui.main
import android.content.Intent
import android.os.Bundle
+import android.util.Log
import android.view.Menu
import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout
import com.google.android.material.navigation.NavigationView
+import com.jayway.jsonpath.Configuration
+import com.jayway.jsonpath.JsonPath
+import com.jayway.jsonpath.Option
+import io.legado.app.App
import io.legado.app.R
import io.legado.app.base.BaseActivity
+import io.legado.app.constant.AppConst.APP_TAG
+import io.legado.app.data.entities.ReplaceRule
+import io.legado.app.help.permission.Permissions
+import io.legado.app.help.permission.PermissionsCompat
+import io.legado.app.ui.replacerule.ReplaceRuleActivity
import io.legado.app.ui.search.SearchActivity
-import io.legado.app.utils.getViewModel
+import io.legado.app.utils.*
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.android.synthetic.main.app_bar_main.*
+import org.jetbrains.anko.doAsync
+import org.jetbrains.anko.startActivity
+import org.jetbrains.anko.uiThread
+import java.io.File
class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener {
override val viewModel: MainViewModel
@@ -26,7 +40,7 @@ class MainActivity : BaseActivity(), NavigationV
fab.setOnClickListener { startActivity(Intent(this, SearchActivity::class.java)) }
val toggle = ActionBarDrawerToggle(
- this, drawer_layout, titleBar.toolbar,
+ this, drawer_layout, title_bar.toolbar,
R.string.navigation_drawer_open,
R.string.navigation_drawer_close
)
@@ -58,6 +72,20 @@ class MainActivity : BaseActivity(), NavigationV
override fun onNavigationItemSelected(item: MenuItem): Boolean {
// Handle navigation view item clicks here.
when (item.itemId) {
+ R.id.nav_backup -> {
+ // Handle the camera action
+ }
+ R.id.nav_import -> {
+
+ }
+ R.id.nav_import_old -> PermissionsCompat.Builder(this)
+ .addPermissions(*Permissions.Group.STORAGE)
+ .rationale(R.string.tip_perm_request_storage)
+ .onGranted { importYueDu() }.request()
+ R.id.nav_import_github -> {
+
+ }
+ R.id.nav_replace_rule -> startActivity()
R.id.nav_send -> {
}
@@ -66,4 +94,50 @@ class MainActivity : BaseActivity(), NavigationV
drawerLayout.closeDrawer(GravityCompat.START)
return true
}
+
+ /*
+ * import from YueDu backup data
+ * */
+ fun importYueDu() {
+ val yuedu = File(getSdPath(), "YueDu")
+ val jsonPath = JsonPath.using(
+ Configuration.builder()
+ .options(Option.SUPPRESS_EXCEPTIONS)
+ .build()
+ )
+
+ // Replace rules
+ val rFile = File(yuedu, "myBookReplaceRule.json")
+ val replaceRules = mutableListOf()
+ if (rFile.exists()) try {
+ val items: List