8 Commits

Author SHA1 Message Date
bb4998d239 Merge branch 'master' of https://github.com/SuperMonster003/AutoJs6
Some checks failed
Android CI / build (push) Has been cancelled
2026-07-28 20:32:45 +08:00
25bd9a866e refactor(accessibility): 重命名无障碍服务类并更新包名
Some checks failed
Android CI / build (push) Has been cancelled
- 将 AccessibilityServiceUsher 类重命名为 SelectToSpeakService
- 将包名从 org.autojs.autojs.core.accessibility 更改为 com.google.android.accessibility.selecttospeak
- 更新 AndroidManifest.xml 中的服务注册名称
- 修改相关导入语句和引用以匹配新的类名和包名
2026-07-28 20:26:59 +08:00
SuperMonster003
ed3eb10e88 Merge pull request #502 from M17764017422/main
feat: 添加底部日志面板功能
2026-03-16 22:48:05 +08:00
ms900
49ea44ec72 feat: 添加底部日志面板功能
- 新增 LogBottomSheet 底部日志面板
- ConsoleView 支持堆栈帧点击跳转
- EditorView 添加 LogPanelCallback 接口
- EditActivity 集成日志面板与代码跳转
- 添加日志菜单项和图标资源
2026-03-16 22:08:01 +08:00
SuperMonster003
9f145340ab Update agpVersionMap for Gradle settings 2026-03-15 15:01:09 +08:00
SuperMonster003
3ce61cf084 Update Temurin version comment and date 2026-03-15 14:56:34 +08:00
SuperMonster003
f6cbb41f90 Merge pull request #490 from iamsanjaymalakar/master
Fix ConcatReader.close() to close all readers on failure
2026-03-14 22:47:17 +08:00
Sanjay Malakar
6474f912a4 Fix ConcatReader.close() to close all readers on failure 2026-03-09 07:59:33 +00:00
19 changed files with 416 additions and 15 deletions

View File

@@ -698,7 +698,7 @@
android:theme="@style/ScriptTheme.Transparent" /> android:theme="@style/ScriptTheme.Transparent" />
<service <service
android:name="org.autojs.autojs.core.accessibility.AccessibilityServiceUsher" android:name="com.google.android.accessibility.selecttospeak.SelectToSpeakService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE" android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE"
android:exported="true"> android:exported="true">

View File

