添加权限请求

pull/32/head
Invinciblelee 6 years ago
parent 514dd5173a
commit 2c8a0c330a
  1. 1
      app/build.gradle
  2. 3
      app/src/main/AndroidManifest.xml
  3. 20
      app/src/main/java/io/legado/app/help/permission/ActivitySource.kt
  4. 19
      app/src/main/java/io/legado/app/help/permission/FragmentSource.kt
  5. 5
      app/src/main/java/io/legado/app/help/permission/OnPermissionsDeniedCallback.kt
  6. 7
      app/src/main/java/io/legado/app/help/permission/OnPermissionsGrantedCallback.kt
  7. 9
      app/src/main/java/io/legado/app/help/permission/OnPermissionsResultCallback.kt
  8. 11
      app/src/main/java/io/legado/app/help/permission/OnRequestPermissionsResultCallback.kt
  9. 77
      app/src/main/java/io/legado/app/help/permission/PermissionActivity.kt
  10. 72
      app/src/main/java/io/legado/app/help/permission/Permissions.kt
  11. 78
      app/src/main/java/io/legado/app/help/permission/PermissionsCompat.kt
  12. 199
      app/src/main/java/io/legado/app/help/permission/Request.kt
  13. 67
      app/src/main/java/io/legado/app/help/permission/RequestManager.kt
  14. 20
      app/src/main/java/io/legado/app/help/permission/RequestPlugins.kt
  15. 13
      app/src/main/java/io/legado/app/help/permission/RequestSource.kt
  16. 78
      app/src/main/java/io/legado/app/ui/main/MainActivity.kt
  17. 2
      app/src/main/java/io/legado/app/ui/widget/TitleBar.kt
  18. 6
      app/src/main/res/layout/activity_search.xml
  19. 2
      app/src/main/res/layout/app_bar_main.xml
  20. 10
      app/src/main/res/values/strings.xml
  21. 15
      app/src/main/res/values/styles.xml

@ -76,7 +76,6 @@ dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android: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.google.code.gson:gson:2.8.5'
implementation 'com.jayway.jsonpath:json-path:2.4.0' implementation 'com.jayway.jsonpath:json-path:2.4.0'
implementation 'org.jsoup:jsoup:1.12.1' implementation 'org.jsoup:jsoup:1.12.1'

@ -40,6 +40,9 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".ui.replacerule.ReplaceRuleActivity"/> <activity android:name=".ui.replacerule.ReplaceRuleActivity"/>
<activity android:name=".help.permission.PermissionActivity"
android:theme="@style/Activity.Permission"/>
</application> </application>
</manifest> </manifest>

@ -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<AppCompatActivity> = WeakReference(activity)
override val context: Context?
get() = actRef.get()
override fun startActivity(intent: Intent) {
actRef.get()?.startActivity(intent)
}
}

@ -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<Fragment> = WeakReference(fragment)
override val context: Context?
get() = fragRef.get()?.requireContext()
override fun startActivity(intent: Intent) {
fragRef.get()?.startActivity(intent)
}
}

@ -0,0 +1,5 @@
package io.legado.app.help.permission
interface OnPermissionsDeniedCallback {
fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array<String>)
}

@ -0,0 +1,7 @@
package io.legado.app.help.permission
interface OnPermissionsGrantedCallback {
fun onPermissionsGranted(requestCode: Int)
}

@ -0,0 +1,9 @@
package io.legado.app.help.permission
interface OnPermissionsResultCallback {
fun onPermissionsGranted(requestCode: Int)
fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array<String>)
}

@ -0,0 +1,11 @@
package io.legado.app.help.permission
import android.content.Intent
interface OnRequestPermissionsResultCallback {
fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray)
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?)
}

@ -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<String>, 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"
}
}

@ -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)
}
}

@ -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<String>) -> Unit): Builder {
mRequest.setOnDeniedCallback(object : OnPermissionsDeniedCallback {
override fun onPermissionsDenied(requestCode: Int, deniedPermissions: Array<String>) {
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
}
}
}

@ -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<String>? = 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<String>?
get() {
val permissions: Array<String>?
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<PermissionActivity>(
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<String>?): Array<String>? {
if (permissions != null) {
val deniedPermissionList = ArrayList<String>()
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<PermissionActivity>(
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<String>) {
try {
deniedCallback?.onPermissionsDenied(requestCode, deniedPermissions)
} catch (ignore: Exception) {
}
RequestPlugins.sResultCallback?.onPermissionsDenied(requestCode, deniedPermissions)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, 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
}
}

@ -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<Request>? = 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<String>) {
startNextRequest()
}
}

@ -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
}
}

@ -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)
}

