diff --git a/app/build.gradle b/app/build.gradle index 978495fb..941622ab 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -11,6 +11,9 @@ def homePath = System.properties['user.home'] def storePasswd = System.getenv('autojspasswd') def keyPasswd = System.getenv('autojspasswd') def alias = System.getenv('autojsalias') +def buglyAppId = System.getenv("bugly_app_id") +def flurryAppId = System.getenv("flurry_app_id") + def signSupport = false android { @@ -39,6 +42,8 @@ android { targetSdkVersion versions.target versionCode versions.appVersionCode versionName versions.appVersionName + buildConfigField "String", "BUGLY_APP_ID", "\"${buglyAppId ?: ''}\"" + buildConfigField "String", "FLURRY_APP_ID", "\"${flurryAppId ?: ''}\"" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" multiDexEnabled true javaCompileOptions { @@ -151,7 +156,7 @@ dependencies { }) testImplementation "junit:junit:$junit_version" // Kotlin - implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0" + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1" // Android Annotations kapt "org.androidannotations:androidannotations:$AAVersion" implementation "org.androidannotations:androidannotations-api:$AAVersion" @@ -210,13 +215,13 @@ dependencies { implementation('com.github.bumptech.glide:glide:4.12.0', { exclude group: 'com.android.support' }) - kapt 'com.github.bumptech.glide:compiler:4.12.0' + kapt 'com.github.bumptech.glide:compiler:4.15.1' //joda time - implementation 'joda-time:joda-time:2.10.13' + implementation 'joda-time:joda-time:2.12.5' // Tasker Plugin implementation 'com.twofortyfouram:android-plugin-client-sdk-for-locale:4.0.3' // Flurry - implementation 'com.flurry.android:analytics:13.1.0@aar' + implementation 'com.flurry.android:analytics:14.4.0@aar' // Bugly implementation 'com.tencent.bugly:crashreport:4.0.4' // 4.+ 合并了 不需要手动引入 @@ -226,10 +231,10 @@ dependencies { exclude group: 'com.android.support' }) // WorkManager - implementation 'androidx.work:work-runtime:2.7.1' + implementation 'androidx.work:work-runtime:2.8.1' // Android job implementation 'com.evernote:android-job:1.4.2' - debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1' + debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.12' releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.3' // Optional, if you use support library fragments: debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.3' diff --git a/app/src/main/java/org/autojs/autojs/App.kt b/app/src/main/java/org/autojs/autojs/App.kt index 29eaece3..d1ef0fae 100644 --- a/app/src/main/java/org/autojs/autojs/App.kt +++ b/app/src/main/java/org/autojs/autojs/App.kt @@ -21,6 +21,7 @@ import com.stardust.autojs.runtime.api.Device import com.stardust.theme.ThemeColor import com.tencent.bugly.Bugly import com.tencent.bugly.crashreport.CrashReport +import org.apache.commons.lang3.StringUtils import org.autojs.autojs.autojs.AutoJs import org.autojs.autojs.autojs.key.GlobalKeyObserver import org.autojs.autojs.external.receiver.DynamicBroadcastReceivers @@ -30,7 +31,6 @@ import org.autojs.autojs.timing.TimedTaskScheduler import org.autojs.autojs.tool.CrashHandler import org.autojs.autojs.ui.error.ErrorReportActivity import java.lang.ref.WeakReference -import java.util.* /** * Created by Stardust on 2017/1/27. @@ -50,25 +50,29 @@ class App : MultiDexApplication() { } private fun setUpStaticsTool() { - if (BuildConfig.DEBUG) + if (BuildConfig.DEBUG || StringUtils.isEmpty(BuildConfig.FLURRY_APP_ID)) return FlurryAgent.Builder() - .withLogEnabled(BuildConfig.DEBUG) - .build(this, "V5B5VT5NP6TT5F78PZXR") + .withLogEnabled(BuildConfig.DEBUG) + .build(this, BuildConfig.FLURRY_APP_ID) } @SuppressLint("HardwareIds") private fun setUpDebugEnvironment() { + if (StringUtils.isEmpty(BuildConfig.BUGLY_APP_ID)) { + return + } Bugly.isDev = BuildConfig.DEBUG val crashHandler = CrashHandler(ErrorReportActivity::class.java) val strategy = CrashReport.UserStrategy(applicationContext) strategy.setCrashHandleCallback(crashHandler) strategy.deviceModel = Device.model - strategy.deviceID = Settings.Secure.getString(this.contentResolver, Settings.Secure.ANDROID_ID) + strategy.deviceID = + Settings.Secure.getString(this.contentResolver, Settings.Secure.ANDROID_ID) CrashReport.setIsDevelopmentDevice(this, BuildConfig.DEBUG) - CrashReport.initCrashReport(applicationContext, BUGLY_APP_ID, false, strategy) + CrashReport.initCrashReport(applicationContext, BuildConfig.BUGLY_APP_ID, false, strategy) crashHandler.setBuglyHandler(Thread.getDefaultUncaughtExceptionHandler()) Thread.setDefaultUncaughtExceptionHandler(crashHandler) @@ -76,7 +80,14 @@ class App : MultiDexApplication() { } private fun init() { - ThemeColorManagerCompat.init(this, ThemeColor(resources.getColor(R.color.colorPrimary), resources.getColor(R.color.colorPrimaryDark), resources.getColor(R.color.colorAccent))) + ThemeColorManagerCompat.init( + this, + ThemeColor( + resources.getColor(R.color.colorPrimary), + resources.getColor(R.color.colorPrimaryDark), + resources.getColor(R.color.colorAccent) + ) + ) AutoJs.initInstance(this) if (Pref.isRunningVolumeControlEnabled()) { GlobalKeyObserver.init() @@ -92,25 +103,27 @@ class App : MultiDexApplication() { val localActions = ArrayList() val actions = ArrayList() TimedTaskManager.getInstance().allIntentTasks - .filter { task -> task.action != null } - .doOnComplete { - if (localActions.isNotEmpty()) { - dynamicBroadcastReceivers.register(localActions, true) - } - if (actions.isNotEmpty()) { - dynamicBroadcastReceivers.register(actions, false) - } - LocalBroadcastManager.getInstance(applicationContext).sendBroadcast(Intent( - DynamicBroadcastReceivers.ACTION_STARTUP - )) + .filter { task -> task.action != null } + .doOnComplete { + if (localActions.isNotEmpty()) { + dynamicBroadcastReceivers.register(localActions, true) } - .subscribe({ - if (it.isLocal) { - localActions.add(it.action) - } else { - actions.add(it.action) - } - }, { it.printStackTrace() }) + if (actions.isNotEmpty()) { + dynamicBroadcastReceivers.register(actions, false) + } + LocalBroadcastManager.getInstance(applicationContext).sendBroadcast( + Intent( + DynamicBroadcastReceivers.ACTION_STARTUP + ) + ) + } + .subscribe({ + if (it.isLocal) { + localActions.add(it.action) + } else { + actions.add(it.action) + } + }, { it.printStackTrace() }) } @@ -119,43 +132,56 @@ class App : MultiDexApplication() { Drawables.setDefaultImageLoader(object : ImageLoader { override fun loadInto(imageView: ImageView, uri: Uri) { Glide.with(imageView) - .load(uri) - .into(imageView) + .load(uri) + .into(imageView) } override fun loadIntoBackground(view: View, uri: Uri) { Glide.with(view) - .load(uri) - .into(object : SimpleTarget() { - override fun onResourceReady(resource: Drawable, transition: Transition?) { - view.background = resource - } - }) + .load(uri) + .into(object : SimpleTarget() { + override fun onResourceReady( + resource: Drawable, + transition: Transition? + ) { + view.background = resource + } + }) } override fun load(view: View, uri: Uri): Drawable { throw UnsupportedOperationException() } - override fun load(view: View, uri: Uri, drawableCallback: ImageLoader.DrawableCallback) { + override fun load( + view: View, + uri: Uri, + drawableCallback: ImageLoader.DrawableCallback + ) { Glide.with(view) - .load(uri) - .into(object : SimpleTarget() { - override fun onResourceReady(resource: Drawable, transition: Transition?) { - drawableCallback.onLoaded(resource) - } - }) + .load(uri) + .into(object : SimpleTarget() { + override fun onResourceReady( + resource: Drawable, + transition: Transition? + ) { + drawableCallback.onLoaded(resource) + } + }) } override fun load(view: View, uri: Uri, bitmapCallback: ImageLoader.BitmapCallback) { Glide.with(view) - .asBitmap() - .load(uri) - .into(object : SimpleTarget() { - override fun onResourceReady(resource: Bitmap, transition: Transition?) { - bitmapCallback.onLoaded(resource) - } - }) + .asBitmap() + .load(uri) + .into(object : SimpleTarget() { + override fun onResourceReady( + resource: Bitmap, + transition: Transition? + ) { + bitmapCallback.onLoaded(resource) + } + }) } }) } @@ -163,7 +189,6 @@ class App : MultiDexApplication() { companion object { private val TAG = "App" - private val BUGLY_APP_ID = "e020acad30" private lateinit var instance: WeakReference diff --git a/app/src/main/java/org/autojs/autojs/tool/AccessibilityServiceTool.java b/app/src/main/java/org/autojs/autojs/tool/AccessibilityServiceTool.java index 0174e15c..1528eb6e 100644 --- a/app/src/main/java/org/autojs/autojs/tool/AccessibilityServiceTool.java +++ b/app/src/main/java/org/autojs/autojs/tool/AccessibilityServiceTool.java @@ -60,7 +60,7 @@ public class AccessibilityServiceTool { "settings put secure enabled_accessibility_services $enabled\n" + "fi\n" + "settings put secure accessibility_enabled 1"; - private static final Pattern SERVICE_PATTERN = Pattern.compile("^(((\\w+\\.)+\\w+)[/]?){2}$"); + private static final Pattern SERVICE_PATTERN = Pattern.compile("^(\\w+\\.?)+/((\\w+.)|(\\.\\w+))+$"); public static boolean enableAccessibilityServiceByRoot() { return enableAccessibilityServiceByRoot(sAccessibilityServiceClass); @@ -108,21 +108,14 @@ public class AccessibilityServiceTool { */ public static boolean enableAccessibilityServiceByAdb(Class accessibilityService) { try { - String enabledServices = Settings.Secure.getString(GlobalAppContext.get().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); + String enabledServices = Settings.Secure.getString(GlobalAppContext.get().getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); String requiredService = BuildConfig.APPLICATION_ID + "/" + accessibilityService.getName(); String services = enabledServices + ":" + requiredService; - String[] serviceInfo = services.split(":"); - StringBuilder sb = new StringBuilder(); - for (String service : serviceInfo) { - if (SERVICE_PATTERN.matcher(service).find()) { - sb.append(service).append(":"); - } - } - if (sb.length() > 0) { - sb.deleteCharAt(sb.length() - 1); - } - Settings.Secure.putString(GlobalAppContext.get().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, sb.toString()); - Settings.Secure.putString(GlobalAppContext.get().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED, "1"); + Settings.Secure.putString(GlobalAppContext.get().getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, resolveAccessibilityString(services)); + Settings.Secure.putString(GlobalAppContext.get().getContentResolver(), + Settings.Secure.ACCESSIBILITY_ENABLED, "1"); return true; } catch (Exception e) { return false; @@ -135,20 +128,12 @@ public class AccessibilityServiceTool { public static boolean disableAccessibilityServiceByAdb(Class accessibilityService) { try { - String enabledServices = Settings.Secure.getString(GlobalAppContext.get().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); + String enabledServices = Settings.Secure.getString(GlobalAppContext.get().getContentResolver(), + Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES); String requiredService = BuildConfig.APPLICATION_ID + "/" + accessibilityService.getName(); String services = enabledServices.replace(requiredService, ""); - String[] serviceInfo = services.split(":"); - StringBuilder sb = new StringBuilder(); - for (String service : serviceInfo) { - if (SERVICE_PATTERN.matcher(service).find()) { - sb.append(service).append(":"); - } - } - if (sb.length() > 0) { - sb.deleteCharAt(sb.length() - 1); - } - Settings.Secure.putString(GlobalAppContext.get().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, sb.toString()); + Settings.Secure.putString(GlobalAppContext.get().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, + resolveAccessibilityString(services)); Settings.Secure.putString(GlobalAppContext.get().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED, "1"); return true; } catch (Exception e) { @@ -156,6 +141,21 @@ public class AccessibilityServiceTool { } } + private static String resolveAccessibilityString(String enabledServices) { + String[] serviceInfo = enabledServices.split(":"); + StringBuilder sb = new StringBuilder(); + for (String service : serviceInfo) { + // 验证名称是否符合规则,其实有点不必要,判断非空也行 + if (SERVICE_PATTERN.matcher(service).find()) { + sb.append(service).append(":"); + } + } + if (sb.length() > 0) { + sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } + public static boolean isAccessibilityServiceEnabled(Context context) { return AccessibilityServiceUtils.INSTANCE.isAccessibilityServiceEnabled(context, sAccessibilityServiceClass); } diff --git a/autojs-aar/paddleocr/src/main/java/com/baidu/paddle/lite/ocr/Predictor.java b/autojs-aar/paddleocr/src/main/java/com/baidu/paddle/lite/ocr/Predictor.java index 99ee4d62..97a70f53 100644 --- a/autojs-aar/paddleocr/src/main/java/com/baidu/paddle/lite/ocr/Predictor.java +++ b/autojs-aar/paddleocr/src/main/java/com/baidu/paddle/lite/ocr/Predictor.java @@ -8,6 +8,7 @@ import android.util.Base64; import android.util.Log; import java.io.File; +import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; @@ -64,7 +65,14 @@ public class Predictor { */ private final String defaultModelPathSlim = "models/ocr_v3_for_cpu(slim)"; + /** + * 初始化时校验模型是否加载正确 + */ private int retryTime = 1; + /** + * 初始化尝试次数 + */ + private int initRetryTime = 1; public Predictor() { } @@ -92,7 +100,11 @@ public class Predictor { } isLoaded = loadLabel(appCtx, labelPath); if (!checkModelLoadedSuccess()) { - init(appCtx, modelPath, labelPath); + if (initRetryTime++ < 3) { + return init(appCtx, modelPath, labelPath); + } else { + return false; + } } return isLoaded; } @@ -204,14 +216,19 @@ public class Predictor { wordLabels.add("black"); // Load word labels from file try { - InputStream assetsInputStream = appCtx.getAssets().open(labelPath); - int available = assetsInputStream.available(); + InputStream labelInputStream = null; + if (labelPath.startsWith("/")) { + labelInputStream = new FileInputStream(labelPath); + } else { + labelInputStream = appCtx.getAssets().open(labelPath); + } + int available = labelInputStream.available(); byte[] lines = new byte[available]; - if (assetsInputStream.read(lines) <= 0) { + if (labelInputStream.read(lines) <= 0) { Log.e(TAG, "读取label失败"); return false; } - assetsInputStream.close(); + labelInputStream.close(); String words = new String(lines); // Windows下换行为\r\n 进行兼容 String[] contents = words.split("(\r)?\n"); @@ -219,7 +236,7 @@ public class Predictor { wordLabels.add(" "); Log.i(TAG, "Word label size: " + wordLabels.size()); } catch (Exception e) { - Log.e(TAG, e.getMessage()); + Log.e(TAG, e.getMessage(), e); return false; } return true; diff --git a/autojs/build.gradle b/autojs/build.gradle index 82883805..cce44852 100644 --- a/autojs/build.gradle +++ b/autojs/build.gradle @@ -47,7 +47,7 @@ dependencies { // api fileTree(include: ['*.jar'], dir: 'libs') api fileTree('libs/dx.jar') api 'org.greenrobot:eventbus:3.3.1' - api 'net.lingala.zip4j:zip4j:1.3.2' + api 'net.lingala.zip4j:zip4j:1.3.3' api('com.afollestad.material-dialogs:core:0.9.2.3', { exclude group: 'com.android.support' }) @@ -62,7 +62,7 @@ dependencies { //RootShell api 'com.github.Stericson:RootShell:1.6' // Gson - api 'com.google.code.gson:gson:2.8.6' + api 'com.google.code.gson:gson:2.10.1' // log4j api 'de.mindpipe.android:android-logging-log4j:1.0.3' api 'log4j:log4j:1.2.17'