Skip to content
This repository has been archived by the owner on Jan 9, 2024. It is now read-only.

Commit

Permalink
R3.1.1
Browse files Browse the repository at this point in the history
修复 ShortcutActivity意外启动问题
增加功能 App shortcut
  • Loading branch information
ryuunoakaihitomi committed Aug 27, 2020
1 parent ce63fba commit 7cda8a6
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 94 deletions.
10 changes: 4 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
// 崩溃分析插件
/* 崩溃分析插件 */
apply plugin: 'com.google.gms.google-services'
apply plugin: 'com.google.firebase.crashlytics'

Expand All @@ -12,13 +12,13 @@ android {
minSdkVersion 22
targetSdkVersion 29
// 版本号:发布日期
versionCode 20200821
versionCode 20200827
/*
版本名说明:
R3.0.0
Refactoring 第三次重构+功能更新+缺陷修复
*/
versionName "R3.0.1"
versionName "R3.1.1"
resConfigs "en", "zh-rCN"
// 致用户:可以在这里禁用Firebase,将以下值设为true
final def disableFirebase = false
Expand Down Expand Up @@ -49,14 +49,12 @@ android {

dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.1'
implementation 'androidx.appcompat:appcompat:1.2.0'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'

def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
/* 崩溃报告组件 */
implementation 'com.google.firebase:firebase-analytics-ktx:17.5.0'
Expand All @@ -65,7 +63,7 @@ dependencies {
// PowerAct
implementation 'github.ryuunoakaihitomi.poweract:poweract:1.1.1'
// Toasty
implementation 'com.github.GrenderG:Toasty:1.4.2'
implementation 'com.github.GrenderG:Toasty:1.5.0'
/* libsu */
def libsuVersion = '3.0.2'
implementation "com.github.topjohnwu.libsu:core:${libsuVersion}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import android.app.Application
import android.os.StrictMode
import github.ryuunoakaihitomi.poweract.ExternalUtils
import github.ryuunoakaihitomi.powerpanel.util.BlackMagic
import github.ryuunoakaihitomi.powerpanel.util.FirebaseUtils
import github.ryuunoakaihitomi.powerpanel.util.StatisticsUtils

class MyApplication : Application() {

Expand All @@ -20,10 +20,11 @@ class MyApplication : Application() {
myApplication = this
if (BuildConfig.DEBUG) {
StrictMode.enableDefaults()
FirebaseUtils.disableDataCollection()
// 也可以使用DebugView:adb shell setprop debug.firebase.analytics.app com.ryuunoakaihitomi.rebootmenu
StatisticsUtils.disableDataCollection()
}
if (BuildConfig.DISABLE_FIREBASE) {
FirebaseUtils.disableDataCollection()
StatisticsUtils.disableDataCollection()
}
BlackMagic.toastBugFix()
ExternalUtils.enableLog(BuildConfig.DEBUG)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,31 @@ import github.ryuunoakaihitomi.poweract.Callback
import github.ryuunoakaihitomi.poweract.ExternalUtils
import github.ryuunoakaihitomi.poweract.PowerAct
import github.ryuunoakaihitomi.poweract.PowerActX
import github.ryuunoakaihitomi.powerpanel.BuildConfig
import github.ryuunoakaihitomi.powerpanel.MyApplication
import github.ryuunoakaihitomi.powerpanel.R
import github.ryuunoakaihitomi.powerpanel.util.FirebaseUtils
import github.ryuunoakaihitomi.powerpanel.util.Log
import github.ryuunoakaihitomi.powerpanel.util.StatisticsUtils
import github.ryuunoakaihitomi.powerpanel.util.restartSysUi

object PowerExecution {

private const val TAG = "PowerExecution"

fun execute(@StringRes labelResId: Int, activity: AppCompatActivity, forceMode: Boolean) {
val callback = object : Callback {

override fun done() {
FirebaseUtils.logPowerOperation(activity, labelResId, forceMode, true)
StatisticsUtils.logPowerOperation(activity, labelResId, forceMode, true)
activity.finish()
}

override fun failed() {
FirebaseUtils.logPowerOperation(activity, labelResId, forceMode, false)
val error = Toasty.error(
activity,
R.string.toast_op_failed
)
error.setGravity(Gravity.CENTER, 0, 0)
error.show()
StatisticsUtils.logPowerOperation(activity, labelResId, forceMode, false)
Toasty.error(activity, R.string.toast_op_failed).run {
setGravity(Gravity.CENTER, 0, 0)
show()
}
activity.finish()
}
}
Expand All @@ -52,6 +54,13 @@ object PowerExecution {
}
R.string.func_safe_mode -> PowerActX.safeMode(callback, forceMode)
R.string.func_lock_screen_privileged -> PowerActX.lockScreen(callback)
else -> {
Log.w(TAG, "execute: Unknown res id($labelResId). Go home...")
activity.startActivity(
activity.packageManager.getLaunchIntentForPackage(BuildConfig.APPLICATION_ID)
)
activity.finish()
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,7 @@ class ShortcutActivity : AppCompatActivity() {
makeTransparent()
val forceMode = intent.getBooleanExtra(EXTRA_FORCE_MODE, false)
PowerExecution.execute(
intent.getIntExtra(
EXTRA_LABEL_RES_ID,
ResourcesCompat.ID_NULL
),
this,
forceMode
intent.getIntExtra(EXTRA_LABEL_RES_ID, ResourcesCompat.ID_NULL), this, forceMode
)
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
package github.ryuunoakaihitomi.powerpanel.ui.main

import android.content.DialogInterface
import android.graphics.Typeface
import android.os.Bundle
import android.text.SpannableString
import android.text.style.StyleSpan
import android.text.style.TypefaceSpan
import android.widget.AdapterView
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.drawable.IconCompat
import androidx.core.graphics.drawable.toBitmap
import androidx.core.text.set
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.observe
import es.dmoral.toasty.Toasty
import github.ryuunoakaihitomi.powerpanel.BuildConfig
import github.ryuunoakaihitomi.powerpanel.MyApplication
import github.ryuunoakaihitomi.powerpanel.R
import github.ryuunoakaihitomi.powerpanel.desc.PowerExecution
import github.ryuunoakaihitomi.powerpanel.desc.PowerInfo
Expand All @@ -23,10 +29,12 @@ import io.noties.markwon.Markwon
import io.noties.markwon.ext.strikethrough.StrikethroughPlugin
import org.apache.commons.io.IOUtils
import java.nio.charset.Charset
import java.util.*

class MainActivity : AppCompatActivity() {

companion object {
private const val TAG = "MainActivity"

// 窗口透明度
private const val DIALOG_ALPHA = 0.85f
Expand All @@ -43,6 +51,23 @@ class MainActivity : AppCompatActivity() {
powerViewModel.labelResId.observe(this) {
PowerExecution.execute(it, this, powerViewModel.getForceMode())
}
powerViewModel.shortcutInfoArray.observe(this) { it ->
ShortcutManagerCompat.removeAllDynamicShortcuts(this)
val maxCount = ShortcutManagerCompat.getMaxShortcutCountPerActivity(this)
if (maxCount >= it.size) {
Log.d(TAG, "onCreate: Allow app shortcut. ${it.size} in $maxCount")
it.forEach {
val unspannedLabel = it.label.toString()
val shortcut = ShortcutInfoCompat.Builder(this, unspannedLabel).run {
setShortLabel(unspannedLabel)
setIcon(IconCompat.createWithResource(applicationContext, it.iconResId))
setIntent(ShortcutActivity.getActionIntent(it.labelResId, false))
build()
}
ShortcutManagerCompat.addDynamicShortcuts(this, listOf(shortcut))
}
}
}
powerViewModel.infoArray.observe(this) {
mainDialog = AlertDialog.Builder(this).apply {
setTitle(powerViewModel.title.value)
Expand All @@ -67,7 +92,7 @@ class MainActivity : AppCompatActivity() {
)
) { _, confirmWhich ->
val ok = confirmWhich == 0
FirebaseUtils.logDialogCancel(item.labelResId, ok.not())
StatisticsUtils.logDialogCancel(item.labelResId, ok.not())
if (ok) {
powerViewModel.call(item.labelResId)
// dismiss防止窗口泄露
Expand All @@ -76,8 +101,12 @@ class MainActivity : AppCompatActivity() {
powerViewModel.prepare()
}
}
setOnCancelListener { powerViewModel.prepare() }
setOnCancelListener {
StatisticsUtils.logDialogCancel(item.labelResId, true)
powerViewModel.prepare()
}
setNeutralButton(null, null)
setPositiveButton(null, null)
show()
} else {
powerViewModel.call(item.labelResId)
Expand Down Expand Up @@ -139,16 +168,32 @@ class MainActivity : AppCompatActivity() {
)
)
}
addLauncherShortcut(
MyApplication.getInstance(),
item.label, toBitmap(),
ShortcutActivity.getActionIntent(
item.labelResId,
powerViewModel.getForceMode()
val unspannedLabel = item.label.toString()
val shortcut = ShortcutInfoCompat.Builder(
applicationContext,
// 使用UUID有两种后果:可以重复添加Icon,修复图标无法变色的bug
UUID.randomUUID().toString()
).run {
setShortLabel(unspannedLabel)
setLongLabel(unspannedLabel)
setIcon(IconCompat.createWithBitmap(toBitmap()))
setIntent(
ShortcutActivity.getActionIntent(
item.labelResId,
powerViewModel.getForceMode()
)
)
build()
}
ShortcutManagerCompat.requestPinShortcut(
applicationContext,
shortcut,
null
)
}
}
// 在Android8.0以下和一些自定义系统(自动拒绝)可能没有反馈
Toasty.info(this, R.string.toast_shortcut_added).show()
return@OnItemLongClickListener true
}
// 半透明
Expand All @@ -167,4 +212,12 @@ class MainActivity : AppCompatActivity() {
})
powerViewModel.prepare()
}
}

private fun CharSequence.emphasize(): SpannableString = let {
val spannableString = SpannableString(it)
val range = 0..it.length
spannableString[range] = StyleSpan(Typeface.BOLD)
spannableString[range] = TypefaceSpan("monospace")
spannableString
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ class PowerViewModel : AndroidViewModel(MyApplication.getInstance()) {
val infoArray: LiveData<Array<PowerInfo>>
get() = _infoArray
private var _infoArray = MutableLiveData<Array<PowerInfo>>()
val shortcutInfoArray: LiveData<Array<PowerInfo>>
get() = _shortcutInfoArray
private var _shortcutInfoArray = MutableLiveData<Array<PowerInfo>>()

/* 观察对象,执行回调 */
val labelResId: LiveData<Int>
Expand Down Expand Up @@ -86,7 +89,7 @@ class PowerViewModel : AndroidViewModel(MyApplication.getInstance()) {
val lockScreenPrivileged = provide(R.string.func_lock_screen_privileged)

/* 这里定义了各个选项的顺序,这个顺序已经经过反复的试验,一般不需要更改 */
val normalActions = arrayOf(lockScreen, showSysPowerDialog)
val restrictedActions = arrayOf(lockScreen, showSysPowerDialog)
val privilegedActions = arrayOf(
reboot,
shutdown,
Expand All @@ -102,13 +105,17 @@ class PowerViewModel : AndroidViewModel(MyApplication.getInstance()) {
if (rootMode.value == true) {
_title.value = rawTitle
_infoArray.value = privilegedActions
// https://developer.android.google.cn/guide/topics/ui/shortcuts?hl=en#shortcut-limitations
// Although you can publish up to five shortcuts (static and dynamic shortcuts combined) at a time for your app, most launchers can only display four.
_shortcutInfoArray.value = privilegedActions.copyOfRange(0, 4)
} else {
_title.value = String.format(
"%s %s",
rawTitle,
app().getString(R.string.title_dialog_restricted_mode)
)
_infoArray.value = normalActions
_infoArray.value = restrictedActions
_shortcutInfoArray.value = restrictedActions
}
}

Expand Down
10 changes: 5 additions & 5 deletions app/src/main/java/github/ryuunoakaihitomi/powerpanel/util/Log.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,36 @@ object Log {
if (BuildConfig.DEBUG) {
Log.v(tag, msg)
}
FirebaseUtils.log(Log.VERBOSE, tag, msg)
StatisticsUtils.log(Log.VERBOSE, tag, msg)
}

fun d(tag: String, msg: String) {
if (BuildConfig.DEBUG) {
Log.d(tag, msg)
}
FirebaseUtils.log(Log.DEBUG, tag, msg)
StatisticsUtils.log(Log.DEBUG, tag, msg)
}

fun i(tag: String, msg: String) {
if (BuildConfig.DEBUG) {
Log.i(tag, msg)
}
FirebaseUtils.log(Log.INFO, tag, msg)
StatisticsUtils.log(Log.INFO, tag, msg)
}

fun w(tag: String, msg: String) {
if (BuildConfig.DEBUG) {
Log.w(tag, msg)
}
FirebaseUtils.log(Log.WARN, tag, msg)
StatisticsUtils.log(Log.WARN, tag, msg)

}

fun e(tag: String, msg: String) {
if (BuildConfig.DEBUG) {
Log.e(tag, msg)
}
FirebaseUtils.log(Log.ERROR, tag, msg)
StatisticsUtils.log(Log.ERROR, tag, msg)
}

fun e(tag: String, msg: String, throwable: Throwable) {
Expand Down
Loading

0 comments on commit 7cda8a6

Please sign in to comment.