@ -2,18 +2,32 @@ package io.legado.app.ui.main
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.core.view.GravityCompat import androidx.core.view.GravityCompat
import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout
import com.google.android.material.navigation.NavigationView 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.R
import io.legado.app.base.BaseActivity 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.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.activity_main.*
import kotlinx.android.synthetic.main.app_bar_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<MainDataBinding, MainViewModel>(), NavigationView.OnNavigationItemSelectedListener { class MainActivity : BaseActivity<MainDataBinding, MainViewModel>(), NavigationView.OnNavigationItemSelectedListener {
override val viewModel: MainViewModel override val viewModel: MainViewModel
@ -26,7 +40,7 @@ class MainActivity : BaseActivity<MainDataBinding, MainViewModel>(), NavigationV
fab.setOnClickListener { startActivity(Intent(this, SearchActivity::class.java)) } fab.setOnClickListener { startActivity(Intent(this, SearchActivity::class.java)) }
val toggle = ActionBarDrawerToggle( val toggle = ActionBarDrawerToggle(
this, drawer_layout, titleBar.toolbar, this, drawer_layout, title_bar.toolbar,
R.string.navigation_drawer_open, R.string.navigation_drawer_open,
R.string.navigation_drawer_close R.string.navigation_drawer_close
) )
@ -58,6 +72,20 @@ class MainActivity : BaseActivity<MainDataBinding, MainViewModel>(), NavigationV
override fun onNavigationItemSelected(item: MenuItem): Boolean { override fun onNavigationItemSelected(item: MenuItem): Boolean {
// Handle navigation view item clicks here. // Handle navigation view item clicks here.
when (item.itemId) { 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<ReplaceRuleActivity>()
R.id.nav_send -> { R.id.nav_send -> {
} }
@ -66,4 +94,50 @@ class MainActivity : BaseActivity<MainDataBinding, MainViewModel>(), NavigationV
drawerLayout.closeDrawer(GravityCompat.START) drawerLayout.closeDrawer(GravityCompat.START)
return true 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<ReplaceRule>()
if (rFile.exists()) try {
val items: List<Map<String, Any>> = jsonPath.parse(rFile.readText()).read("$.*")
for (item in items) {
val jsonItem = jsonPath.parse(item)
val rRule = ReplaceRule()
rRule.name = jsonItem.readString("$.replaceSummary")
rRule.pattern = jsonItem.readString("$.regex")
rRule.replacement = jsonItem.readString("$.replacement")
rRule.isRegex = jsonItem.readBool("$.isRegex")
rRule.scope = jsonItem.readString("$.useTo")
rRule.isEnabled = jsonItem.readBool("$.enable")
rRule.order = jsonItem.readInt("$.serialNumber")
replaceRules.add(rRule)
// Log.e(APP_TAG, rRule.toString())
}
doAsync {
App.db.replaceRuleDao().insert(*replaceRules.toTypedArray())
val count = App.db.replaceRuleDao().all.size
val maxId = App.db.replaceRuleDao().maxOrder
uiThread {
Log.e(APP_TAG, "$count records were inserted to database, and max id is $maxId.")
}
}
} catch (e: Exception) {
Log.e(APP_TAG, e.localizedMessage)
}
}
} }

@ -37,7 +37,6 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a
val attachToActivity = a.getBoolean(R.styleable.TitleBar_attachToActivity, true) val attachToActivity = a.getBoolean(R.styleable.TitleBar_attachToActivity, true)
val titleText = a.getString(R.styleable.TitleBar_title) val titleText = a.getString(R.styleable.TitleBar_title)
val subtitleText = a.getString(R.styleable.TitleBar_subtitle) val subtitleText = a.getString(R.styleable.TitleBar_subtitle)
a.recycle()
toolbar.apply { toolbar.apply {
if(showNavigationIcon){ if(showNavigationIcon){
@ -71,6 +70,7 @@ class TitleBar(context: Context, attrs: AttributeSet?) : AppBarLayout(context, a
} }
} }
a.recycle()
if (attachToActivity) { if (attachToActivity) {
attachToActivity(context) attachToActivity(context)

@ -12,7 +12,7 @@
tools:context="io.legado.app.ui.search.SearchActivity"> tools:context="io.legado.app.ui.search.SearchActivity">
<io.legado.app.ui.widget.TitleBar <io.legado.app.ui.widget.TitleBar
android:id="@+id/titleBar" android:id="@+id/title_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
@ -22,11 +22,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/titleBar"> app:layout_constraintTop_toBottomOf="@id/title_bar">
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/searchList" android:id="@+id/rv_search_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent"/>

@ -8,7 +8,7 @@
tools:context=".ui.main.MainActivity"> tools:context=".ui.main.MainActivity">
<io.legado.app.ui.widget.TitleBar <io.legado.app.ui.widget.TitleBar
android:id="@+id/titleBar" android:id="@+id/title_bar"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"/> android:layout_height="wrap_content"/>

@ -15,9 +15,17 @@
<string name="menu_send">Send</string> <string name="menu_send">Send</string>
<string name="dialog_title">提示</string>
<string name="dialog_cancel">取消</string>
<string name="dialog_confirm">确定</string>
<string name="dialog_setting">去设置</string>
<string name="tip_cannot_jump_setting_page">无法跳转至设置界面</string>
<string name="tip_perm_request_storage">阅读需要访问存储卡权限,请前往“设置”—”应用权限“—打开所需权限</string>
<string name="dynamic_click_retry">点击重试</string> <string name="dynamic_click_retry">点击重试</string>
<string name="dynamic_loading">正在加载</string> <string name="dynamic_loading">正在加载</string>
<string name="perm_request_storage">阅读需要访问存储卡权限:</string>
<string name="edit">编辑</string> <string name="edit">编辑</string>
<string name="delete">删除</string> <string name="delete">删除</string>
</resources> </resources>

@ -1,4 +1,4 @@
<resources> <resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. --> <!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
@ -14,6 +14,19 @@
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/> <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/> <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
<style name="Activity.Permission" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowDisablePreview">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowTranslucentStatus" tools:targetApi="kitkat">true</item>
<item name="android:windowAnimationStyle">@null</item>
</style>
<style name="Style.Line" parent="android:Widget">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">0.5dp</item>
<item name="android:background">@color/divider</item>
</style>
<style name="Style.Text.Primary.Normal" parent="android:Widget"> <style name="Style.Text.Primary.Normal" parent="android:Widget">
<item name="android:layout_width">match_parent</item> <item name="android:layout_width">match_parent</item>

Loading…
Cancel
Save