diff --git a/.changelog/lang_zh-Hans.json b/.changelog/lang_zh-Hans.json
index 9982b75e..757a9036 100644
--- a/.changelog/lang_zh-Hans.json
+++ b/.changelog/lang_zh-Hans.json
@@ -1,8 +1,9 @@
{
"$data": {
"v6.7.0": {
- "released_date": "2025/11/20",
+ "released_date": "2025/11/28",
"feature": [
+ "插件中心功能, 支持插件的安装/卸载/更新等操作 (入口: 主页抽屉按钮)",
"cvt 模块, 用于数据单位转换 (参阅 项目文档 > [单位转换](https://docs.autojs6.com/#/cvt))",
"fmt 模块, 用于数据格式化 (参阅 项目文档 > [格式化](https://docs.autojs6.com/#/fmt))",
"zip 模块, 用于文件压缩与解压缩操作 (Ref to [Auto.js Pro](https://g.pro.autojs.org/)) (参阅 项目文档 > [Zip](https://docs.autojs6.com/#/zip))",
@@ -26,6 +27,7 @@
"设置页面增加 \"定时任务调度引擎\" 设置选项, 支持 AlarmManager/WorkManager/JobScheduler _[`issue #457`](http://issues.autojs6.com/457)_ _[`issue #388`](http://issues.autojs6.com/388)_ _[`issue #163`](http://issues.autojs6.com/163)_ _[`issue #53`](http://issues.autojs6.com/53)_ _[`issue #21`](http://issues.autojs6.com/21)_",
"设置页面增加 \"应用启动器图标\" 设置选项, 支持自适应图标/透明背景图标 _[`issue #405`](http://issues.autojs6.com/405)_",
"设置页面增加 \"重启策略\" 设置选项, 用于设置主页抽屉栏重启按钮是否使用快速重启策略",
+ "设置页面启动器快捷方式增加 \"插件\" 选项, 用于通过快捷方式跳转到插件中心页面",
"Scrapers 工具 (run-scrapers.mjs) 用于自动更新 Gradle 构建脚本结构化数据/README 通用数据/README 模板数据等"
],
"fix": [
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index adb1d02e..287e3770 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -35,9 +35,15 @@
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="29" />
-
-
-
+
+
+
-
+ android:excludeFromRecents="true" />
+
+
= withContext(Dispatchers.IO) {
+ val pm = context.packageManager
+ val discovered = runCatching { PaddleOcrPluginHost.discover(context) }.getOrElse { emptyList() }
+
+ discovered.map { d ->
+ val serviceInfo = d.serviceInfo
+ val packageName = serviceInfo.packageName
+ val appInfo = runCatching { pm.getApplicationInfo(packageName, 0) }.getOrNull()
+ val appLabel = appInfo?.loadLabel(pm)?.toString()
+ val icon = appInfo?.loadIcon(pm)
+
+ val pkgInfo = runCatching { pm.getPackageInfo(packageName, 0) }.getOrNull()
+ val versionName = pkgInfo?.versionName ?: d.pluginInfo?.versionName ?: context.getString(R.string.text_unknown)
+ val versionCode = pkgInfo?.let { PackageInfoCompat.getLongVersionCode(it) } ?: d.pluginInfo?.versionCode
+ val firstInstallTime = pkgInfo?.firstInstallTime
+ val lastUpdateTime = pkgInfo?.lastUpdateTime
+
+ InstalledPlugin(
+ packageName = packageName,
+ title = d.pluginInfo?.name ?: appLabel ?: packageName,
+ description = d.pluginInfo?.description,
+ author = d.pluginInfo?.author,
+ versionName = versionName,
+ versionCode = versionCode,
+ installTime = firstInstallTime,
+ updateTime = lastUpdateTime,
+ icon = icon,
+ pluginInfo = d.pluginInfo,
+ )
+ }
+ }
+}
diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterActivity.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterActivity.kt
new file mode 100644
index 00000000..566365c1
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterActivity.kt
@@ -0,0 +1,41 @@
+package org.autojs.autojs.core.plugin.center
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.Intent
+import android.os.Bundle
+import org.autojs.autojs.ui.BaseActivity
+import org.autojs.autojs6.R
+import org.autojs.autojs6.databinding.ActivityPluginCenterBinding
+
+@SuppressLint("NotifyDataSetChanged")
+class PluginCenterActivity : BaseActivity() {
+
+ private lateinit var binding: ActivityPluginCenterBinding
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ binding = ActivityPluginCenterBinding.inflate(layoutInflater).also {
+ setContentView(it.root)
+ }
+
+ supportFragmentManager
+ .beginTransaction()
+ .replace(R.id.fragment_plugin_center, PluginCenterFragment())
+ .commit()
+
+ setToolbarAsBack(R.string.text_plugin_center)
+ }
+
+ companion object {
+
+ fun startActivity(context: Context) {
+ Intent(context, PluginCenterActivity::class.java)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .let { context.startActivity(it) }
+ }
+
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterFragment.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterFragment.kt
new file mode 100644
index 00000000..20bdd6cd
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterFragment.kt
@@ -0,0 +1,58 @@
+package org.autojs.autojs.core.plugin.center
+
+import android.content.Context
+import android.os.Bundle
+import android.view.View
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.viewModels
+import androidx.lifecycle.lifecycleScope
+import androidx.recyclerview.widget.DividerItemDecoration
+import androidx.recyclerview.widget.DividerItemDecoration.VERTICAL
+import androidx.recyclerview.widget.LinearLayoutManager
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.launch
+import org.autojs.autojs.util.ViewUtils.excludePaddingClippableViewFromBottomNavigationBar
+import org.autojs.autojs6.R
+import org.autojs.autojs6.databinding.FragmentPluginCenterBinding
+
+class PluginCenterFragment : Fragment(R.layout.fragment_plugin_center) {
+
+ private var _binding: FragmentPluginCenterBinding? = null
+ private val binding get() = _binding!!
+
+ private val vm: PluginCenterViewModel by viewModels()
+ private lateinit var adapter: PluginCenterItemAdapter
+ private lateinit var context: Context
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ _binding = FragmentPluginCenterBinding.bind(view)
+
+ val context = requireContext().also { context = it }
+
+ binding.pluginCenterRecyclerView.apply {
+ layoutManager = LinearLayoutManager(context)
+ adapter = PluginCenterItemAdapter().also { this@PluginCenterFragment.adapter = it }
+ addItemDecoration(DividerItemDecoration(context, VERTICAL))
+ excludePaddingClippableViewFromBottomNavigationBar()
+ }
+
+ // Load data.
+ // zh-CN: 加载数据.
+ vm.load(context)
+
+ // Subscribe data updates.
+ // zh-CN: 订阅数据更新.
+ viewLifecycleOwner.lifecycleScope.launch {
+ vm.items.collectLatest { list ->
+ adapter.updateData(list)
+ }
+ }
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+
+}
diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItem.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItem.kt
new file mode 100644
index 00000000..a150ea1f
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItem.kt
@@ -0,0 +1,18 @@
+package org.autojs.autojs.core.plugin.center
+
+import android.graphics.drawable.Drawable
+
+data class PluginCenterItem(
+ val packageName: String,
+ val title: String,
+ val description: String,
+ val author: String? = null,
+ val collaborators: List = emptyList(),
+ val versionName: String,
+ val versionCode: Long? = null,
+ val versionDate: String? = null,
+ val isEnabled: Boolean = true,
+ val isUpdatable: Boolean = false,
+ val icon: Drawable? = null,
+ val settings: PluginCenterItemSettings? = null,
+)
diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItemAdapter.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItemAdapter.kt
new file mode 100644
index 00000000..b6ea67a6
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItemAdapter.kt
@@ -0,0 +1,32 @@
+package org.autojs.autojs.core.plugin.center
+
+import android.annotation.SuppressLint
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+import org.autojs.autojs6.databinding.PluginCenterRecyclerViewItemBinding
+
+@SuppressLint("NotifyDataSetChanged")
+class PluginCenterItemAdapter : RecyclerView.Adapter() {
+
+ internal var items = emptyList()
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PluginCenterItemViewHolder {
+ val binding = PluginCenterRecyclerViewItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
+ return PluginCenterItemViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: PluginCenterItemViewHolder, position: Int) {
+ holder.bind(items[position])
+ }
+
+ override fun getItemCount() = items.size
+
+ fun items() = items
+
+ fun updateData(newItems: List) {
+ items = newItems
+ notifyDataSetChanged()
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItemSettings.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItemSettings.kt
new file mode 100644
index 00000000..d67dd331
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItemSettings.kt
@@ -0,0 +1,5 @@
+package org.autojs.autojs.core.plugin.center
+
+data class PluginCenterItemSettings(
+ val title: String? = null,
+)
diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItemViewHolder.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItemViewHolder.kt
new file mode 100644
index 00000000..4fcbb7e1
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterItemViewHolder.kt
@@ -0,0 +1,187 @@
+package org.autojs.autojs.core.plugin.center
+
+import android.content.res.ColorStateList
+import android.graphics.ColorMatrix
+import android.graphics.ColorMatrixColorFilter
+import android.graphics.PorterDuff
+import android.view.View
+import android.widget.ImageView
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.appcompat.content.res.AppCompatResources
+import androidx.core.graphics.drawable.DrawableCompat
+import androidx.core.view.isVisible
+import androidx.core.widget.ImageViewCompat
+import androidx.recyclerview.widget.RecyclerView
+import de.hdodenhof.circleimageview.CircleImageView
+import org.autojs.autojs.theme.ThemeColorManager
+import org.autojs.autojs.util.ColorUtils
+import org.autojs.autojs.util.ViewUtils
+import org.autojs.autojs6.R
+import org.autojs.autojs6.databinding.PluginCenterRecyclerViewItemBinding
+import org.joda.time.DateTime
+import org.joda.time.format.DateTimeFormat
+
+class PluginCenterItemViewHolder(itemViewBinding: PluginCenterRecyclerViewItemBinding) : RecyclerView.ViewHolder(itemViewBinding.root) {
+
+ private val context = itemViewBinding.root.context
+
+ private val themeColor
+ get() = ThemeColorManager.colorPrimary
+ private val adjustedTextContrastColor
+ get() = ColorUtils.adjustColorForContrast(context.getColor(R.color.window_background), themeColor, 3.2)
+ private val adjustedImageContrastColor
+ get() = ColorUtils.adjustColorForContrast(context.getColor(R.color.window_background), themeColor, 2.3)
+
+ private val iconView: CircleImageView = itemViewBinding.icon
+
+ private val titleView = itemViewBinding.title
+ private val versionInfoView = itemViewBinding.versionInfo
+ private val authorView = itemViewBinding.author
+ private val descriptionView = itemViewBinding.description
+
+ private val switchView = itemViewBinding.sw
+
+ private val updatableBadgeView = itemViewBinding.updatableBadge
+ private val updatableBadgeTextView = itemViewBinding.updatableBadgeText
+ private val versionInfoForUpdateView = itemViewBinding.versionInfoForUpdate
+
+ private val btnDeleteView = itemViewBinding.btnDelete
+ private val btnUpdateView = itemViewBinding.btnUpdate
+ private val btnSettingsView = itemViewBinding.btnSettings
+ private val btnDetailsView = itemViewBinding.btnDetails
+
+ fun bind(item: PluginCenterItem) {
+ item.icon?.let { iconView.setImageDrawable(it) } ?: AppCompatResources.getDrawable(
+ iconView.context,
+ R.drawable.ic_plugin_center_default
+ )?.mutate()?.let { d ->
+ DrawableCompat.setTint(d, adjustedImageContrastColor)
+ DrawableCompat.setTintMode(d, PorterDuff.Mode.SRC_IN)
+ iconView.setImageDrawable(d)
+ } ?: iconView.setImageResource(R.mipmap.ic_app_shortcut_plugin_center_adaptive_round)
+
+ switchView.isChecked = item.isEnabled
+
+ titleView.text = item.title
+ versionInfoView.text = formatVersionInfo(item.versionName, item.versionCode, item.versionDate)
+ authorView.text = item.author
+ descriptionView.text = item.description
+
+ btnDeleteView.setButtonState(true) {
+ ViewUtils.showToast(context, R.string.text_under_development)
+ }
+ if (item.isUpdatable) {
+ updatableBadgeView.isVisible = true
+ versionInfoForUpdateView.isVisible = true
+ versionInfoForUpdateView.text = formatVersionInfo(item.versionName, item.versionCode?.let { it + 16 }, item.versionDate?.let {
+ DateTime.parse(it).plusDays(3).toString("yyyy-MM-dd")
+ })
+ btnUpdateView.setButtonState(true) {
+ ViewUtils.showToast(context, R.string.text_under_development)
+ }
+ } else {
+ updatableBadgeView.isVisible = false
+ versionInfoForUpdateView.isVisible = false
+ btnUpdateView.setButtonState(false) {
+ ViewUtils.showToast(context, R.string.text_unavailable)
+ }
+ }
+ if (item.settings != null) {
+ btnSettingsView.setButtonState(true) {
+ ViewUtils.showToast(context, R.string.text_under_development)
+ }
+ } else {
+ btnSettingsView.setButtonState(false) {
+ ViewUtils.showToast(context, R.string.text_unavailable)
+ }
+ }
+ btnDetailsView.setButtonState(true) {
+ ViewUtils.showToast(context, R.string.text_under_development)
+ }
+
+ applyUiBySwitch(switchView.isChecked, item)
+
+ switchView.setOnCheckedChangeListener { _, isChecked ->
+ applyUiBySwitch(isChecked, item)
+ }
+ }
+
+ private fun formatVersionInfo(versionName: String, versionCode: Long?, versionDate: String?): String {
+ val code = versionCode?.takeIf { it > 0 }
+ val date = versionDate?.runCatching {
+ DateTimeFormat.forPattern("yyyy-MM-dd").print(DateTime.parse(this))
+ }?.getOrNull()
+ return buildString {
+ append(versionName)
+ code?.let { append(" ($it)") }
+ date?.let { append(" | $it") }
+ }
+ }
+
+ private fun LinearLayout.setButtonState(enabled: Boolean, onClickListener: View.OnClickListener) {
+ isEnabled = enabled
+ this.setOnClickListener(onClickListener)
+ }
+
+ private fun applyUiBySwitch(isOn: Boolean, item: PluginCenterItem) {
+ val colorPrimary = context.getColor(R.color.text_color_primary)
+ val colorPrimaryA50 = context.getColor(R.color.text_color_primary_alpha_50)
+ val colorPrimaryA30 = context.getColor(R.color.text_color_primary_alpha_30)
+ val colorPrimaryA20 = context.getColor(R.color.text_color_primary_alpha_20)
+
+ btnDeleteView.setActionColors(iconColor = colorPrimaryA50, textColor = colorPrimary)
+
+ if (btnUpdateView.isEnabled) {
+ if (isOn) {
+ btnUpdateView.setActionColors(iconColor = adjustedImageContrastColor, textColor = adjustedTextContrastColor)
+ } else {
+ btnUpdateView.setActionColors(iconColor = colorPrimaryA50, textColor = colorPrimary)
+ }
+ } else {
+ btnUpdateView.setActionColors(iconColor = colorPrimaryA20, textColor = colorPrimaryA30)
+ }
+
+ if (item.settings == null) {
+ btnSettingsView.setActionColors(iconColor = colorPrimaryA20, textColor = colorPrimaryA30)
+ } else {
+ btnSettingsView.setActionColors(iconColor = colorPrimaryA50, textColor = colorPrimary)
+ }
+
+ btnDetailsView.setActionColors(iconColor = colorPrimaryA50, textColor = colorPrimary)
+
+ if (isOn) {
+ versionInfoForUpdateView.setTextColor(adjustedTextContrastColor)
+ updatableBadgeTextView.setTextColor(adjustedTextContrastColor)
+ } else {
+ versionInfoForUpdateView.setTextColor(colorPrimary)
+ updatableBadgeTextView.setTextColor(colorPrimary)
+ }
+
+ if (isOn) {
+ iconView.colorFilter = null
+ } else {
+ // Construct the desaturation matrix.
+ // zh-CN: 构造灰度矩阵.
+ val desaturate = ColorMatrix().apply { setSaturation(0f) }
+ // Construct the alpha scaling matrix.
+ // zh-CN: 构造透明度缩放矩阵.
+ val alphaMatrix = ColorMatrix().apply { setScale(1f, 1f, 1f, 0.5f) }
+ // Concatenate: first desaturate, then apply alpha.
+ // zh-CN: 叠加: 先灰度, 再透明度.
+ desaturate.postConcat(alphaMatrix)
+ iconView.colorFilter = ColorMatrixColorFilter(desaturate)
+ }
+ }
+
+ private fun LinearLayout.setActionColors(iconColor: Int, textColor: Int) {
+ val imageView = getChildAtOrNull(0) as? ImageView
+ val textView = getChildAtOrNull(1) as? TextView
+ imageView?.let { ImageViewCompat.setImageTintList(it, ColorStateList.valueOf(iconColor)) }
+ textView?.setTextColor(textColor)
+ }
+
+ private fun LinearLayout.getChildAtOrNull(index: Int) = if (index in 0 until childCount) getChildAt(index) else null
+
+}
+
diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterViewModel.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterViewModel.kt
new file mode 100644
index 00000000..9111b3ee
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginCenterViewModel.kt
@@ -0,0 +1,82 @@
+package org.autojs.autojs.core.plugin.center
+
+import android.content.Context
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import kotlinx.coroutines.async
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.launch
+import org.autojs.autojs6.R
+
+/**
+ * Loads both index plugins and locally installed plugins,
+ * merging them into a PluginCenterItem list.
+ *
+ * zh-CN: 统一加载索引插件与本地已安装插件, 合并为 PluginCenterItem 列表.
+ */
+class PluginCenterViewModel : ViewModel() {
+
+ private val indexRepo = PluginIndexRepository()
+ private val installedRepo = InstalledPluginRepository()
+
+ private val _items = MutableStateFlow>(emptyList())
+ val items: StateFlow> = _items
+
+ fun load(context: Context) {
+ viewModelScope.launch {
+ val idxDeferred = async { runCatching { indexRepo.fetchOfficialIndex(context) }.getOrElse { emptyList() } }
+ val insDeferred = async { runCatching { installedRepo.discoverInstalled(context) }.getOrElse { emptyList() } }
+
+ val indexEntries = idxDeferred.await()
+ val installed = insDeferred.await()
+
+ val installedByPkg = installed.associateBy { it.packageName }
+
+ // 1. Use index to drive UI first (ensuring "installable but not installed" items are displayed).
+ // 1. [ zh-CN ] 优先用索引驱动 UI (确保 "未安装但可安装" 的项也能显示).
+ val fromIndex = indexEntries.map { e ->
+ val local = installedByPkg[e.packageName]
+ toPluginCenterItem(context, index = e, local = local)
+ }
+
+ // 2. Add items that "exist locally but not in index" (third-party or not indexed yet).
+ // 2. [ zh-CN ] 补充 "本地存在但索引里暂时没有" 的项 (第三方或暂未入索引).
+ val extraLocals = installed
+ .filter { ins -> indexEntries.none { it.packageName == ins.packageName } }
+ .map { local -> toPluginCenterItem(context, index = null, local = local) }
+
+ _items.value = fromIndex + extraLocals
+ }
+ }
+
+ private fun toPluginCenterItem(context: Context, index: PluginIndexEntry?, local: InstalledPluginRepository.InstalledPlugin?): PluginCenterItem {
+ val packageName = local?.packageName ?: index?.packageName.orEmpty()
+ val title = local?.title ?: index?.title ?: packageName
+ val description = local?.description ?: index?.description.orEmpty()
+ val author = local?.author ?: index?.author
+ val collaborators = index?.collaborators ?: emptyList()
+
+ val versionName = local?.versionName ?: index?.versionName ?: context.getString(R.string.text_unknown)
+ val localCode = local?.versionCode
+ val indexCode = index?.versionCode
+
+ val isInstalled = local != null
+ val isUpdatable = isInstalled && (indexCode != null && indexCode > (localCode ?: -1))
+
+ return PluginCenterItem(
+ packageName = packageName,
+ title = title,
+ description = description,
+ author = author,
+ collaborators = collaborators,
+ versionName = versionName,
+ versionCode = localCode ?: indexCode,
+ versionDate = index?.versionDate, // M1: 显示索引日期; 仅本地项时可为空
+ isEnabled = true, // M1: 先统一 true, M2 再接入启用状态持久化
+ isUpdatable = isUpdatable,
+ icon = local?.icon, // 已安装优先用应用图标; 未安装走默认占位图
+ settings = null, // M1 暂不接入单插件设置入口
+ )
+ }
+}
diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginIndexEntry.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginIndexEntry.kt
new file mode 100644
index 00000000..0fc65493
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginIndexEntry.kt
@@ -0,0 +1,27 @@
+package org.autojs.autojs.core.plugin.center
+
+import android.net.Uri
+
+data class PluginIndexEntry(
+ val packageName: String,
+ val iconUrl: Uri? = null,
+
+ val title: String,
+ val description: String,
+
+ val author: String? = null,
+ val collaborators: List = emptyList(),
+
+ /** @sample "paddle-ocr" */
+ val engine: String? = null,
+ /** @sample "v5" */
+ val variant: String? = null,
+ /** @sample "paddle-ocr-v5" */
+ val engineId: String? = null,
+
+ val versionName: String,
+ val versionCode: Long? = null,
+ val versionDate: String? = null,
+
+ val tags: List = emptyList(),
+)
diff --git a/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginIndexRepository.kt b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginIndexRepository.kt
new file mode 100644
index 00000000..d62fd9f0
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/core/plugin/center/PluginIndexRepository.kt
@@ -0,0 +1,30 @@
+package org.autojs.autojs.core.plugin.center
+
+import android.content.Context
+
+/**
+ * 官方插件索引仓库 (M1: 内置静态; M2 再接入网络/ETag/缓存).
+ */
+class PluginIndexRepository {
+
+ suspend fun fetchOfficialIndex(context: Context): List {
+ // M1 先预置 1 条官方样例 "Paddle OCR (PP-OCRv5)", 便于与本地已安装合并显示.
+ return listOf(
+ PluginIndexEntry(
+ packageName = "io.github.supermonster003.autojs6.plugin.paddleocr.v5",
+ title = "Paddle OCR (PP-OCRv5)",
+ description = "百度飞桨光学字符识别插件",
+ author = "SuperMonster003",
+ collaborators = emptyList(),
+ versionName = "0.1.0",
+ versionCode = 17L,
+ versionDate = "2025-11-21",
+ iconUrl = null, // M1 暂不拉网图标, 使用应用图标或默认图标.
+ tags = listOf("official", "ocr", "paddle", "v5"),
+ engine = "paddle-ocr",
+ variant = "v5",
+ engineId = "paddle-ocr-v5",
+ ),
+ )
+ }
+}
diff --git a/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.kt b/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.kt
index c916c0b4..ef904a1f 100644
--- a/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.kt
+++ b/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.kt
@@ -2,7 +2,6 @@ package org.autojs.autojs.ui.main.drawer
import android.annotation.SuppressLint
import android.content.Context
-import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@@ -15,6 +14,7 @@ import org.autojs.autojs.app.tool.FloatingButtonTool
import org.autojs.autojs.app.tool.JsonSocketClientTool
import org.autojs.autojs.app.tool.JsonSocketServerTool
import org.autojs.autojs.core.accessibility.AccessibilityTool
+import org.autojs.autojs.core.plugin.center.PluginCenterActivity
import org.autojs.autojs.core.pref.Pref
import org.autojs.autojs.permission.DisplayOverOtherAppsPermission
import org.autojs.autojs.permission.IgnoreBatteryOptimizationsPermission
@@ -410,12 +410,8 @@ open class DrawerFragment : Fragment() {
}
private fun setupListeners() {
- binding.settings.setOnClickListener { view ->
- startActivity(
- Intent(view.context, PreferencesActivity::class.java)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- )
- }
+ binding.settings.setOnClickListener { PreferencesActivity.launch(it.context) }
+ binding.pluginCenter.setOnClickListener { PluginCenterActivity.startActivity(it.context) }
binding.restart.setOnClickListener { restart(mActivity, mActivity::beforeExit) }
binding.exit.setOnClickListener { exit(mActivity, mActivity::beforeExit) }
}
diff --git a/app/src/main/java/org/autojs/autojs/ui/settings/LauncherShortcutsPreference.kt b/app/src/main/java/org/autojs/autojs/ui/settings/LauncherShortcutsPreference.kt
index 022b98b7..61de2a01 100644
--- a/app/src/main/java/org/autojs/autojs/ui/settings/LauncherShortcutsPreference.kt
+++ b/app/src/main/java/org/autojs/autojs/ui/settings/LauncherShortcutsPreference.kt
@@ -5,6 +5,7 @@ import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.core.content.pm.ShortcutManagerCompat
import com.afollestad.materialdialogs.MaterialDialog
+import org.autojs.autojs.core.plugin.center.PluginCenterActivity
import org.autojs.autojs.theme.preference.MaterialPreference
import org.autojs.autojs.ui.doc.DocumentationActivity
import org.autojs.autojs.ui.log.LogActivity
@@ -21,43 +22,60 @@ class LauncherShortcutsPreference : MaterialPreference {
val binding = SelectLauncherShortcutBinding.inflate(LayoutInflater.from(prefContext))
- MaterialDialog.Builder(prefContext)
- .customView(binding.root, true)
+ val dialog = MaterialDialog.Builder(prefContext)
+ .customView(binding.root, false)
.build()
- .also { dialog ->
- binding.launcherShortcutSettings.setOnClickListener {
- ShortcutUtils.requestPinShortcut(
- prefContext,
- R.string.id_launcher_shortcut_settings,
- PreferencesActivity::class.java.name,
- R.string.text_app_shortcut_settings_long_label,
- R.string.text_app_shortcut_settings_short_label,
- R.mipmap.ic_app_shortcut_settings_adaptive,
- ).also { dialog.dismiss() }
- }
- binding.launcherShortcutDocs.setOnClickListener {
- ShortcutUtils.requestPinShortcut(
- prefContext,
- R.string.id_launcher_shortcut_docs,
- DocumentationActivity::class.java.name,
- R.string.text_app_shortcut_docs_long_label,
- R.string.text_app_shortcut_docs_short_label,
- R.mipmap.ic_app_shortcut_docs_adaptive,
- ).also { dialog.dismiss() }
- }
+ dialog.window?.apply {
+ setBackgroundDrawable(null)
+ setDimAmount(0.64f)
+ }
- binding.launcherShortcutLog.setOnClickListener {
- ShortcutUtils.requestPinShortcut(
- prefContext,
- R.string.id_launcher_shortcut_log,
- LogActivity::class.java.name,
- R.string.text_app_shortcut_log_long_label,
- R.string.text_app_shortcut_log_short_label,
- R.mipmap.ic_app_shortcut_log_adaptive,
- ).also { dialog.dismiss() }
- }
- }
+ binding.launcherShortcutSettings.setOnClickListener {
+ ShortcutUtils.requestPinShortcut(
+ prefContext,
+ R.string.id_launcher_shortcut_settings,
+ PreferencesActivity::class.java.name,
+ R.string.text_app_shortcut_settings_long_label,
+ R.string.text_app_shortcut_settings_short_label,
+ R.mipmap.ic_app_shortcut_settings_adaptive,
+ ).also { dialog.dismiss() }
+ }
+
+ binding.launcherShortcutDocs.setOnClickListener {
+ ShortcutUtils.requestPinShortcut(
+ prefContext,
+ R.string.id_launcher_shortcut_docs,
+ DocumentationActivity::class.java.name,
+ R.string.text_app_shortcut_docs_long_label,
+ R.string.text_app_shortcut_docs_short_label,
+ R.mipmap.ic_app_shortcut_docs_adaptive,
+ ).also { dialog.dismiss() }
+ }
+
+ binding.launcherShortcutLog.setOnClickListener {
+ ShortcutUtils.requestPinShortcut(
+ prefContext,
+ R.string.id_launcher_shortcut_log,
+ LogActivity::class.java.name,
+ R.string.text_app_shortcut_log_long_label,
+ R.string.text_app_shortcut_log_short_label,
+ R.mipmap.ic_app_shortcut_log_adaptive,
+ ).also { dialog.dismiss() }
+ }
+
+ binding.launcherShortcutPluginCenter.setOnClickListener {
+ ShortcutUtils.requestPinShortcut(
+ prefContext,
+ R.string.id_launcher_shortcut_plugin_center,
+ PluginCenterActivity::class.java.name,
+ R.string.text_app_shortcut_plugin_center_long_label,
+ R.string.text_app_shortcut_plugin_center_short_label,
+ R.mipmap.ic_app_shortcut_plugin_center_adaptive,
+ ).also { dialog.dismiss() }
+ }
+
+ return@lazy dialog
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)
diff --git a/app/src/main/res/drawable-xhdpi/ic_search_smaller_black_48dp.png b/app/src/main/res/drawable-xhdpi/ic_search_smaller_black_48dp.png
new file mode 100644
index 00000000..314d758c
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_search_smaller_black_48dp.png differ
diff --git a/app/src/main/res/drawable/ic_app_shortcut_plugin_center_adaptive_foreground.xml b/app/src/main/res/drawable/ic_app_shortcut_plugin_center_adaptive_foreground.xml
new file mode 100644
index 00000000..68ec4466
--- /dev/null
+++ b/app/src/main/res/drawable/ic_app_shortcut_plugin_center_adaptive_foreground.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_jigsaw.png b/app/src/main/res/drawable/ic_jigsaw.png
new file mode 100644
index 00000000..2ab560f5
Binary files /dev/null and b/app/src/main/res/drawable/ic_jigsaw.png differ
diff --git a/app/src/main/res/drawable/ic_plugin_center_default.xml b/app/src/main/res/drawable/ic_plugin_center_default.xml
new file mode 100644
index 00000000..93d7bb3e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_plugin_center_default.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_plugin_paddle_ocr.png b/app/src/main/res/drawable/ic_plugin_paddle_ocr.png
new file mode 100644
index 00000000..5bfc0989
Binary files /dev/null and b/app/src/main/res/drawable/ic_plugin_paddle_ocr.png differ
diff --git a/app/src/main/res/drawable/ic_power_switch.png b/app/src/main/res/drawable/ic_power_switch.png
new file mode 100644
index 00000000..f4004a3c
Binary files /dev/null and b/app/src/main/res/drawable/ic_power_switch.png differ
diff --git a/app/src/main/res/drawable/ic_settings.png b/app/src/main/res/drawable/ic_settings.png
new file mode 100644
index 00000000..0e7dc27a
Binary files /dev/null and b/app/src/main/res/drawable/ic_settings.png differ
diff --git a/app/src/main/res/layout/activity_plugin_center.xml b/app/src/main/res/layout/activity_plugin_center.xml
new file mode 100644
index 00000000..9b89959b
--- /dev/null
+++ b/app/src/main/res/layout/activity_plugin_center.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_drawer.xml b/app/src/main/res/layout/fragment_drawer.xml
index 12e144c1..f23629ca 100644
--- a/app/src/main/res/layout/fragment_drawer.xml
+++ b/app/src/main/res/layout/fragment_drawer.xml
@@ -22,100 +22,130 @@
+ android:layout_gravity="center|bottom"
+ android:orientation="vertical">
+ android:textSize="12sp" />
+
+
+
+
+
+
+
+ android:layout_gravity="center|bottom"
+ android:orientation="vertical">
+ android:textSize="12sp" />
+ android:layout_gravity="center|bottom"
+ android:orientation="vertical">
+ android:textColor="?android:textColorPrimary"
+ android:textSize="12sp" />
diff --git a/app/src/main/res/layout/fragment_plugin_center.xml b/app/src/main/res/layout/fragment_plugin_center.xml
new file mode 100644
index 00000000..9e16f858
--- /dev/null
+++ b/app/src/main/res/layout/fragment_plugin_center.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/plugin_center_recycler_view_item.xml b/app/src/main/res/layout/plugin_center_recycler_view_item.xml
new file mode 100644
index 00000000..0cbb817e
--- /dev/null
+++ b/app/src/main/res/layout/plugin_center_recycler_view_item.xml
@@ -0,0 +1,317 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/select_launcher_shortcut.xml b/app/src/main/res/layout/select_launcher_shortcut.xml
index dfb01d2e..a532dac5 100644
--- a/app/src/main/res/layout/select_launcher_shortcut.xml
+++ b/app/src/main/res/layout/select_launcher_shortcut.xml
@@ -1,118 +1,189 @@
-
+
+
+
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:focusable="true">
-
-
-
+
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:maxLines="2"
+ android:ellipsize="end"
+ android:gravity="center"
+ android:layout_gravity="center|bottom"
+ android:layout_marginTop="6dp"
+ android:textColor="@color/night"
+ tools:textColor="@color/day_night"
+ android:clickable="false"
+ android:focusable="false"
+ android:text="@string/text_app_shortcut_settings_short_label" />
+ android:id="@+id/launcher_shortcut_docs"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:focusable="true">
-
+
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:maxLines="2"
+ android:ellipsize="end"
+ android:gravity="center"
+ android:layout_gravity="center|bottom"
+ android:layout_marginTop="6dp"
+ android:textColor="@color/night"
+ tools:textColor="@color/day_night"
+ android:clickable="false"
+ android:focusable="false"
+ android:text="@string/text_app_shortcut_docs_short_label" />
+ android:id="@+id/launcher_shortcut_log"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical"
+ android:clickable="true"
+ android:focusable="true">
-
+
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:maxLines="2"
+ android:ellipsize="end"
+ android:gravity="center"
+ android:layout_gravity="center|bottom"
+ android:layout_marginTop="6dp"
+ android:textColor="@color/night"
+ tools:textColor="@color/day_night"
+ android:clickable="false"
+ android:focusable="false"
+ android:text="@string/text_app_shortcut_log_short_label" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_main.xml b/app/src/main/res/menu/menu_main.xml
index 8cb85163..545a01a6 100644
--- a/app/src/main/res/menu/menu_main.xml
+++ b/app/src/main/res/menu/menu_main.xml
@@ -11,7 +11,7 @@
-
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_app_shortcut_plugin_center_adaptive_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_app_shortcut_plugin_center_adaptive_round.xml
new file mode 100644
index 00000000..b8113512
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_app_shortcut_plugin_center_adaptive_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_app_shortcut_plugin_center_adaptive.png b/app/src/main/res/mipmap-hdpi/ic_app_shortcut_plugin_center_adaptive.png
new file mode 100644
index 00000000..db441827
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_app_shortcut_plugin_center_adaptive.png differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_app_shortcut_plugin_center_adaptive_round.png b/app/src/main/res/mipmap-hdpi/ic_app_shortcut_plugin_center_adaptive_round.png
new file mode 100644
index 00000000..bf3ef1ef
Binary files /dev/null and b/app/src/main/res/mipmap-hdpi/ic_app_shortcut_plugin_center_adaptive_round.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_app_shortcut_plugin_center_adaptive.png b/app/src/main/res/mipmap-mdpi/ic_app_shortcut_plugin_center_adaptive.png
new file mode 100644
index 00000000..47fd6dd7
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_app_shortcut_plugin_center_adaptive.png differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_app_shortcut_plugin_center_adaptive_round.png b/app/src/main/res/mipmap-mdpi/ic_app_shortcut_plugin_center_adaptive_round.png
new file mode 100644
index 00000000..a30e1d10
Binary files /dev/null and b/app/src/main/res/mipmap-mdpi/ic_app_shortcut_plugin_center_adaptive_round.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_app_shortcut_plugin_center_adaptive.png b/app/src/main/res/mipmap-xhdpi/ic_app_shortcut_plugin_center_adaptive.png
new file mode 100644
index 00000000..a2bf6819
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_app_shortcut_plugin_center_adaptive.png differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_app_shortcut_plugin_center_adaptive_round.png b/app/src/main/res/mipmap-xhdpi/ic_app_shortcut_plugin_center_adaptive_round.png
new file mode 100644
index 00000000..836d7f9b
Binary files /dev/null and b/app/src/main/res/mipmap-xhdpi/ic_app_shortcut_plugin_center_adaptive_round.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_app_shortcut_plugin_center_adaptive.png b/app/src/main/res/mipmap-xxhdpi/ic_app_shortcut_plugin_center_adaptive.png
new file mode 100644
index 00000000..1028c6e4
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_app_shortcut_plugin_center_adaptive.png differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_app_shortcut_plugin_center_adaptive_round.png b/app/src/main/res/mipmap-xxhdpi/ic_app_shortcut_plugin_center_adaptive_round.png
new file mode 100644
index 00000000..100073f5
Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/ic_app_shortcut_plugin_center_adaptive_round.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_app_shortcut_plugin_center_adaptive.png b/app/src/main/res/mipmap-xxxhdpi/ic_app_shortcut_plugin_center_adaptive.png
new file mode 100644
index 00000000..d3ab2e37
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_app_shortcut_plugin_center_adaptive.png differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_app_shortcut_plugin_center_adaptive_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_app_shortcut_plugin_center_adaptive_round.png
new file mode 100644
index 00000000..78039032
Binary files /dev/null and b/app/src/main/res/mipmap-xxxhdpi/ic_app_shortcut_plugin_center_adaptive_round.png differ
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 533a953c..13e1a8cb 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -1079,5 +1079,14 @@
اكتب إعدادات الأمان
إعدادات النظام الآمنة ، التي تحتوي على تفضيلات النظام التي يمكن أن تقرأها التطبيقات ولكن لا يُسمح لها بالكتابة.\nهذه هي لتفضيلات يجب على المستخدم تعديلها بشكل صريح من خلال واجهة المستخدم لتطبيق النظام.\nمع إذن إعدادات النظام الآمن ، يمكن للتطبيقات العادية تعديل الإعدادات الآمنة مباشرة (مثل خدمة إمكانية الوصول).
كتابة إعدادات النظام
+ Update
+ Plugin center
+ Plugins
+ Updatable
+ Uninstall
+ AutoJs6 Plugin Center
+ Plugins
+ Click icon to add launcher shortcut
+ Click other areas to exit selection
diff --git a/app/src/main/res/values-en/strings.xml b/app/src/main/res/values-en/strings.xml
index 6d04d89d..602fb39d 100644
--- a/app/src/main/res/values-en/strings.xml
+++ b/app/src/main/res/values-en/strings.xml
@@ -1074,5 +1074,14 @@
Write security settings
Secure system settings, containing system preferences that applications can read but are not allowed to write.\nThese are for preferences that the user must explicitly modify through the UI of a system app.\nWith secure system settings permission, normal applications can directly modify the secure settings (such as accessibility service).
Write system settings
+ Update
+ Plugin center
+ Plugins
+ Updatable
+ Uninstall
+ AutoJs6 Plugin Center
+ Plugins
+ Click icon to add launcher shortcut
+ Click other areas to exit selection
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index a24e66eb..cb0f0b2c 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -1077,5 +1077,14 @@
Escribir la configuración de seguridad
Ajustes de seguridad del sistema, que contienen preferencias del sistema que las aplicaciones pueden leer pero no pueden escribir.\nSe trata de preferencias que el usuario debe modificar explícitamente a través de la interfaz de usuario de una aplicación del sistema.\nCon el permiso de configuración segura del sistema, las aplicaciones normales pueden modificar directamente la configuración segura (como el servicio de accesibilidad).
Escribir la configuración del sistema
+ Update
+ Plugin center
+ Plugins
+ Updatable
+ Uninstall
+ AutoJs6 Plugin Center
+ Plugins
+ Click icon to add launcher shortcut
+ Click other areas to exit selection
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index f926a325..b4501dff 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -1077,5 +1077,14 @@
Écrire les paramètres de sécurité.
Paramètres de sécurité du système, contenant les préférences du système que les applications peuvent lire mais ne sont pas autorisées à écrire.\nIl s\'agit des préférences que l\'utilisateur doit explicitement modifier par le biais de l\'interface utilisateur d\'une application système.\nAvec l\'autorisation de paramètres de sécurité du système, les applications normales peuvent directement modifier les paramètres de sécurité (comme le service d\'accessibilité).
Écrire les paramètres système
+ Update
+ Plugin center
+ Plugins
+ Updatable
+ Uninstall
+ AutoJs6 Plugin Center
+ Plugins
+ Click icon to add launcher shortcut
+ Click other areas to exit selection
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index 2f40aca9..c0f7d28c 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -1078,5 +1078,14 @@
セキュリティ設定の書き込み
アプリケーションが読み取ることはできるが, 書き込むことはできないシステム環境設定を含む, 安全なシステム設定です.\nこれは, ユーザーがシステムアプリの UI を通じて明示的に変更する必要がある環境設定のためのものです.\nセキュアなシステム設定を許可すると, 通常のアプリケーションはセキュアな設定 (アクセシビリティサービスなど) を直接変更できるようになります
システム設定の書き込み
+ Update
+ Plugin center
+ Plugins
+ Updatable
+ Uninstall
+ AutoJs6 Plugin Center
+ Plugins
+ Click icon to add launcher shortcut
+ Click other areas to exit selection
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 4e865d76..acac1d59 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -1079,5 +1079,14 @@
보안 설정을 작성하십시오
애플리케이션이 읽을 수 있지만 쓸 수없는 시스템 환경 설정을 포함하는 보안 시스템 설정.\n이들은 사용자가 시스템 앱의 UI 를 통해 명시 적으로 수정 해야하는 선호도입니다.\n보안 시스템 설정 권한을 사용하면 일반 애플리케이션이 보안 설정 (예: 접근성 서비스)을 직접 수정할 수 있습니다.
시스템 설정을 작성하십시오
+ Update
+ Plugin center
+ Plugins
+ Updatable
+ Uninstall
+ AutoJs6 Plugin Center
+ Plugins
+ Click icon to add launcher shortcut
+ Click other areas to exit selection
diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml
index 1ac089dc..9313cc72 100644
--- a/app/src/main/res/values-night/colors.xml
+++ b/app/src/main/res/values-night/colors.xml
@@ -6,6 +6,7 @@
#B3BFBFBF
#9ABFBFBF
#80BFBFBF
+ #66BFBFBF
#4DBFBFBF
#33BFBFBF
@color/dawn
@@ -15,7 +16,11 @@
@color/day_night
@color/day_night_full
@color/day_night_alpha_70
- #808080
+ @color/day_night_alpha_50
+ @color/day_night_alpha_40
+ @color/day_night_alpha_30
+ @color/day_night_alpha_20
+ #808080
#DFE0E0E0
#7F7F80
@@ -49,6 +54,7 @@
#26E2E5EA
@color/prefTextColorPrimary
@color/prefTextColorSecondary
+ #26E2E5EA
#808080
#9A9A9A
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index ecb6cf1a..8f62c48c 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -1077,5 +1077,14 @@
Параметры безопасности записи
Настройки безопасности системы, содержащие системные предпочтения, которые приложения могут читать, но не имеют права записывать.\nОни предназначены для параметров, которые пользователь должен явно изменить через пользовательский интерфейс системного приложения.\nПри наличии разрешения на безопасные системные настройки обычные приложения могут напрямую изменять безопасные настройки (например, служба доступности).
Запись системных настроек
+ Update
+ Plugin center
+ Plugins
+ Updatable
+ Uninstall
+ AutoJs6 Plugin Center
+ Plugins
+ Click icon to add launcher shortcut
+ Click other areas to exit selection
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index 91029ae4..934a33a6 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -1075,5 +1075,14 @@
修改安全設置
安全設置包含應用程序可讀但不可寫入的設置選項, 這些選項只能由 UI 或系統級別應用修改.\n被授予 \"修改安全設置權限\" 後, 普通應用可直接修改上述安全設置 (例如無障礙服務).
修改系統設置
+ Update
+ Plugin center
+ Plugins
+ Updatable
+ Uninstall
+ AutoJs6 Plugin Center
+ Plugins
+ Click icon to add launcher shortcut
+ Click other areas to exit selection
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index 79e2b9f3..050cf68e 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -1075,5 +1075,14 @@
修改安全設定
安全設定包含應用程式可讀但不可寫入的設定選項, 這些選項只能由 UI 或系統級別應用修改.\n被授予 \"修改安全設定許可權\" 後, 普通應用可直接修改上述安全設定 (例如無障礙服務).
修改系統設定
+ Update
+ Plugin center
+ Plugins
+ Updatable
+ Uninstall
+ AutoJs6 Plugin Center
+ Plugins
+ Click icon to add launcher shortcut
+ Click other areas to exit selection
diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml
index 45ca0450..1e2765d6 100644
--- a/app/src/main/res/values-zh/strings.xml
+++ b/app/src/main/res/values-zh/strings.xml
@@ -1075,5 +1075,14 @@
修改安全设置
安全设置包含应用程序可读但不可写入的设置选项, 这些选项只能由 UI 或系统级别应用修改.\n被授予 \"修改安全设置权限\" 后, 普通应用可直接修改上述安全设置 (例如无障碍服务).
修改系统设置
+ 更新
+ 插件中心
+ 插件
+ 可更新
+ 卸载
+ AutoJs6 插件中心
+ 插件
+ 点击图标添加启动器快捷方式
+ 点击其他区域退出选择
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
index 4a1ca795..971828cf 100644
--- a/app/src/main/res/values/colors.xml
+++ b/app/src/main/res/values/colors.xml
@@ -24,6 +24,7 @@
#B3212121
#9A212121
#80212121
+ #66212121
#4D212121
#33212121
@color/night
@@ -35,7 +36,11 @@
@color/day_night
@color/day_night_full
@color/day_night_alpha_70
- #9DA0A2
+ @color/day_night_alpha_50
+ @color/day_night_alpha_40
+ @color/day_night_alpha_30
+ @color/day_night_alpha_20
+ #9DA0A2
#66000000
#70000000
@@ -129,6 +134,7 @@
#261B1F24
#24292F
#57606A
+ #261B1F24
#2B7A85
#CC7A34
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
index c6890de9..816c8925 100644
--- a/app/src/main/res/values/dimens.xml
+++ b/app/src/main/res/values/dimens.xml
@@ -4,6 +4,8 @@
42dp
60dp
54dp
+ 64dp
+ 1dp
16dp
6dp
16dp
diff --git a/app/src/main/res/values/ic_app_shortcut_plugin_center_adaptive_background.xml b/app/src/main/res/values/ic_app_shortcut_plugin_center_adaptive_background.xml
new file mode 100644
index 00000000..03072f84
--- /dev/null
+++ b/app/src/main/res/values/ic_app_shortcut_plugin_center_adaptive_background.xml
@@ -0,0 +1,4 @@
+
+
+ #68AA1C
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index b002b3fc..e9bb2689 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -54,6 +54,7 @@
%.2fMB/%.2fMB
shortcut_$_docs
shortcut_$_log
+ shortcut_$_plugin_center
shortcut_$_settings
key_$_a11y_service
key_$_about_app_and_developer
@@ -1328,5 +1329,14 @@
Write security settings
Secure system settings, containing system preferences that applications can read but are not allowed to write.\nThese are for preferences that the user must explicitly modify through the UI of a system app.\nWith secure system settings permission, normal applications can directly modify the secure settings (such as accessibility service).
Write system settings
+ Update
+ Plugin center
+ Plugins
+ Updatable
+ Uninstall
+ AutoJs6 Plugin Center
+ Plugins
+ Click icon to add launcher shortcut
+ Click other areas to exit selection
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index 07ccf582..b4f68163 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -24,7 +24,7 @@
- false
- @color/item_background
- @color/text_color_primary
- - @color/text_color_secondly
+ - @color/text_color_secondary
- @color/window_background
- @android:color/transparent
- @color/colorAccent