Files
BiliRoaming/app/src/main/java/me/iacn/biliroaming/MainActivity.kt
T
Zhaohui Huang d5d3e61e30
Android CI / build (push) Has been cancelled
backup repo
2026-07-06 19:09:41 -11:00

206 lines
8.0 KiB
Kotlin
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@file:Suppress("DEPRECATION")
package me.iacn.biliroaming
import android.app.Activity
import android.app.AlertDialog
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.preference.Preference
import android.preference.Preference.OnPreferenceChangeListener
import android.preference.Preference.OnPreferenceClickListener
import android.preference.PreferenceCategory
import android.preference.PreferenceFragment
import android.util.Log
import android.view.View
import android.widget.Toast
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.cancel
import kotlinx.coroutines.launch
import me.iacn.biliroaming.hook.SettingHook
import me.iacn.biliroaming.utils.fetchJson
/**
* Created by iAcn on 2019/3/23
* Email i@iacn.me
*/
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
fragmentManager.beginTransaction().replace(android.R.id.content, PrefsFragment()).commit()
}
class PrefsFragment : PreferenceFragment(), OnPreferenceChangeListener,
OnPreferenceClickListener {
private lateinit var runningStatusPref: Preference
private val scope = MainScope()
@Deprecated("Deprecated in Java")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
addPreferencesFromResource(R.xml.main_activity)
runningStatusPref = findPreference("running_status")
findPreference("hide_icon").onPreferenceChangeListener = this
findPreference("version").summary = BuildConfig.VERSION_NAME
findPreference("feature").onPreferenceClickListener = this
findPreference("setting").onPreferenceClickListener = this
findPreference("clear_hook_cache").onPreferenceClickListener = this
checkUpdate()
}
@Deprecated("Deprecated in Java")
override fun onDestroy() {
super.onDestroy()
scope.cancel()
}
@Deprecated("Deprecated in Java")
override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
when (preference.key) {
"hide_icon" -> {
val isShow = newValue as Boolean
val aliasName = ComponentName(activity, MainActivity::class.java.name + "Alias")
val packageManager = activity.packageManager
val status =
if (isShow) PackageManager.COMPONENT_ENABLED_STATE_DISABLED else PackageManager.COMPONENT_ENABLED_STATE_ENABLED
if (packageManager.getComponentEnabledSetting(aliasName) != status) {
packageManager.setComponentEnabledSetting(
aliasName,
status,
PackageManager.DONT_KILL_APP
)
}
}
}
return true
}
@Deprecated("Deprecated in Java")
override fun onResume() {
super.onResume()
when {
isModuleActive() -> {
runningStatusPref.setTitle(R.string.running_status_enable)
runningStatusPref.setSummary(R.string.runtime_xposed)
}
isTaiChiModuleActive(activity) -> {
runningStatusPref.setTitle(R.string.running_status_enable)
runningStatusPref.setSummary(R.string.runtime_taichi)
}
else -> {
runningStatusPref.setTitle(R.string.running_status_disable)
runningStatusPref.setSummary(R.string.not_running_summary)
}
}
}
private fun checkUpdate() = scope.launch {
val result = fetchJson(resources.getString(R.string.version_url)) ?: return@launch
val newestVer = result.optString("name")
if (newestVer.isNotEmpty() && BuildConfig.VERSION_NAME != newestVer) {
findPreference("version").summary = "${BuildConfig.VERSION_NAME}(最新版$newestVer)"
(findPreference("about") as PreferenceCategory).addPreference(Preference(activity).apply {
key = "update"
title = resources.getString(R.string.update_title)
summary = result.optString("body").substringAfterLast("更新日志\r\n")
.ifEmpty { resources.getString(R.string.update_summary) }
onPreferenceClickListener = this@PrefsFragment
order = 1
})
}
}
private fun onUpdateCheck(): Boolean {
val uri = Uri.parse(resources.getString(R.string.update_url))
val intent = Intent(Intent.ACTION_VIEW, uri)
startActivity(intent)
return true
}
private fun onFeatureClick(): Boolean {
AlertDialog.Builder(activity).run {
setView(View.inflate(activity, R.layout.feature, null))
setNegativeButton("关闭", null)
show()
}
return true
}
private fun onSettingClick(): Boolean {
val packages = Constant.BILIBILI_PACKAGE_NAME.filter { isPackageInstalled(it.value) }
when {
packages.size == 1 -> startSetting(packages.values.first())
packages.isEmpty() -> Toast.makeText(activity, "未检测到已安装的客户端", Toast.LENGTH_LONG)
.show()
else -> {
AlertDialog.Builder(activity).run {
val keys = packages.keys.toTypedArray()
setItems(keys) { _, i -> startSetting(packages[keys[i]] ?: error("")) }
setTitle("请选择版本")
show()
}
}
}
return true
}
@Deprecated("Deprecated in Java")
override fun onPreferenceClick(preference: Preference?) = when (preference?.key) {
"update" -> onUpdateCheck()
"feature" -> onFeatureClick()
"setting" -> onSettingClick()
"clear_hook_cache" -> onClearHookCacheClick()
else -> false
}
private fun isPackageInstalled(packageName: String) = try {
activity.packageManager.getPackageInfo(packageName, 0)
true
} catch (e: PackageManager.NameNotFoundException) {
false
}
private fun startSetting(packageName: String) {
activity.packageManager.getLaunchIntentForPackage(packageName)?.run {
addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
putExtra(SettingHook.START_SETTING_KEY, true)
startActivity(this)
}
}
private fun onClearHookCacheClick(): Boolean {
val prefs = activity.getSharedPreferences("biliroaming_hookinfo", Context.MODE_PRIVATE)
val nextGen = prefs.getInt("generation", 0) + 1
prefs.edit().putInt("generation", nextGen).apply()
Toast.makeText(activity, "将在下次启动哔哩哔哩时重新扫描", Toast.LENGTH_SHORT).show()
return true
}
}
companion object {
fun isModuleActive(): Boolean {
Log.i("大不自多", "海纳江河")
return false
}
private fun isTaiChiModuleActive(context: Context): Boolean {
val contentResolver = context.contentResolver
val uri = Uri.parse("content://me.weishu.exposed.CP/")
return try {
val result = contentResolver.call(uri, "active", null, null)
result?.getBoolean("active", false) ?: false
} catch (e: Exception) {
false
}
}
}
}