@@ -1,4 +1,4 @@
package org.autojs.autojs.core.accessibility package com.google.android.accessibility.selecttospeak
import android.accessibilityservice.AccessibilityServiceInfo import android.accessibilityservice.AccessibilityServiceInfo
import android.os.Build import android.os.Build
@@ -6,7 +6,7 @@ import android.util.Log
import org.autojs.autojs.core.pref.Pref import org.autojs.autojs.core.pref.Pref
import org.autojs.autojs.core.accessibility.AccessibilityService as CoreAccessibilityService import org.autojs.autojs.core.accessibility.AccessibilityService as CoreAccessibilityService
class AccessibilityServiceUsher : CoreAccessibilityService() { class SelectToSpeakService : CoreAccessibilityService() {
override fun onServiceConnected() { override fun onServiceConnected() {
Log.d(TAG, "onServiceConnected") Log.d(TAG, "onServiceConnected")
@@ -29,7 +29,7 @@ class AccessibilityServiceUsher : CoreAccessibilityService() {
companion object { companion object {
private val TAG = AccessibilityServiceUsher::class.java.simpleName private val TAG = SelectToSpeakService::class.java.simpleName
} }

View File

@@ -383,10 +383,17 @@ public class ConcatReader extends Reader {
@Override @Override
public void close() throws IOException { public void close() throws IOException {
if (closed) return; if (closed) return;
IOException first = null;
for (Reader reader : readerQueue) { for (Reader reader : readerQueue) {
try {
reader.close(); reader.close();
} catch (IOException e) {
if (first == null) first = e;
else first.addSuppressed(e);
}
} }
closed = true; closed = true;
if (first != null) throw first;
} }
/** /**

View File

@@ -7,6 +7,7 @@ import android.provider.Settings
import android.provider.Settings.Secure import android.provider.Settings.Secure
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
import com.google.android.accessibility.selecttospeak.SelectToSpeakService
import org.autojs.autojs.annotation.ScriptInterface import org.autojs.autojs.annotation.ScriptInterface
import org.autojs.autojs.app.GlobalAppContext import org.autojs.autojs.app.GlobalAppContext
import org.autojs.autojs.core.pref.Pref import org.autojs.autojs.core.pref.Pref
@@ -30,7 +31,7 @@ class AccessibilityTool(private val context: Context? = null) {
private val mContext: Context private val mContext: Context
get() = context ?: mApplicationContext get() = context ?: mApplicationContext
private val mServiceNamePrefix = mApplicationContext.packageName private val mServiceNamePrefix = mApplicationContext.packageName
private val mServiceNameSuffix = AccessibilityServiceUsher::class.java.name private val mServiceNameSuffix = SelectToSpeakService::class.java.name
private val mServiceName = "$mServiceNamePrefix/$mServiceNameSuffix" private val mServiceName = "$mServiceNamePrefix/$mServiceNameSuffix"
@ScriptInterface @ScriptInterface

View File

@@ -4,6 +4,11 @@ import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.content.res.TypedArray; import android.content.res.TypedArray;
import android.graphics.Color; import android.graphics.Color;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
@@ -17,6 +22,14 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.autojs.autojs.theme.ThemeColorHelper; import org.autojs.autojs.theme.ThemeColorHelper;
import org.autojs.autojs.tool.MapBuilder; import org.autojs.autojs.tool.MapBuilder;
import org.autojs.autojs.ui.log.LogActivity; import org.autojs.autojs.ui.log.LogActivity;
@@ -24,11 +37,6 @@ import org.autojs.autojs.util.DisplayUtils;
import org.autojs.autojs.util.ViewUtils; import org.autojs.autojs.util.ViewUtils;
import org.autojs.autojs6.R; import org.autojs.autojs6.R;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;
/** /**
* Created by Stardust on May 2, 2017. * Created by Stardust on May 2, 2017.
* <p> * <p>
@@ -37,6 +45,21 @@ import java.util.Objects;
public class ConsoleView extends FrameLayout implements ConsoleImpl.LogListener { public class ConsoleView extends FrameLayout implements ConsoleImpl.LogListener {
private final static int sRefreshInterval = 100; private final static int sRefreshInterval = 100;
// Stack frame link pattern: matches "file:line" or "file:line:col" format
// Examples: "/sdcard/script.js:10", "script.js:10:5", "file:///path/to/script.js:42:3"
private static final Pattern STACK_FRAME_PATTERN = Pattern.compile(
"(?:file:)?((?:/[\\S]+?|[^\\s:]+?)\\.js):(\\d+)(?::(\\d+))?"
);
private static final int LINK_COLOR = 0xFF2196F3; // Blue color for clickable links
private boolean mEnableStackFrameLinks = false;
private OnStackFrameClickListener mStackFrameClickListener;
public interface OnStackFrameClickListener {
void onStackFrameClick(String fileName, int lineNumber, int columnNumber);
}
private final Map<Integer, Integer> mColors = new MapBuilder<Integer, Integer>().build(); private final Map<Integer, Integer> mColors = new MapBuilder<Integer, Integer>().build();
private ConsoleImpl mConsole; private ConsoleImpl mConsole;
private WeakReference<LogActivity> mLogActivity = null; private WeakReference<LogActivity> mLogActivity = null;
@@ -228,6 +251,66 @@ public class ConsoleView extends FrameLayout implements ConsoleImpl.LogListener
mIsPinchToZoomEnabled = enabled; mIsPinchToZoomEnabled = enabled;
} }
/**
* Enable or disable clickable stack frame links in log entries
* @param enabled true to enable, false to disable
*/
public void setEnableStackFrameLinks(boolean enabled) {
mEnableStackFrameLinks = enabled;
}
/**
* Set the listener for stack frame click events
* @param listener the listener to receive click events
*/
public void setOnStackFrameClickListener(OnStackFrameClickListener listener) {
mStackFrameClickListener = listener;
}
/**
* Parse log content and create clickable spans for stack frames
* @param content the original log content
* @param baseColor the base text color
* @return CharSequence with clickable spans for stack frames
*/
private CharSequence createClickableContent(CharSequence content, int baseColor) {
if (!mEnableStackFrameLinks) {
return content;
}
String text = content.toString();
SpannableString spannable = new SpannableString(text);
Matcher matcher = STACK_FRAME_PATTERN.matcher(text);
boolean hasLinks = false;
while (matcher.find()) {
hasLinks = true;
final String fileName = matcher.group(1);
final int lineNumber = Integer.parseInt(matcher.group(2));
final int columnNumber = matcher.group(3) != null ? Integer.parseInt(matcher.group(3)) : 0;
final int start = matcher.start();
final int end = matcher.end();
ClickableSpan clickableSpan = new ClickableSpan() {
@Override
public void onClick(@NonNull View widget) {
if (mStackFrameClickListener != null) {
mStackFrameClickListener.onStackFrameClick(fileName, lineNumber - 1, columnNumber);
}
}
};
spannable.setSpan(clickableSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ForegroundColorSpan colorSpan = new ForegroundColorSpan(LINK_COLOR);
spannable.setSpan(colorSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return hasLinks ? spannable : content;
}
protected Map<Integer, Integer> getLogLevelMap() { protected Map<Integer, Integer> getLogLevelMap() {
return new MapBuilder<Integer, Integer>() return new MapBuilder<Integer, Integer>()
.put(Log.VERBOSE, R.color.console_view_verbose) .put(Log.VERBOSE, R.color.console_view_verbose)
@@ -323,6 +406,7 @@ public class ConsoleView extends FrameLayout implements ConsoleImpl.LogListener
public ViewHolder(View itemView) { public ViewHolder(View itemView) {
super(itemView); super(itemView);
textView = (TextView) itemView; textView = (TextView) itemView;
textView.setMovementMethod(LinkMovementMethod.getInstance());
} }
} }
@@ -341,12 +425,18 @@ public class ConsoleView extends FrameLayout implements ConsoleImpl.LogListener
public void onBindViewHolder(ViewHolder holder, int position) { public void onBindViewHolder(ViewHolder holder, int position) {
TextView textView = holder.textView; TextView textView = holder.textView;
ConsoleImpl.LogEntry logEntry = mLogEntries.get(position); ConsoleImpl.LogEntry logEntry = mLogEntries.get(position);
textView.setText(logEntry.content);
ThemeColorHelper.setThemeColorPrimary(textView, true);
Integer color = mColors.get(logEntry.level); Integer color = mColors.get(logEntry.level);
if (color != null) { if (color != null) {
// Create clickable content with stack frame links
CharSequence content = createClickableContent(logEntry.content, color);
textView.setText(content);
textView.setTextColor(color); textView.setTextColor(color);
} else {
textView.setText(logEntry.content);
} }
ThemeColorHelper.setThemeColorPrimary(textView, true);
if (textSize > 0) { if (textSize > 0) {
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize); textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
} else { } else {

View File

@@ -381,10 +381,17 @@ public class ConcatReader extends Reader {
@Override @Override
public void close() throws IOException { public void close() throws IOException {
if (closed) return; if (closed) return;
IOException first = null;
for (Reader reader : readerQueue) { for (Reader reader : readerQueue) {
try {
reader.close(); reader.close();
} catch (IOException e) {
if (first == null) first = e;
else first.addSuppressed(e);
}
} }
closed = true; closed = true;
if (first != null) throw first;
} }
/** /**

View File

@@ -35,6 +35,7 @@ import org.autojs.autojs.storage.file.StableDraftFileHelper
import org.autojs.autojs.theme.widget.ThemeColorToolbar import org.autojs.autojs.theme.widget.ThemeColorToolbar
import org.autojs.autojs.ui.BaseActivity import org.autojs.autojs.ui.BaseActivity
import org.autojs.autojs.ui.error.ErrorDialogActivity import org.autojs.autojs.ui.error.ErrorDialogActivity
import org.autojs.autojs.ui.log.LogBottomSheet
import org.autojs.autojs.ui.main.MainActivity import org.autojs.autojs.ui.main.MainActivity
import org.autojs.autojs.ui.main.scripts.EditableFileInfoDialogManager import org.autojs.autojs.ui.main.scripts.EditableFileInfoDialogManager
import org.autojs.autojs.util.DialogUtils import org.autojs.autojs.util.DialogUtils
@@ -157,6 +158,39 @@ open class EditActivity : BaseActivity(), DelegateHost, PermissionRequestProxyAc
setToolbarAsBack(editorView.name) setToolbarAsBack(editorView.name)
onBackPressedDispatcher.addCallback(this, mOnBackPressedCallback) onBackPressedDispatcher.addCallback(this, mOnBackPressedCallback)
// Setup log bottom sheet
setUpLogSheet()
}
private fun setUpLogSheet() {
mEditorView.setLogPanelCallback(object : EditorView.LogPanelCallback {
override fun onShowLogPanel() {
val scriptName = mEditorView.name
val scriptPath = mEditorView.uri?.path
val bottomSheet = LogBottomSheet.newInstance(scriptName, scriptPath)
bottomSheet.setOnStackFrameClickListener(object : LogBottomSheet.OnStackFrameClickListener {
override fun onStackFrameClick(fileName: String, lineNumber: Int, columnNumber: Int) {
// Jump to the line in editor
try {
val editor = mEditorView.editor
val layout = editor.codeEditText.layout
if (lineNumber >= 0 && lineNumber < layout.lineCount) {
val lineStart = layout.getLineStart(lineNumber)
val column = if (columnNumber > 0) columnNumber else 0
val offset = minOf(lineStart + column, layout.getLineEnd(lineNumber) - 1)
editor.codeEditText.setSelection(offset)
editor.codeEditText.requestFocus()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
})
bottomSheet.show(supportFragmentManager, "LogBottomSheet")
}
})
} }
private fun onLoadFileError(message: String?) { private fun onLoadFileError(message: String?) {

View File

@@ -98,6 +98,9 @@ public class EditorMenu {
if (itemId == R.id.action_log) { if (itemId == R.id.action_log) {
return ConsoleUtils.launch(mContext); return ConsoleUtils.launch(mContext);
} }
if (itemId == R.id.action_show_log) {
return tryDoing(mEditorView::showLogPanel);
}
if (itemId == R.id.action_force_stop) { if (itemId == R.id.action_force_stop) {
return tryDoing(mEditorView::forceStop); return tryDoing(mEditorView::forceStop);
} }
@@ -160,6 +163,10 @@ public class EditorMenu {
if (itemId == R.id.action_console) { if (itemId == R.id.action_console) {
return tryDoing(mEditorView::showConsole); return tryDoing(mEditorView::showConsole);
} }
if (itemId == R.id.action_show_log) {
showLogPanel();
return true;
}
if (itemId == R.id.action_import_java_class) { if (itemId == R.id.action_import_java_class) {
importJavaPackageOrClass(); importJavaPackageOrClass();
return true; return true;
@@ -399,6 +406,10 @@ public class EditorMenu {
builder.show(); builder.show();
} }
private void showLogPanel() {
mEditorView.showLogPanel();
}
private void showFileDetails() { private void showFileDetails() {
Uri uri = mEditorView.getUri(); Uri uri = mEditorView.getUri();
String path; String path;

View File

@@ -127,6 +127,23 @@ import java.util.regex.Pattern
@SuppressLint("CheckResult") @SuppressLint("CheckResult")
class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFragment.OnMenuItemClickListener { class EditorView : LinearLayout, OnHintClickListener, ClickCallback, ToolbarFragment.OnMenuItemClickListener {
/**
* Callback interface for showing the log panel from the editor
*/
interface LogPanelCallback {
fun onShowLogPanel()
}
private var mLogPanelCallback: LogPanelCallback? = null
fun setLogPanelCallback(callback: LogPanelCallback) {
mLogPanelCallback = callback
}
fun showLogPanel() {
mLogPanelCallback?.onShowLogPanel()
}
private var binding: EditorViewBinding = EditorViewBinding.bind(inflate(context, R.layout.editor_view, this)) private var binding: EditorViewBinding = EditorViewBinding.bind(inflate(context, R.layout.editor_view, this))
@JvmField @JvmField

View File

@@ -0,0 +1,115 @@
package org.autojs.autojs.ui.log
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import org.autojs.autojs.AutoJs
import org.autojs.autojs6.R
import org.autojs.autojs6.databinding.BottomSheetLogBinding
/**
* Bottom sheet dialog for displaying script logs in the editor.
* Provides quick access to log output without leaving the editor.
* Clickable stack frames (file:line) are highlighted in blue.
*/
class LogBottomSheet : BottomSheetDialogFragment() {
private var _binding: BottomSheetLogBinding? = null
private val binding get() = _binding!!
private var mScriptName: String? = null
private var mScriptPath: String? = null
private var mStackFrameClickListener: OnStackFrameClickListener? = null
interface OnStackFrameClickListener {
fun onStackFrameClick(fileName: String, lineNumber: Int, columnNumber: Int)
}
companion object {
private const val ARG_SCRIPT_NAME = "script_name"
private const val ARG_SCRIPT_PATH = "script_path"
/**
* Create a new instance with script info
*/
@JvmStatic
fun newInstance(scriptName: String?, scriptPath: String?): LogBottomSheet {
val fragment = LogBottomSheet()
val args = Bundle()
args.putString(ARG_SCRIPT_NAME, scriptName)
args.putString(ARG_SCRIPT_PATH, scriptPath)
fragment.arguments = args
return fragment
}
}
fun setOnStackFrameClickListener(listener: OnStackFrameClickListener) {
mStackFrameClickListener = listener
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
mScriptName = it.getString(ARG_SCRIPT_NAME)
mScriptPath = it.getString(ARG_SCRIPT_PATH)
}
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = BottomSheetLogBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupViews()
}
private fun setupViews() {
// Set title
if (!mScriptName.isNullOrEmpty()) {
binding.tvTitle.text = mScriptName
}
// Setup ConsoleView with global console
val autoJs = AutoJs.getInstance()
if (autoJs != null) {
binding.console.setConsole(autoJs.globalConsole)
// Hide input container (not needed in bottom sheet)
binding.console.findViewById<View>(R.id.input_container)?.visibility = View.GONE
// Enable clickable stack frame links (only in bottom sheet, not in LogActivity)
binding.console.setEnableStackFrameLinks(true)
// Set up clickable stack frame listener
binding.console.setOnStackFrameClickListener { fileName, lineNumber, columnNumber ->
mStackFrameClickListener?.onStackFrameClick(fileName, lineNumber, columnNumber)
dismiss()
}
}
// Clear button
binding.btnClear.setOnClickListener {
AutoJs.getInstance()?.globalConsole?.clear()
}
// Open full log activity button
binding.btnOpenFull.setOnClickListener {
startActivity(Intent(requireContext(), LogActivity::class.java))
dismiss()
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="?android:attr/windowBackground"/>
<corners
android:topLeftRadius="16dp"
android:topRightRadius="16dp"
android:bottomLeftRadius="0dp"
android:bottomRightRadius="0dp"/>
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#DDDDDD"/>
<corners android:radius="2dp"/>
<size android:width="40dp" android:height="4dp"/>
</shape>

View File

@@ -0,0 +1,4 @@
<vector android:height="24dp" android:viewportHeight="200"
android:viewportWidth="200" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M158.68,145.53c-4.72,4.97 -8.34,8.79 -12.38,13.05c-15.53,-15.56 -30.72,-30.76 -46.09,-46.16c-15.36,15.61 -30.56,31.05 -46.11,46.86c-4.63,-5 -8.23,-8.89 -12.16,-13.12c15.14,-15.01 30.41,-30.14 45.57,-45.17C71.76,85.33 56.39,70.07 40.7,54.48c5.16,-4.64 9.08,-8.16 13.08,-11.76c14.67,14.75 29.81,29.96 44.63,44.86c15.9,-15.95 31.17,-31.27 46.38,-46.52c5.04,5.1 8.71,8.81 12.83,12.97c-14.92,14.81 -30.26,30.04 -45.52,45.19C127.99,115.01 143.2,130.14 158.68,145.53z"/>
</vector>

View File

@@ -0,0 +1,5 @@
<vector android:height="24dp" android:viewportHeight="128"
android:viewportWidth="128" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FF000000" android:pathData="M95.9,22.4H85.3v-4.2c0,-2.5 -1.7,-4.2 -4.3,-4.2c-2.6,0 -4.3,1.6 -4.3,4.2v4.2H51.3v-4.2c0,-2.5 -1.7,-4.2 -4.2,-4.2c-2.5,0 -4.3,1.6 -4.3,4.2v4.2H32.1c-6,0 -10.6,4.5 -10.6,10.4v70.8c0,5.8 4.7,10.4 10.6,10.4h63.7c6,0 10.6,-4.5 10.6,-10.4V32.8C106.5,26.9 101.8,22.4 95.9,22.4zM98,103.5c0,1.3 -0.8,2.1 -2.1,2.1H32.1c-1.3,0 -2.1,-0.8 -2.1,-2.1V32.8c0,-1.3 0.8,-2.1 2.1,-2.1h10.6v4.2c0,2.5 1.7,4.2 4.2,4.2c2.5,0 4.2,-1.6 4.2,-4.2v-4.2h25.5v4.2c0,2.5 1.7,4.2 4.3,4.2c2.6,0 4.3,-1.6 4.3,-4.2v-4.2h10.6c1.3,0 2.1,0.8 2.1,2.1L98,103.5L98,103.5z"/>
<path android:fillColor="#FF000000" android:pathData="M83.1,49.5H44.9c-2.5,0 -4.2,1.6 -4.2,4.2c0,2.5 1.7,4.2 4.2,4.2h38.2c2.5,0 4.3,-1.6 4.3,-4.2C87.4,51.1 85.7,49.5 83.1,49.5zM83.1,68.2H44.9c-2.5,0 -4.2,1.6 -4.2,4.2s1.7,4.2 4.2,4.2h38.2c2.5,0 4.3,-1.6 4.3,-4.2C87.4,69.8 85.7,68.2 83.1,68.2zM70.4,86.9H44.9c-2.5,0 -4.2,1.6 -4.2,4.2c0,2.5 1.7,4.2 4.2,4.2h25.5c2.5,0 4.2,-1.6 4.2,-4.2C74.6,88.5 73,86.9 70.4,86.9z"/>
</vector>

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/bg_bottom_sheet_rounded">
<!-- Drag handle -->
<View
android:layout_width="40dp"
android:layout_height="4dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="@drawable/bg_drag_handle"/>
<!-- Header -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="horizontal"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="8dp">
<!-- Script name / Title -->
<TextView
android:id="@+id/tv_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/text_log"
android:textColor="?android:attr/textColorPrimary"
android:textSize="16sp"
android:textStyle="bold"
android:ellipsize="end"
android:maxLines="1"/>
<!-- Action buttons -->
<ImageButton
android:id="@+id/btn_open_full"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="?selectableItemBackgroundBorderless"
android:src="@drawable/ic_logcat"
android:tint="?attr/colorPrimary"
android:contentDescription="@string/text_log"
android:scaleType="center"/>
<ImageButton
android:id="@+id/btn_clear"
android:layout_width="40dp"
android:layout_height="40dp"
android:background="?selectableItemBackgroundBorderless"
android:src="@drawable/ic_clear"
android:tint="#666666"
android:contentDescription="@string/text_clear"
android:scaleType="center"/>
</LinearLayout>
<!-- Divider -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?android:attr/listDivider"/>
<!-- Console View -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="400dp"
android:paddingStart="4dp">
<org.autojs.autojs.core.console.ConsoleView
android:id="@+id/console"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:color_debug="@color/console_debug"
app:color_verbose="@color/console_verbose"/>
</FrameLayout>
</LinearLayout>

View File

@@ -115,6 +115,11 @@
android:title="@string/text_log" android:title="@string/text_log"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/action_show_log"
android:title="@string/text_show_log"
app:showAsAction="never" />
<item android:title="@string/text_more"> <item android:title="@string/text_more">
<menu> <menu>
<item <item

View File

@@ -938,6 +938,7 @@
<string name="text_loading_with_dots" tools:ignore="TypographyEllipsis">加载中...</string> <string name="text_loading_with_dots" tools:ignore="TypographyEllipsis">加载中...</string>
<string name="text_locate_current_theme_color">定位当前主题色</string> <string name="text_locate_current_theme_color">定位当前主题色</string>
<string name="text_log">日志</string> <string name="text_log">日志</string>
<string name="text_show_log">显示日志</string>
<string name="text_logging_in">登录中</string> <string name="text_logging_in">登录中</string>
<string name="text_login">登录</string> <string name="text_login">登录</string>
<string name="text_login_succeed">登录成功</string> <string name="text_login_succeed">登录成功</string>

View File

@@ -1216,6 +1216,7 @@
<string name="text_loading_with_dots" tools:ignore="TypographyEllipsis">Loading...</string> <string name="text_loading_with_dots" tools:ignore="TypographyEllipsis">Loading...</string>
<string name="text_locate_current_theme_color">Locate current theme color</string> <string name="text_locate_current_theme_color">Locate current theme color</string>
<string name="text_log">Log</string> <string name="text_log">Log</string>
<string name="text_show_log">Show log</string>
<string name="text_logging_in">Logging in</string> <string name="text_logging_in">Logging in</string>
<string name="text_login">Login</string> <string name="text_login">Login</string>
<string name="text_login_succeed">Login succeeded</string> <string name="text_login_succeed">Login succeeded</string>

View File

@@ -346,8 +346,9 @@ pluginManagement {
val temurin = object : Platform( val temurin = object : Platform(
name = "Temurin", vendor = "temurin", name = "Temurin", vendor = "temurin",
/* More common as "Eclipse Adoptium". */ /* More common as "Eclipse Adoptium". */
// @Updated by SuperMonster003 on Apr 16, 2025. (Manual) // @Updated by SuperMonster003 on Mar 15, 2026. (Manual)
agpVersionMap = mapOf( agpVersionMap = mapOf(
"21.0.10+7" to "8.9.3", /* Mar 15, 2026. */
"21.0.6+7" to "8.7.3", /* Apr 16, 2025. */ "21.0.6+7" to "8.7.3", /* Apr 16, 2025. */
"20.0.2+9" to "8.2.2", /* Dec 2, 2024. */ "20.0.2+9" to "8.2.2", /* Dec 2, 2024. */
), ),