diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index d6a56099..85995d5c 100644
Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ
diff --git a/app/build.gradle b/app/build.gradle
index 0b280778..0f381340 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,19 +1,27 @@
apply plugin: 'com.android.application'
-def AAVersion = '4.3.1'
+def AAVersion = '4.4.0'
+def SupportLibVersion = '28.0.0'
+
+configurations.all {
+ resolutionStrategy {
+ force "com.android.support:appcompat-v7:${SupportLibVersion}"
+ force "com.android.support:support-v4:${SupportLibVersion}"
+ }
+}
android {
- compileSdkVersion 27
- buildToolsVersion '27.0.3'
+ compileSdkVersion versions.compile
+ buildToolsVersion versions.buildTool
defaultConfig {
applicationId "org.autojs.autojs"
- minSdkVersion 17
- targetSdkVersion 23
- versionCode 421
- versionName "4.0.3 Alpha2"
+ minSdkVersion versions.mini
+ targetSdkVersion versions.target
+ versionCode versions.appVersionCode
+ versionName versions.appVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {
- abiFilters 'armeabi-v7a'
+ abiFilters 'armeabi-v7a', 'x86'
}
}
buildTypes {
@@ -24,7 +32,7 @@ android {
}
release {
shrinkResources false
- minifyEnabled true
+ minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
@@ -62,6 +70,7 @@ android {
+
repositories {
flatDir {
dirs 'libs'
@@ -70,83 +79,83 @@ repositories {
}
dependencies {
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
- testCompile 'junit:junit:4.12'
+ testImplementation 'junit:junit:4.12'
// Android Annotations
annotationProcessor "org.androidannotations:androidannotations:$AAVersion"
- compile "org.androidannotations:androidannotations-api:$AAVersion"
+ implementation "org.androidannotations:androidannotations-api:$AAVersion"
// ButterKnife
- compile('com.jakewharton:butterknife:8.6.0', {
+ implementation('com.jakewharton:butterknife:8.8.1', {
exclude group: 'com.android.support'
})
- annotationProcessor 'com.jakewharton:butterknife-compiler:8.6.0'
+ annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
// Android supports
- compile 'com.android.support:appcompat-v7:27.1.1'
- compile 'com.android.support:cardview-v7:27.1.1'
- compile 'com.android.support:design:27.1.1'
- compile 'com.android.support:multidex:1.0.3'
+ implementation "com.android.support:appcompat-v7:${SupportLibVersion}"
+ implementation "com.android.support:cardview-v7:${SupportLibVersion}"
+ implementation "com.android.support:design:${SupportLibVersion}"
+ implementation 'com.android.support:multidex:1.0.3'
// Personal libraries
- compile 'com.github.hyb1996:MutableTheme:0.2.2'
+ implementation 'com.github.hyb1996:MutableTheme:0.2.2'
// Material Dialogs
- compile('com.afollestad.material-dialogs:core:0.9.2.3', {
+ implementation('com.afollestad.material-dialogs:core:0.9.2.3', {
exclude group: 'com.android.support'
})
// Common Markdown
- compile 'com.github.atlassian:commonmark-java:commonmark-parent-0.9.0'
+ implementation 'com.github.atlassian:commonmark-java:commonmark-parent-0.9.0'
// Android issue reporter (a github issue reporter)
- compile('com.heinrichreimersoftware:android-issue-reporter:1.3.1', {
+ implementation('com.heinrichreimersoftware:android-issue-reporter:1.3.1', {
exclude group: 'com.afollestad.material-dialogs'
exclude group: 'com.android.support'
})
//MultiLevelListView
- compile 'com.github.hyb1996:android-multi-level-listview:1.1'
+ implementation 'com.github.hyb1996:android-multi-level-listview:1.1'
//Licenses Dialog
- compile 'de.psdev.licensesdialog:licensesdialog:1.8.1'
+ implementation 'de.psdev.licensesdialog:licensesdialog:1.8.1'
//Expandable RecyclerView
- compile 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1'
+ implementation 'com.bignerdranch.android:expandablerecyclerview:3.0.0-RC1'
//FlexibleDivider
- compile 'com.yqritc:recyclerview-flexibledivider:1.4.0'
+ implementation 'com.yqritc:recyclerview-flexibledivider:1.4.0'
//???
- compile 'com.wang.avi:library:2.1.3'
+ implementation 'com.wang.avi:library:2.1.3'
//Commons-lang
- compile 'org.apache.commons:commons-lang3:3.6'
+ implementation 'org.apache.commons:commons-lang3:3.6'
//Expandable RecyclerView
- compile 'com.thoughtbot:expandablerecyclerview:1.3'
- compile('com.github.hyb1996:FloatingCircularActionMenu:0.0.4')
- compile 'com.github.hyb1996:Auto.js-ApkBuilder:1.0.1'
+ implementation 'com.thoughtbot:expandablerecyclerview:1.3'
+ implementation('com.github.hyb1996:FloatingCircularActionMenu:0.0.4')
+ implementation 'com.github.hyb1996:Auto.js-ApkBuilder:1.0.1'
// RxJava
- compile "io.reactivex.rxjava2:rxjava:2.1.2"
- compile 'io.reactivex.rxjava2:rxandroid:2.0.1'
+ implementation "io.reactivex.rxjava2:rxjava:2.1.2"
+ implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
// Retrofit
- compile 'com.squareup.retrofit2:retrofit:2.3.0'
- compile 'com.squareup.retrofit2:converter-gson:2.3.0'
- compile 'com.squareup.retrofit2:converter-gson:2.3.0'
- compile 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
+ implementation 'com.squareup.retrofit2:retrofit:2.3.0'
+ implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
+ implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
+ implementation 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0'
//Glide
- compile('com.github.bumptech.glide:glide:4.2.0', {
+ implementation('com.github.bumptech.glide:glide:4.8.0', {
exclude group: 'com.android.support'
})
- annotationProcessor 'com.github.bumptech.glide:compiler:4.2.0'
+ annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
//joda time
- compile 'joda-time:joda-time:2.9.9'
+ implementation 'joda-time:joda-time:2.9.9'
// Tasker Plugin
- compile 'com.twofortyfouram:android-plugin-client-sdk-for-locale:4.0.3'
+ implementation 'com.twofortyfouram:android-plugin-client-sdk-for-locale:4.0.3'
// Flurry
- compile 'com.flurry.android:analytics:7.0.0@aar'
+ implementation 'com.flurry.android:analytics:7.0.0@aar'
// Bugly
- compile 'com.tencent.bugly:crashreport:2.6.6'
+ implementation 'com.tencent.bugly:crashreport:2.6.6'
// MaterialDialogCommon
- compile('com.afollestad.material-dialogs:commons:0.9.2.3', {
+ implementation('com.afollestad.material-dialogs:commons:0.9.2.3', {
exclude group: 'com.android.support'
})
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.1'
// Optional, if you use support library fragments:
debugImplementation 'com.squareup.leakcanary:leakcanary-support-fragment:1.6.1'
- compile project(':automator')
- compile project(':common')
- compile project(':autojs')
+ implementation project(':automator')
+ implementation project(':common')
+ implementation project(':autojs')
implementation (name: 'ads8', ext: 'aar')
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index d68b0544..ed15d0a1 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -23,6 +23,7 @@
+
+
+
@@ -139,11 +144,6 @@
-
-
-
-
-
diff --git a/app/src/main/java/org/autojs/autojs/App.java b/app/src/main/java/org/autojs/autojs/App.java
index 7738151e..b0c7c854 100644
--- a/app/src/main/java/org/autojs/autojs/App.java
+++ b/app/src/main/java/org/autojs/autojs/App.java
@@ -18,6 +18,7 @@ import com.stardust.autojs.core.ui.inflater.ImageLoader;
import com.stardust.autojs.core.ui.inflater.util.Drawables;
import com.stardust.theme.ThemeColor;
import com.stardust.theme.ThemeColorManager;
+import com.tencent.bugly.Bugly;
import com.tencent.bugly.crashreport.CrashReport;
import org.autojs.autojs.autojs.AutoJs;
diff --git a/app/src/main/java/org/autojs/autojs/autojs/build/AutoJsApkBuilder.java b/app/src/main/java/org/autojs/autojs/autojs/build/AutoJsApkBuilder.java
index 419ce82c..174e609d 100644
--- a/app/src/main/java/org/autojs/autojs/autojs/build/AutoJsApkBuilder.java
+++ b/app/src/main/java/org/autojs/autojs/autojs/build/AutoJsApkBuilder.java
@@ -48,14 +48,18 @@ public class AutoJsApkBuilder extends ApkBuilder {
Callable icon;
public static AppConfig fromProjectConfig(String projectDir, ProjectConfig projectConfig) {
- return new AppConfig()
+ String icon = projectConfig.getIcon();
+ AppConfig appConfig = new AppConfig()
.setAppName(projectConfig.getName())
.setPackageName(projectConfig.getPackageName())
.ignoreDir(new File(projectDir, projectConfig.getBuildDir()))
.setVersionCode(projectConfig.getVersionCode())
.setVersionName(projectConfig.getVersionName())
- .setIcon(projectConfig.getIcon())
.setSourcePath(projectDir);
+ if (icon != null) {
+ appConfig.setIcon(new File(projectDir, icon).getPath());
+ }
+ return appConfig;
}
diff --git a/app/src/main/java/org/autojs/autojs/external/fileprovider/AppFileProvider.java b/app/src/main/java/org/autojs/autojs/external/fileprovider/AppFileProvider.java
new file mode 100644
index 00000000..a2c99237
--- /dev/null
+++ b/app/src/main/java/org/autojs/autojs/external/fileprovider/AppFileProvider.java
@@ -0,0 +1,16 @@
+package org.autojs.autojs.external.fileprovider;
+
+import android.content.Context;
+import android.net.Uri;
+import android.support.v4.content.FileProvider;
+
+import java.io.File;
+
+public class AppFileProvider extends FileProvider {
+
+ public static final String AUTHORITY = "org.autojs.autojs.fileprovider";
+
+ public static Uri getUriForFile(Context context, File file){
+ return FileProvider.getUriForFile(context, AUTHORITY, file);
+ }
+}
diff --git a/app/src/main/java/org/autojs/autojs/external/foreground/ForegroundService.java b/app/src/main/java/org/autojs/autojs/external/foreground/ForegroundService.java
index e9108beb..a600f0a5 100644
--- a/app/src/main/java/org/autojs/autojs/external/foreground/ForegroundService.java
+++ b/app/src/main/java/org/autojs/autojs/external/foreground/ForegroundService.java
@@ -13,11 +13,12 @@ import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.NotificationCompat;
-import com.stardust.app.GlobalAppContext;
-
import org.autojs.autojs.R;
import org.autojs.autojs.ui.main.MainActivity_;
+import java.lang.reflect.Array;
+import java.util.Arrays;
+
public class ForegroundService extends Service {
@@ -64,6 +65,7 @@ public class ForegroundService extends Service {
.setWhen(System.currentTimeMillis())
.setContentIntent(contentIntent)
.setChannelId(CHANEL_ID)
+ .setVibrate(new long[0])
.build();
}
diff --git a/app/src/main/java/org/autojs/autojs/external/receiver/DynamicBroadcastReceivers.java b/app/src/main/java/org/autojs/autojs/external/receiver/DynamicBroadcastReceivers.java
index b837f046..faf0388c 100644
--- a/app/src/main/java/org/autojs/autojs/external/receiver/DynamicBroadcastReceivers.java
+++ b/app/src/main/java/org/autojs/autojs/external/receiver/DynamicBroadcastReceivers.java
@@ -4,10 +4,15 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.os.Build;
+import android.support.design.widget.TabLayout;
+import android.util.Log;
+import android.util.Pair;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
+import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -18,61 +23,110 @@ import static android.content.Intent.ACTION_PACKAGES_SUSPENDED;
import static android.content.Intent.ACTION_PACKAGES_UNSUSPENDED;
import static android.content.Intent.ACTION_SCREEN_OFF;
import static android.content.Intent.ACTION_SCREEN_ON;
-import static android.content.Intent.ACTION_TIME_TICK;
public class DynamicBroadcastReceivers {
- private static final List DEFAULT_ACTIONS = new ArrayList<>(Arrays.asList(
- ACTION_TIME_TICK,
- ACTION_SCREEN_OFF,
- ACTION_SCREEN_ON,
- ACTION_BATTERY_CHANGED,
- ACTION_CONFIGURATION_CHANGED
- ));
-
- static {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
- DEFAULT_ACTIONS.addAll(Arrays.asList(
- ACTION_PACKAGES_SUSPENDED,
- ACTION_PACKAGES_UNSUSPENDED
- ));
- }
- }
+ private static final String LOG_TAG = "DynBroadcastReceivers";
private final Set mActions = new LinkedHashSet<>();
- private final List mReceivers = new ArrayList<>();
+ private final List mReceiverRegistries = new ArrayList<>();
+ private final BaseBroadcastReceiver mDefaultActionReceiver = new BaseBroadcastReceiver();
+ private final BaseBroadcastReceiver mPackageActionReceiver = new BaseBroadcastReceiver();
private final Context mContext;
public DynamicBroadcastReceivers(Context context) {
mContext = context;
- register(DEFAULT_ACTIONS);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ mContext.registerReceiver(mDefaultActionReceiver, createIntentFilter(StaticBroadcastReceiver.ACTIONS));
+ IntentFilter filter = createIntentFilter(StaticBroadcastReceiver.PACKAGE_ACTIONS);
+ filter.addDataScheme("package");
+ mContext.registerReceiver(mPackageActionReceiver, filter);
+ }
+
+
}
public void register(String action) {
register(Collections.singletonList(action));
}
- public void register(List actions) {
- IntentFilter filter = new IntentFilter();
+ public synchronized void register(List actions) {
+ LinkedHashSet newActions = new LinkedHashSet<>();
for (String action : actions) {
if (!StaticBroadcastReceiver.ACTIONS.contains(action)
+ && !StaticBroadcastReceiver.PACKAGE_ACTIONS.contains(action)
&& !mActions.contains(action)) {
- mActions.add(action);
- filter.addAction(action);
+ newActions.add(action);
}
}
- if (filter.countActions() == 0) {
+ if (newActions.isEmpty()) {
return;
}
- BaseBroadcastReceiver receiver = new BaseBroadcastReceiver();
- mContext.registerReceiver(receiver, filter);
+ ReceiverRegistry receiverRegistry = new ReceiverRegistry(newActions);
+ receiverRegistry.register();
+ mReceiverRegistries.add(receiverRegistry);
}
- public void unregisterAll() {
- for (BroadcastReceiver receiver : mReceivers) {
+ public synchronized void unregister(String action) {
+ if (!mActions.contains(action)) {
+ return;
+ }
+ mActions.remove(action);
+ Iterator iterator = mReceiverRegistries.iterator();
+ while (iterator.hasNext()) {
+ ReceiverRegistry receiverRegistry = iterator.next();
+ if (!receiverRegistry.actions.contains(action)) {
+ continue;
+ }
+ receiverRegistry.actions.remove(action);
+ receiverRegistry.unregister();
+ if (!receiverRegistry.register()) {
+ iterator.remove();
+ }
+ break;
+ }
+ }
+
+ public synchronized void unregisterAll() {
+ for (ReceiverRegistry registry : mReceiverRegistries) {
+ registry.unregister();
+ }
+ mReceiverRegistries.clear();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ mContext.unregisterReceiver(mDefaultActionReceiver);
+ mContext.unregisterReceiver(mPackageActionReceiver);
+ }
+ }
+
+ static IntentFilter createIntentFilter(Collection actions) {
+ IntentFilter filter = new IntentFilter();
+ for (String action : actions) {
+ filter.addAction(action);
+ }
+ return filter;
+ }
+
+ private class ReceiverRegistry {
+ BroadcastReceiver receiver;
+ LinkedHashSet actions;
+
+ ReceiverRegistry(LinkedHashSet actions) {
+ this.actions = actions;
+ receiver = new BaseBroadcastReceiver();
+ }
+
+ void unregister() {
mContext.unregisterReceiver(receiver);
}
- mReceivers.clear();
+
+ boolean register() {
+ if (actions.isEmpty())
+ return false;
+ IntentFilter intentFilter = createIntentFilter(actions);
+ mContext.registerReceiver(receiver, intentFilter);
+ Log.d(LOG_TAG, "register: " + actions);
+ return true;
+ }
}
}
diff --git a/app/src/main/java/org/autojs/autojs/external/receiver/StaticBroadcastReceiver.java b/app/src/main/java/org/autojs/autojs/external/receiver/StaticBroadcastReceiver.java
index 55b93726..31ee2ba9 100644
--- a/app/src/main/java/org/autojs/autojs/external/receiver/StaticBroadcastReceiver.java
+++ b/app/src/main/java/org/autojs/autojs/external/receiver/StaticBroadcastReceiver.java
@@ -37,4 +37,12 @@ public class StaticBroadcastReceiver extends BaseBroadcastReceiver {
"android.net.conn.CONNECTIVITY_CHANGE"
));
+ static final List PACKAGE_ACTIONS = new ArrayList<>(Arrays.asList(
+ "android.intent.action.PACKAGE_ADDED",
+ "android.intent.action.PACKAGE_CHANGED",
+ "android.intent.action.PACKAGE_DATA_CLEARED",
+ "android.intent.action.PACKAGE_REMOVED",
+ "android.intent.action.PACKAGE_RESTARTED"
+ ));
+
}
diff --git a/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerFileItem.java b/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerFileItem.java
index 443fc7a7..73fbf984 100644
--- a/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerFileItem.java
+++ b/app/src/main/java/org/autojs/autojs/model/explorer/ExplorerFileItem.java
@@ -1,6 +1,7 @@
package org.autojs.autojs.model.explorer;
import com.stardust.pio.PFile;
+import com.stardust.util.ObjectHelper;
import org.autojs.autojs.model.script.ScriptFile;
@@ -9,6 +10,7 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
+
public class ExplorerFileItem implements ExplorerItem {
private static final Set sEditableFileExts = new HashSet<>(Arrays.asList(
@@ -19,6 +21,7 @@ public class ExplorerFileItem implements ExplorerItem {
private final ExplorerPage mParent;
public ExplorerFileItem(PFile file, ExplorerPage parent) {
+ ObjectHelper.requireNonNull(file, "file");
mFile = file;
mParent = parent;
}
diff --git a/app/src/main/java/org/autojs/autojs/model/script/Scripts.java b/app/src/main/java/org/autojs/autojs/model/script/Scripts.java
index 9a73962e..6281dfdb 100644
--- a/app/src/main/java/org/autojs/autojs/model/script/Scripts.java
+++ b/app/src/main/java/org/autojs/autojs/model/script/Scripts.java
@@ -12,11 +12,13 @@ import com.stardust.autojs.execution.ScriptExecutionListener;
import com.stardust.autojs.execution.SimpleScriptExecutionListener;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.autojs.script.ScriptSource;
+import com.stardust.util.IntentUtil;
import org.autojs.autojs.Pref;
import org.autojs.autojs.R;
import org.autojs.autojs.autojs.AutoJs;
import org.autojs.autojs.external.ScriptIntents;
+import org.autojs.autojs.external.fileprovider.AppFileProvider;
import org.autojs.autojs.external.shortcut.Shortcut;
import org.autojs.autojs.external.shortcut.ShortcutActivity;
import org.autojs.autojs.ui.edit.EditActivity;
@@ -71,8 +73,7 @@ public class Scripts {
public static void openByOtherApps(String path) {
- Uri uri = Uri.parse("file://" + path);
- GlobalAppContext.get().startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(uri, "text/plain").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ IntentUtil.viewFile(GlobalAppContext.get(), path, "text/plain", AppFileProvider.AUTHORITY);
}
public static void openByOtherApps(File file) {
@@ -111,8 +112,8 @@ public class Scripts {
public static ScriptExecution run(ScriptSource source) {
try {
return AutoJs.getInstance().getScriptEngineService().execute(source, new ExecutionConfig()
- .executePath(Pref.getScriptDirPath())
- .requirePath(Pref.getScriptDirPath()));
+ .executePath(Pref.getScriptDirPath())
+ .requirePath(Pref.getScriptDirPath()));
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(GlobalAppContext.get(), e.getMessage(), Toast.LENGTH_LONG).show();
diff --git a/app/src/main/java/org/autojs/autojs/pluginclient/JsonWebSocket.java b/app/src/main/java/org/autojs/autojs/pluginclient/JsonWebSocket.java
index 73d77eab..641adf46 100644
--- a/app/src/main/java/org/autojs/autojs/pluginclient/JsonWebSocket.java
+++ b/app/src/main/java/org/autojs/autojs/pluginclient/JsonWebSocket.java
@@ -8,11 +8,7 @@ import com.google.gson.JsonParseException;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
import java.io.StringReader;
-import java.net.Socket;
import javax.annotation.Nullable;
@@ -23,7 +19,6 @@ import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
-import okio.ByteString;
public class JsonWebSocket extends WebSocketListener {
diff --git a/app/src/main/java/org/autojs/autojs/timing/TimedTaskManager.java b/app/src/main/java/org/autojs/autojs/timing/TimedTaskManager.java
index a8898ce9..b0bcd9a2 100644
--- a/app/src/main/java/org/autojs/autojs/timing/TimedTaskManager.java
+++ b/app/src/main/java/org/autojs/autojs/timing/TimedTaskManager.java
@@ -94,7 +94,12 @@ public class TimedTaskManager {
@SuppressLint("CheckResult")
public void removeTask(IntentTask intentTask) {
mIntentTaskDatabase.delete(intentTask)
- .subscribe(EmptyObservers.consumer(), Throwable::printStackTrace);;
+ .subscribe(i -> {
+ if(!TextUtils.isEmpty(intentTask.getAction())){
+ App.getApp().getDynamicBroadcastReceivers()
+ .unregister(intentTask.getAction());
+ }
+ }, Throwable::printStackTrace);
}
public Flowable getAllTasks() {
diff --git a/app/src/main/java/org/autojs/autojs/ui/common/ScriptOperations.java b/app/src/main/java/org/autojs/autojs/ui/common/ScriptOperations.java
index 5803da69..3b1b4511 100644
--- a/app/src/main/java/org/autojs/autojs/ui/common/ScriptOperations.java
+++ b/app/src/main/java/org/autojs/autojs/ui/common/ScriptOperations.java
@@ -291,14 +291,14 @@ public class ScriptOperations {
}
public void delete(final ScriptFile scriptFile) {
- new ThemeColorMaterialDialogBuilder(mContext)
+ DialogUtils.showDialog(new ThemeColorMaterialDialogBuilder(mContext)
.title(mContext.getString(R.string.text_are_you_sure_to_delete, scriptFile.getName()))
.positiveText(R.string.cancel)
.negativeText(R.string.ok)
.onNegative((dialog, which) -> {
deleteWithoutConfirm(scriptFile);
})
- .show();
+ .build());
}
diff --git a/app/src/main/java/org/autojs/autojs/ui/edit/EditActivity.java b/app/src/main/java/org/autojs/autojs/ui/edit/EditActivity.java
index 0ec43fef..2063ab26 100644
--- a/app/src/main/java/org/autojs/autojs/ui/edit/EditActivity.java
+++ b/app/src/main/java/org/autojs/autojs/ui/edit/EditActivity.java
@@ -6,6 +6,7 @@ import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
+import android.util.Log;
import android.view.ActionMode;
import android.view.Menu;
import android.view.MenuItem;
@@ -48,6 +49,7 @@ public class
EditActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHost, PermissionRequestProxyActivity {
private OnActivityResultDelegate.Mediator mMediator = new OnActivityResultDelegate.Mediator();
+ private static final String LOG_TAG = "EditActivity";
@ViewById(R.id.editor_view)
EditorView mEditorView;
@@ -125,6 +127,7 @@ EditActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHo
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
+ Log.d(LOG_TAG, "onPrepareOptionsMenu: " + menu);
boolean isScriptRunning = mEditorView.getScriptExecutionId() != ScriptExecution.NO_ID;
MenuItem forceStopItem = menu.findItem(R.id.action_force_stop);
forceStopItem.setEnabled(isScriptRunning);
@@ -132,6 +135,7 @@ EditActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHo
}
public boolean onPrepareActionMode(Menu menu) {
+ Log.d(LOG_TAG, "onPrepareActionMode: " + menu);
boolean isScriptRunning = mEditorView.getScriptExecutionId() != ScriptExecution.NO_ID;
MenuItem forceStopItem = menu.findItem(R.id.action_force_stop);
forceStopItem.setEnabled(isScriptRunning);
@@ -140,6 +144,7 @@ EditActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHo
@Override
public void onActionModeStarted(ActionMode mode) {
+ Log.d(LOG_TAG, "onActionModeStarted: " + mode);
Menu menu = mode.getMenu();
MenuItem item = menu.getItem(menu.size() - 1);
menu.add(item.getGroupId(), R.id.action_delete_line, 10000, R.string.text_delete_line);
@@ -147,6 +152,31 @@ EditActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHo
super.onActionModeStarted(mode);
}
+ @Override
+ public void onSupportActionModeStarted(@NonNull android.support.v7.view.ActionMode mode) {
+ Log.d(LOG_TAG, "onSupportActionModeStarted: mode = " + mode);
+ super.onSupportActionModeStarted(mode);
+ }
+
+ @Nullable
+ @Override
+ public android.support.v7.view.ActionMode onWindowStartingSupportActionMode(@NonNull android.support.v7.view.ActionMode.Callback callback) {
+ Log.d(LOG_TAG, "onWindowStartingSupportActionMode: callback = " + callback);
+ return super.onWindowStartingSupportActionMode(callback);
+ }
+
+ @Override
+ public ActionMode startActionMode(ActionMode.Callback callback, int type) {
+ Log.d(LOG_TAG, "startActionMode: callback = " + callback + ", type = " + type);
+ return super.startActionMode(callback, type);
+ }
+
+ @Override
+ public ActionMode startActionMode(ActionMode.Callback callback) {
+ Log.d(LOG_TAG, "startActionMode: callback = " + callback );
+ return super.startActionMode(callback);
+ }
+
@Override
public void onBackPressed() {
if (!mEditorView.onBackPressed()) {
diff --git a/app/src/main/java/org/autojs/autojs/ui/edit/EditorView.java b/app/src/main/java/org/autojs/autojs/ui/edit/EditorView.java
index 3f9b827c..96f9b73d 100644
--- a/app/src/main/java/org/autojs/autojs/ui/edit/EditorView.java
+++ b/app/src/main/java/org/autojs/autojs/ui/edit/EditorView.java
@@ -532,7 +532,7 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
return mEditor;
}
- public void find(String keywords, boolean usingRegex) {
+ public void find(String keywords, boolean usingRegex) throws CodeEditor.CheckedPatternSyntaxException {
mEditor.find(keywords, usingRegex);
showSearchToolbar(false);
}
@@ -547,12 +547,12 @@ public class EditorView extends FrameLayout implements CodeCompletionBar.OnHintC
.commit();
}
- public void replace(String keywords, String replacement, boolean usingRegex) {
+ public void replace(String keywords, String replacement, boolean usingRegex) throws CodeEditor.CheckedPatternSyntaxException {
mEditor.replace(keywords, replacement, usingRegex);
showSearchToolbar(true);
}
- public void replaceAll(String keywords, String replacement, boolean usingRegex) {
+ public void replaceAll(String keywords, String replacement, boolean usingRegex) throws CodeEditor.CheckedPatternSyntaxException {
mEditor.replaceAll(keywords, replacement, usingRegex);
}
diff --git a/app/src/main/java/org/autojs/autojs/ui/edit/FindOrReplaceDialogBuilder.java b/app/src/main/java/org/autojs/autojs/ui/edit/FindOrReplaceDialogBuilder.java
index 7cf9c876..7c2317d3 100644
--- a/app/src/main/java/org/autojs/autojs/ui/edit/FindOrReplaceDialogBuilder.java
+++ b/app/src/main/java/org/autojs/autojs/ui/edit/FindOrReplaceDialogBuilder.java
@@ -10,8 +10,11 @@ import android.widget.CheckBox;
import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
+import com.stardust.app.GlobalAppContext;
+
import org.autojs.autojs.R;
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
+import org.autojs.autojs.ui.edit.editor.CodeEditor;
import butterknife.BindView;
import butterknife.ButterKnife;
@@ -43,20 +46,16 @@ public class FindOrReplaceDialogBuilder extends ThemeColorMaterialDialogBuilder
private EditorView mEditorView;
-
public FindOrReplaceDialogBuilder(@NonNull Context context, EditorView editorView) {
super(context);
mEditorView = editorView;
setupViews();
restoreState();
- onPositive(new MaterialDialog.SingleButtonCallback() {
-
- @Override
- public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
- storeState();
- findOrReplace();
- }
-
+ autoDismiss(false);
+ onNegative((dialog, which)-> dialog.dismiss());
+ onPositive((dialog, which) -> {
+ storeState();
+ findOrReplace(dialog);
});
}
@@ -96,21 +95,27 @@ public class FindOrReplaceDialogBuilder extends ThemeColorMaterialDialogBuilder
}
}
- private void findOrReplace() {
+ private void findOrReplace(MaterialDialog dialog) {
String keywords = mKeywordsEditText.getText().toString();
if (keywords.isEmpty()) {
return;
}
- boolean usingRegex = mRegexCheckBox.isChecked();
- if (!mReplaceCheckBox.isChecked()) {
- mEditorView.find(keywords, usingRegex);
- } else {
- String replacement = mReplacementEditText.getText().toString();
- if (mReplaceAllCheckBox.isChecked()) {
- mEditorView.replaceAll(keywords, replacement, usingRegex);
+ try {
+ boolean usingRegex = mRegexCheckBox.isChecked();
+ if (!mReplaceCheckBox.isChecked()) {
+ mEditorView.find(keywords, usingRegex);
} else {
- mEditorView.replace(keywords, replacement, usingRegex);
+ String replacement = mReplacementEditText.getText().toString();
+ if (mReplaceAllCheckBox.isChecked()) {
+ mEditorView.replaceAll(keywords, replacement, usingRegex);
+ } else {
+ mEditorView.replace(keywords, replacement, usingRegex);
+ }
}
+ dialog.dismiss();
+ } catch (CodeEditor.CheckedPatternSyntaxException e) {
+ e.printStackTrace();
+ mKeywordsEditText.setError(getContext().getString(R.string.error_pattern_syntax));
}
}
diff --git a/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditor.java b/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditor.java
index 0c6eeceb..aff768ad 100644
--- a/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditor.java
+++ b/app/src/main/java/org/autojs/autojs/ui/edit/editor/CodeEditor.java
@@ -19,6 +19,7 @@ import com.stardust.util.TextUtils;
import java.util.LinkedHashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
import io.reactivex.Observable;
@@ -41,6 +42,11 @@ import io.reactivex.Observable;
*/
public class CodeEditor extends HVScrollView {
+ public static class CheckedPatternSyntaxException extends Exception {
+ public CheckedPatternSyntaxException(PatternSyntaxException cause) {
+ super(cause);
+ }
+ }
public interface CursorChangeCallback {
@@ -222,9 +228,13 @@ public class CodeEditor extends HVScrollView {
mTextViewRedoUndo.redo();
}
- public void find(String keywords, boolean usingRegex) {
+ public void find(String keywords, boolean usingRegex) throws CheckedPatternSyntaxException {
if (usingRegex) {
- mMatcher = Pattern.compile(keywords).matcher(mCodeEditText.getText());
+ try {
+ mMatcher = Pattern.compile(keywords).matcher(mCodeEditText.getText());
+ }catch (PatternSyntaxException e){
+ throw new CheckedPatternSyntaxException(e);
+ }
mKeywords = null;
} else {
mKeywords = keywords;
@@ -233,17 +243,21 @@ public class CodeEditor extends HVScrollView {
findNext();
}
- public void replace(String keywords, String replacement, boolean usingRegex) {
+ public void replace(String keywords, String replacement, boolean usingRegex) throws CheckedPatternSyntaxException {
mReplacement = replacement == null ? "" : replacement;
find(keywords, usingRegex);
}
- public void replaceAll(String keywords, String replacement, boolean usingRegex) {
+ public void replaceAll(String keywords, String replacement, boolean usingRegex) throws CheckedPatternSyntaxException {
if (!usingRegex) {
keywords = Pattern.quote(keywords);
}
String text = mCodeEditText.getText().toString();
- text = text.replaceAll(keywords, replacement);
+ try {
+ text = text.replaceAll(keywords, replacement);
+ }catch (PatternSyntaxException e){
+ throw new CheckedPatternSyntaxException(e);
+ }
setText(text);
}
diff --git a/app/src/main/java/org/autojs/autojs/ui/edit/editor/JavaScriptHighlighter.java b/app/src/main/java/org/autojs/autojs/ui/edit/editor/JavaScriptHighlighter.java
index 7037a3ff..750ce697 100644
--- a/app/src/main/java/org/autojs/autojs/ui/edit/editor/JavaScriptHighlighter.java
+++ b/app/src/main/java/org/autojs/autojs/ui/edit/editor/JavaScriptHighlighter.java
@@ -40,6 +40,12 @@ public class JavaScriptHighlighter implements SimpleTextWatcher.AfterTextChanged
}
public void addToken(int tokenStart, int tokenEnd, int color) {
+ if(mCount < tokenStart){
+ int c = mCount > 0 ? colors[mCount - 1] : color;
+ for (int i = mCount; i < tokenStart; i++) {
+ colors[i] = c;
+ }
+ }
for (int i = tokenStart; i < tokenEnd; i++) {
colors[i] = color;
}
diff --git a/app/src/main/java/org/autojs/autojs/ui/filechooser/FileChooserDialogBuilder.java b/app/src/main/java/org/autojs/autojs/ui/filechooser/FileChooserDialogBuilder.java
index abd73d02..9ed471b3 100644
--- a/app/src/main/java/org/autojs/autojs/ui/filechooser/FileChooserDialogBuilder.java
+++ b/app/src/main/java/org/autojs/autojs/ui/filechooser/FileChooserDialogBuilder.java
@@ -6,7 +6,6 @@ import android.support.annotation.StringRes;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.pio.PFile;
-import com.tencent.bugly.crashreport.BuglyLog;
import org.autojs.autojs.R;
import org.autojs.autojs.model.explorer.Explorer;
diff --git a/app/src/main/java/org/autojs/autojs/ui/floating/CircularMenuWindow.java b/app/src/main/java/org/autojs/autojs/ui/floating/CircularMenuWindow.java
index 8f57a5e6..12ef5e99 100644
--- a/app/src/main/java/org/autojs/autojs/ui/floating/CircularMenuWindow.java
+++ b/app/src/main/java/org/autojs/autojs/ui/floating/CircularMenuWindow.java
@@ -3,6 +3,7 @@ package org.autojs.autojs.ui.floating;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
+import android.view.Gravity;
import android.view.OrientationEventListener;
import android.view.View;
import android.view.WindowManager;
@@ -94,8 +95,10 @@ public class CircularMenuWindow implements FloatyWindow {
}
private WindowManager.LayoutParams createWindowLayoutParams() {
- WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(-2, -2, 2003, 520, -3);
- layoutParams.gravity = 51;
+ WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
+ WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT,
+ FloatyWindowManger.getWindowType(), 520, -3);
+ layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
return layoutParams;
}
diff --git a/app/src/main/java/org/autojs/autojs/ui/floating/FloatyWindowManger.java b/app/src/main/java/org/autojs/autojs/ui/floating/FloatyWindowManger.java
index 54dec712..6bb1f31e 100644
--- a/app/src/main/java/org/autojs/autojs/ui/floating/FloatyWindowManger.java
+++ b/app/src/main/java/org/autojs/autojs/ui/floating/FloatyWindowManger.java
@@ -2,6 +2,8 @@ package org.autojs.autojs.ui.floating;
import android.content.Context;
import android.content.Intent;
+import android.os.Build;
+import android.view.WindowManager;
import android.widget.Toast;
import com.stardust.app.GlobalAppContext;
@@ -9,9 +11,11 @@ import com.stardust.autojs.util.FloatingPermission;
import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.enhancedfloaty.FloatyWindow;
import com.stardust.enhancedfloaty.util.FloatingWindowPermissionUtil;
+
import org.autojs.autojs.App;
import org.autojs.autojs.R;
import org.autojs.autojs.ui.floating.CircularMenu;
+
import com.stardust.util.IntentUtil;
import java.lang.ref.WeakReference;
@@ -74,4 +78,12 @@ public class FloatyWindowManger {
menu.close();
sCircularMenu = null;
}
+
+ public static int getWindowType() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ return WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+ } else {
+ return WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+ }
+ }
}
diff --git a/app/src/main/java/org/autojs/autojs/ui/main/MainActivity.java b/app/src/main/java/org/autojs/autojs/ui/main/MainActivity.java
index c8d716dd..606485f7 100644
--- a/app/src/main/java/org/autojs/autojs/ui/main/MainActivity.java
+++ b/app/src/main/java/org/autojs/autojs/ui/main/MainActivity.java
@@ -176,6 +176,8 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
}
private void setUpViewPagerFragmentBehaviors() {
+
+
mPagerAdapter.setOnFragmentInstantiateListener((pos, fragment) -> {
((ViewPagerFragment) fragment).setFab(mFab);
if (pos == mViewPager.getCurrentItem()) {
diff --git a/app/src/main/java/org/autojs/autojs/ui/main/community/CommunityFragment.java b/app/src/main/java/org/autojs/autojs/ui/main/community/CommunityFragment.java
index e9f0b637..4cfc18b3 100644
--- a/app/src/main/java/org/autojs/autojs/ui/main/community/CommunityFragment.java
+++ b/app/src/main/java/org/autojs/autojs/ui/main/community/CommunityFragment.java
@@ -63,7 +63,7 @@ public class CommunityFragment extends ViewPagerFragment implements BackPressedH
@AfterViews
void setUpViews() {
mWebView = mEWebView.getWebView();
- String url = "http://www.autojs.org/";
+ String url = "https://www.autojs.org/";
Bundle savedWebViewState = getArguments().getBundle("savedWebViewState");
if (savedWebViewState != null) {
mWebView.restoreState(savedWebViewState);
diff --git a/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.java b/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.java
index 09643151..49e176eb 100644
--- a/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.java
+++ b/app/src/main/java/org/autojs/autojs/ui/main/drawer/DrawerFragment.java
@@ -239,9 +239,9 @@ public class DrawerFragment extends android.support.v4.app.Fragment {
SettingsActivity.selectThemeColor(getActivity());
}
+ @SuppressLint("CheckResult")
private void enableAccessibilityServiceByRootIfNeeded() {
Observable.fromCallable(() -> Pref.shouldEnableAccessibilityServiceByRoot() && !isAccessibilityServiceEnabled())
- .subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(needed -> {
if (needed) {
diff --git a/app/src/main/java/org/autojs/autojs/ui/main/scripts/MyScriptListFragment.java b/app/src/main/java/org/autojs/autojs/ui/main/scripts/MyScriptListFragment.java
index a8fd7241..559bf5aa 100644
--- a/app/src/main/java/org/autojs/autojs/ui/main/scripts/MyScriptListFragment.java
+++ b/app/src/main/java/org/autojs/autojs/ui/main/scripts/MyScriptListFragment.java
@@ -5,10 +5,8 @@ import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.design.widget.FloatingActionButton;
-import android.support.v7.widget.RecyclerView;
import com.stardust.app.GlobalAppContext;
-import com.stardust.util.BackPressedHandler;
import com.stardust.util.IntentUtil;
import org.androidannotations.annotations.AfterViews;
@@ -16,6 +14,7 @@ import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.ViewById;
import org.autojs.autojs.Pref;
import org.autojs.autojs.R;
+import org.autojs.autojs.external.fileprovider.AppFileProvider;
import org.autojs.autojs.model.explorer.ExplorerDirPage;
import org.autojs.autojs.model.explorer.Explorers;
import org.autojs.autojs.model.script.Scripts;
@@ -28,7 +27,6 @@ import org.autojs.autojs.ui.main.ViewPagerFragment;
import org.autojs.autojs.ui.project.ProjectConfigActivity;
import org.autojs.autojs.ui.project.ProjectConfigActivity_;
import org.autojs.autojs.ui.viewmodel.ExplorerItemList;
-import org.autojs.autojs.ui.widget.ExpandableRecyclerView;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
@@ -66,7 +64,7 @@ public class MyScriptListFragment extends ViewPagerFragment implements FloatingA
if (item.isEditable()) {
Scripts.edit(item.toScriptFile());
} else {
- IntentUtil.viewFile(GlobalAppContext.get(), item.getPath());
+ IntentUtil.viewFile(GlobalAppContext.get(), item.getPath(), AppFileProvider.AUTHORITY);
}
});
}
diff --git a/app/src/main/java/org/autojs/autojs/ui/project/BuildActivity.java b/app/src/main/java/org/autojs/autojs/ui/project/BuildActivity.java
index 2eadd7f1..e413073c 100644
--- a/app/src/main/java/org/autojs/autojs/ui/project/BuildActivity.java
+++ b/app/src/main/java/org/autojs/autojs/ui/project/BuildActivity.java
@@ -25,10 +25,12 @@ import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.ViewById;
+import org.autojs.autojs.App;
import org.autojs.autojs.Pref;
import org.autojs.autojs.R;
import org.autojs.autojs.autojs.build.AutoJsApkBuilder;
import org.autojs.autojs.build.ApkBuilderPluginHelper;
+import org.autojs.autojs.external.fileprovider.AppFileProvider;
import org.autojs.autojs.model.script.ScriptFile;
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
import org.autojs.autojs.tool.BitmapTool;
@@ -53,6 +55,8 @@ import io.reactivex.schedulers.Schedulers;
@EActivity(R.layout.activity_build)
public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.ProgressCallback {
+ private static final int REQUEST_CODE = 44401;
+
public static final String EXTRA_SOURCE = BuildActivity.class.getName() + ".extra_source_file";
private static final String LOG_TAG = "BuildActivity";
@@ -194,7 +198,7 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
@Click(R.id.icon)
void selectIcon() {
ShortcutIconSelectActivity_.intent(this)
- .startForResult(31209);
+ .startForResult(REQUEST_CODE);
}
@Click(R.id.fab)
@@ -299,7 +303,7 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
.positiveText(R.string.text_install)
.negativeText(R.string.cancel)
.onPositive((dialog, which) ->
- IntentUtil.installApk(BuildActivity.this, outApk.getPath())
+ IntentUtil.installApk(BuildActivity.this, outApk.getPath(), AppFileProvider.AUTHORITY)
)
.show();
@@ -333,27 +337,13 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
if (resultCode != RESULT_OK) {
return;
}
- String packageName = data.getStringExtra(ShortcutIconSelectActivity.EXTRA_PACKAGE_NAME);
- if (packageName != null) {
- try {
- mIcon.setImageDrawable(getPackageManager().getApplicationIcon(packageName));
- mIsDefaultIcon = false;
- } catch (PackageManager.NameNotFoundException e) {
- e.printStackTrace();
- }
- return;
- }
- if (data.getData() == null)
- return;
- Observable.fromCallable(() -> BitmapFactory.decodeStream(getContentResolver().openInputStream(data.getData())))
- .subscribeOn(Schedulers.computation())
+ ShortcutIconSelectActivity.getBitmapFromIntent(getApplicationContext(), data)
+ .subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
- .subscribe((bitmap -> {
+ .subscribe(bitmap -> {
mIcon.setImageBitmap(bitmap);
mIsDefaultIcon = false;
- }), error -> {
- Log.e(LOG_TAG, "decode stream", error);
- });
+ }, Throwable::printStackTrace);
}
diff --git a/app/src/main/java/org/autojs/autojs/ui/project/ProjectConfigActivity.java b/app/src/main/java/org/autojs/autojs/ui/project/ProjectConfigActivity.java
index 3950d0f6..d6b834d4 100644
--- a/app/src/main/java/org/autojs/autojs/ui/project/ProjectConfigActivity.java
+++ b/app/src/main/java/org/autojs/autojs/ui/project/ProjectConfigActivity.java
@@ -1,6 +1,8 @@
package org.autojs.autojs.ui.project;
import android.annotation.SuppressLint;
+import android.content.Intent;
+import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TextInputEditText;
@@ -12,7 +14,6 @@ import android.widget.ImageView;
import android.widget.Toast;
import com.stardust.autojs.project.ProjectConfig;
-import com.stardust.autojs.runtime.api.Dialogs;
import com.stardust.pio.PFiles;
import org.androidannotations.annotations.AfterViews;
@@ -22,14 +23,18 @@ import org.androidannotations.annotations.ViewById;
import org.autojs.autojs.R;
import org.autojs.autojs.model.explorer.ExplorerDirPage;
import org.autojs.autojs.model.explorer.ExplorerFileItem;
-import org.autojs.autojs.model.explorer.ExplorerItem;
import org.autojs.autojs.model.explorer.Explorers;
import org.autojs.autojs.model.project.ProjectTemplate;
+import org.autojs.autojs.network.GlideApp;
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
import org.autojs.autojs.ui.BaseActivity;
+import org.autojs.autojs.ui.shortcut.ShortcutIconSelectActivity;
+import org.autojs.autojs.ui.shortcut.ShortcutIconSelectActivity_;
import org.autojs.autojs.ui.widget.SimpleTextWatcher;
import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -44,6 +49,8 @@ public class ProjectConfigActivity extends BaseActivity {
public static final String EXTRA_DIRECTORY = "directory";
+ private static final int REQUEST_CODE = 12477;
+
@ViewById(R.id.project_location)
EditText mProjectLocation;
@@ -70,6 +77,7 @@ public class ProjectConfigActivity extends BaseActivity {
private File mParentDirectory;
private ProjectConfig mProjectConfig;
private boolean mNewProject;
+ private Bitmap mIconBitmap;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -118,6 +126,12 @@ public class ProjectConfigActivity extends BaseActivity {
mVersionName.setText(mProjectConfig.getVersionName());
mMainFileName.setText(mProjectConfig.getMainScriptFile());
mProjectLocation.setVisibility(View.GONE);
+ String icon = mProjectConfig.getIcon();
+ if (icon != null) {
+ GlideApp.with(this)
+ .load(new File(mDirectory, icon))
+ .into(mIcon);
+ }
}
}
@@ -128,9 +142,22 @@ public class ProjectConfigActivity extends BaseActivity {
if (!checkInputs()) {
return;
}
+ if (mIconBitmap != null) {
+ saveIcon(mIconBitmap)
+ .subscribe(ignored -> saveProjectConfig(), e -> {
+ e.printStackTrace();
+ Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
+ });
+ } else {
+ saveProjectConfig();
+ }
+
+ }
+
+ @SuppressLint("CheckResult")
+ private void saveProjectConfig() {
if (mNewProject) {
- String location = mProjectLocation.getText().toString();
- new ProjectTemplate(mProjectConfig, new File(location))
+ new ProjectTemplate(mProjectConfig, mDirectory)
.newProject()
.subscribe(ignored -> {
Explorers.workspace().notifyChildrenChanged(new ExplorerDirPage(mParentDirectory, null));
@@ -158,12 +185,22 @@ public class ProjectConfigActivity extends BaseActivity {
}
}
+ @Click(R.id.icon)
+ void selectIcon() {
+ ShortcutIconSelectActivity_.intent(this)
+ .startForResult(REQUEST_CODE);
+ }
+
private void syncProjectConfig() {
mProjectConfig.setName(mAppName.getText().toString());
mProjectConfig.setVersionCode(Integer.parseInt(mVersionCode.getText().toString()));
mProjectConfig.setVersionName(mVersionName.getText().toString());
mProjectConfig.setMainScriptFile(mMainFileName.getText().toString());
mProjectConfig.setPackageName(mPackageName.getText().toString());
+ if (mNewProject) {
+ String location = mProjectLocation.getText().toString();
+ mDirectory = new File(location);
+ }
//mProjectConfig.getLaunchConfig().setHideLogs(true);
}
@@ -184,4 +221,43 @@ public class ProjectConfigActivity extends BaseActivity {
editText.setError(hint + getString(R.string.text_should_not_be_empty));
return false;
}
+
+
+ @SuppressLint("CheckResult")
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode != RESULT_OK) {
+ return;
+ }
+ ShortcutIconSelectActivity.getBitmapFromIntent(getApplicationContext(), data)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(bitmap -> {
+ mIcon.setImageBitmap(bitmap);
+ mIconBitmap = bitmap;
+ },
+ Throwable::printStackTrace);
+ }
+
+ @SuppressLint("CheckResult")
+ private Observable saveIcon(Bitmap b) {
+ return Observable.just(b)
+ .map(bitmap -> {
+ String iconPath = mProjectConfig.getIcon();
+ if (iconPath == null) {
+ iconPath = "res/logo.png";
+ }
+ File iconFile = new File(mDirectory, iconPath);
+ PFiles.ensureDir(iconFile.getPath());
+ FileOutputStream fos = new FileOutputStream(iconFile);
+ bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
+ fos.close();
+ return iconPath;
+ })
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .doOnNext(iconPath -> mProjectConfig.setIcon(iconPath));
+
+ }
+
}
diff --git a/app/src/main/java/org/autojs/autojs/ui/shortcut/ShortcutCreateActivity.java b/app/src/main/java/org/autojs/autojs/ui/shortcut/ShortcutCreateActivity.java
index 54368f49..67716426 100644
--- a/app/src/main/java/org/autojs/autojs/ui/shortcut/ShortcutCreateActivity.java
+++ b/app/src/main/java/org/autojs/autojs/ui/shortcut/ShortcutCreateActivity.java
@@ -6,6 +6,7 @@ import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Icon;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PersistableBundle;
@@ -131,6 +132,7 @@ public class ShortcutCreateActivity extends AppCompatActivity {
}
+ @SuppressLint("CheckResult")
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) {
@@ -146,7 +148,11 @@ public class ShortcutCreateActivity extends AppCompatActivity {
}
return;
}
- Observable.fromCallable(() -> BitmapFactory.decodeStream(getContentResolver().openInputStream(data.getData())))
+ Uri uri = data.getData();
+ if(uri == null){
+ return;
+ }
+ Observable.fromCallable(() -> BitmapFactory.decodeStream(getContentResolver().openInputStream(uri)))
.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe((bitmap -> {
diff --git a/app/src/main/java/org/autojs/autojs/ui/shortcut/ShortcutIconSelectActivity.java b/app/src/main/java/org/autojs/autojs/ui/shortcut/ShortcutIconSelectActivity.java
index 0cb1968f..fb0521ee 100644
--- a/app/src/main/java/org/autojs/autojs/ui/shortcut/ShortcutIconSelectActivity.java
+++ b/app/src/main/java/org/autojs/autojs/ui/shortcut/ShortcutIconSelectActivity.java
@@ -5,7 +5,10 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ShortcutManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
+import android.net.Uri;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
@@ -16,6 +19,7 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import org.autojs.autojs.R;
+import org.autojs.autojs.tool.BitmapTool;
import org.autojs.autojs.ui.BaseActivity;
import org.androidannotations.annotations.AfterViews;
@@ -24,6 +28,7 @@ import org.androidannotations.annotations.ViewById;
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.Callable;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -97,6 +102,23 @@ public class ShortcutIconSelectActivity extends BaseActivity {
}
}
+ public static Observable getBitmapFromIntent(Context context, Intent data) {
+ String packageName = data.getStringExtra(EXTRA_PACKAGE_NAME);
+ if (packageName != null) {
+ return Observable.fromCallable(() -> {
+ Drawable drawable = context.getPackageManager().getApplicationIcon(packageName);
+ return BitmapTool.drawableToBitmap(drawable);
+ });
+ }
+ Uri uri = data.getData();
+ if (uri == null) {
+ return Observable.error(new IllegalArgumentException("invalid intent"));
+ }
+ return Observable.fromCallable(() ->
+ BitmapFactory.decodeStream(context.getContentResolver().openInputStream(uri))
+ );
+ }
+
private class AppItem {
Drawable icon;
ApplicationInfo info;
diff --git a/app/src/main/java/org/autojs/autojs/ui/splash/SplashActivity.java b/app/src/main/java/org/autojs/autojs/ui/splash/SplashActivity.java
index ec5f693a..62411794 100644
--- a/app/src/main/java/org/autojs/autojs/ui/splash/SplashActivity.java
+++ b/app/src/main/java/org/autojs/autojs/ui/splash/SplashActivity.java
@@ -3,19 +3,16 @@ package org.autojs.autojs.ui.splash;
import android.Manifest;
import android.os.Bundle;
import android.os.Handler;
+import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
-import android.widget.ImageView;
+import com.stardust.autojs.core.image.OpenCVHelper;
import com.xcy8.ads.listener.LoadAdListener;
import com.xcy8.ads.view.FullScreenAdView;
-import com.xcy8.ads.view.skipview.OnFullScreenListener;
-import org.androidannotations.annotations.AfterViews;
-import org.androidannotations.annotations.EActivity;
-import org.androidannotations.annotations.ViewById;
import org.autojs.autojs.Constants;
import org.autojs.autojs.Pref;
import org.autojs.autojs.R;
@@ -33,6 +30,7 @@ public class SplashActivity extends BaseActivity {
public static final String FORCE_SHOW_AD = "forceShowAd";
private static final String LOG_TAG = SplashActivity.class.getSimpleName();
+ private static final long INIT_TIMEOUT = 1500;
private boolean mCanEnterNextActivity = false;
@@ -47,19 +45,31 @@ public class SplashActivity extends BaseActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mHandler = new Handler();
- mNotStartMainActivity = getIntent().getBooleanExtra(NOT_START_MAIN_ACTIVITY, false);
+ init();
boolean forceShowAd = getIntent().getBooleanExtra(FORCE_SHOW_AD, false);
- setContentView(R.layout.activity_splash);
- mFullScreenAdView = findViewById(R.id.full_screen_view);
+ final long millis = SystemClock.uptimeMillis();
if (!forceShowAd && !Pref.shouldShowAd()) {
mFullScreenAdView.setVisibility(View.INVISIBLE);
- mHandler.postDelayed(this::enterNextActivity, 1500);
} else {
- if(checkPermission(Manifest.permission.READ_PHONE_STATE)){
+ if (checkPermission(Manifest.permission.READ_PHONE_STATE)) {
fetchSplashAD();
}
}
+ OpenCVHelper.initIfNeeded(this, () -> {
+ long delay = INIT_TIMEOUT - (SystemClock.uptimeMillis() - millis);
+ if (delay <= 0) {
+ enterNextActivity();
+ return;
+ }
+ mHandler.postDelayed(SplashActivity.this::enterNextActivity, delay);
+ });
+ }
+
+ private void init() {
+ setContentView(R.layout.activity_splash);
+ mFullScreenAdView = findViewById(R.id.full_screen_view);
+ mHandler = new Handler();
+ mNotStartMainActivity = getIntent().getBooleanExtra(NOT_START_MAIN_ACTIVITY, false);
}
void enterNextActivity() {
@@ -116,7 +126,7 @@ public class SplashActivity extends BaseActivity {
});
mHandler.postDelayed(() -> {
if (mAdLoading) {
- enterNextActivity();
+ enterNextActivity();
}
}, 2000);
mFullScreenAdView.loadAd(getAdId(), false);
diff --git a/app/src/main/java/org/autojs/autojs/ui/update/UpdateInfoDialogBuilder.java b/app/src/main/java/org/autojs/autojs/ui/update/UpdateInfoDialogBuilder.java
index 95b7e819..f0837477 100644
--- a/app/src/main/java/org/autojs/autojs/ui/update/UpdateInfoDialogBuilder.java
+++ b/app/src/main/java/org/autojs/autojs/ui/update/UpdateInfoDialogBuilder.java
@@ -20,6 +20,7 @@ import com.stardust.util.IntentUtil;
import org.autojs.autojs.BuildConfig;
import org.autojs.autojs.Pref;
import org.autojs.autojs.R;
+import org.autojs.autojs.external.fileprovider.AppFileProvider;
import org.autojs.autojs.network.download.DownloadManager;
import org.autojs.autojs.network.entity.VersionInfo;
import org.autojs.autojs.tool.IntentTool;
@@ -118,7 +119,7 @@ public class UpdateInfoDialogBuilder extends MaterialDialog.Builder {
final String path = new File(Pref.getScriptDirPath(), "AutoJs.apk").getPath();
DownloadManager.getInstance().downloadWithProgress(getContext(), downloadUrl, path)
.subscribeOn(AndroidSchedulers.mainThread())
- .subscribe(file -> IntentUtil.installApk(getContext(), file.getPath()),
+ .subscribe(file -> IntentUtil.installApk(getContext(), file.getPath(), AppFileProvider.AUTHORITY),
error -> {
error.printStackTrace();
Toast.makeText(getContext(), R.string.text_download_failed, Toast.LENGTH_SHORT).show();
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index d7849859..8cf59738 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -71,6 +71,7 @@
耳机插拔时
每分钟一次
某些设置(屏幕方向,地区等)更改时
+ 正则表达式错误
diff --git a/app/src/main/res/xml/provider_paths.xml b/app/src/main/res/xml/provider_paths.xml
index ffa74ab5..3e5ddda3 100644
--- a/app/src/main/res/xml/provider_paths.xml
+++ b/app/src/main/res/xml/provider_paths.xml
@@ -1,4 +1,6 @@
+
+
\ No newline at end of file
diff --git a/autojs/build.gradle b/autojs/build.gradle
index 9e221666..d2f8af64 100644
--- a/autojs/build.gradle
+++ b/autojs/build.gradle
@@ -1,12 +1,12 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion 27
- buildToolsVersion '27.0.3'
+ compileSdkVersion versions.compile
+ buildToolsVersion versions.buildTool
defaultConfig {
- minSdkVersion 17
- targetSdkVersion 25
+ minSdkVersion versions.mini
+ targetSdkVersion versions.target
versionCode 1
versionName "1.0"
@@ -35,35 +35,34 @@ repositories {
}
dependencies {
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
- testCompile 'junit:junit:4.12'
- compile fileTree(dir: 'libs', include: ['*.jar'])
- compile 'org.greenrobot:eventbus:3.0.0'
- compile 'net.lingala.zip4j:zip4j:1.3.2'
- compile('com.afollestad.material-dialogs:core:0.9.2.3', {
+ testImplementation 'junit:junit:4.12'
+ api fileTree(dir: 'libs', include: ['*.jar'])
+ api 'org.greenrobot:eventbus:3.0.0'
+ api 'net.lingala.zip4j:zip4j:1.3.2'
+ api('com.afollestad.material-dialogs:core:0.9.2.3', {
exclude group: 'com.android.support'
})
- compile 'com.android.support:design:25.4.0'
- compile 'com.android.support:appcompat-v7:25.4.0'
- compile 'com.github.hyb1996:EnhancedFloaty:0.21'
- compile 'com.github.hyb1996:OpenCvLib:2.4.13.4-imgproc'
- compile 'com.makeramen:roundedimageview:2.3.0'
+ api 'com.android.support:design:28.0.0'
+ api 'com.github.hyb1996:EnhancedFloaty:0.21'
+ api 'com.github.hyb1996:OpenCvLib:2.4.13.4-imgproc'
+ api 'com.makeramen:roundedimageview:2.3.0'
// OkHttp
- compile 'com.squareup.okhttp3:okhttp:3.9.0'
+ api 'com.squareup.okhttp3:okhttp:3.10.0'
//JDeferred
- compile 'org.jdeferred:jdeferred-android-aar:1.2.6'
+ api 'org.jdeferred:jdeferred-android-aar:1.2.6'
//RootShell
- compile 'com.github.Stericson:RootShell:1.6'
+ api 'com.github.Stericson:RootShell:1.6'
// Gson
- compile 'com.google.code.gson:gson:2.8.0'
+ api 'com.google.code.gson:gson:2.8.2'
// Terminal emulator
- compile(name: 'libtermexec-release', ext: 'aar')
- compile(name: 'emulatorview-release', ext: 'aar')
- compile(name: 'term-debug', ext: 'aar')
- compile files('libs/rhino-1.7.7.2.jar')
- compile project(path: ':common')
- compile project(path: ':automator')
+ api(name: 'libtermexec-release', ext: 'aar')
+ api(name: 'emulatorview-release', ext: 'aar')
+ api(name: 'term-debug', ext: 'aar')
+ api files('libs/rhino-1.7.7.2.jar')
+ api project(path: ':common')
+ api project(path: ':automator')
}
diff --git a/autojs/src/main/AndroidManifest.xml b/autojs/src/main/AndroidManifest.xml
index 39c0a23a..bf47a035 100644
--- a/autojs/src/main/AndroidManifest.xml
+++ b/autojs/src/main/AndroidManifest.xml
@@ -7,6 +7,7 @@
+
result = new VolatileBox<>();
+ mAccessibilityBridge.post(() -> result.setAndNotify(findImpl()));
+ return result.blockedGet();
+ }
+ return findImpl();
+ }
+
+ @NonNull
+ @ScriptInterface
+ protected UiObjectCollection findImpl() {
AccessibilityNodeInfo root = mAccessibilityBridge.getRootInCurrentWindow();
if (BuildConfig.DEBUG)
Log.d(TAG, "find: root = " + root);
@@ -98,6 +112,7 @@ public class UiSelector extends UiGlobalSelector {
return regex;
}
+
@Override
public UiGlobalSelector classNameMatches(String regex) {
return super.classNameMatches(convertRegex(regex));
diff --git a/autojs/src/main/java/com/stardust/autojs/core/console/ConsoleFloaty.java b/autojs/src/main/java/com/stardust/autojs/core/console/ConsoleFloaty.java
index a6349951..a6a91a51 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/console/ConsoleFloaty.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/console/ConsoleFloaty.java
@@ -80,7 +80,7 @@ public class ConsoleFloaty extends ResizableExpandableFloaty.AbstractResizableEx
}
private void initConsoleTitle(View view) {
- mTitleView = (TextView) view.findViewById(R.id.title);
+ mTitleView = view.findViewById(R.id.title);
if (mTitle != null) {
mTitleView.setText(mTitle);
}
@@ -91,7 +91,7 @@ public class ConsoleFloaty extends ResizableExpandableFloaty.AbstractResizableEx
}
private void setUpConsole(View view, ResizableExpandableFloatyWindow window) {
- ConsoleView consoleView = (ConsoleView) view.findViewById(R.id.console);
+ ConsoleView consoleView = view.findViewById(R.id.console);
consoleView.setConsole(mConsole);
consoleView.setWindow(window);
initConsoleTitle(view);
diff --git a/autojs/src/main/java/com/stardust/autojs/core/floaty/RawWindow.java b/autojs/src/main/java/com/stardust/autojs/core/floaty/RawWindow.java
index d7d9e7a7..a2dbc401 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/floaty/RawWindow.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/floaty/RawWindow.java
@@ -66,10 +66,16 @@ public class RawWindow implements FloatyWindow {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
flags |= WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
}
+ int type;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+ } else {
+ type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
+ }
WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
- WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
+ type,
flags,
PixelFormat.TRANSLUCENT);
layoutParams.gravity = Gravity.TOP | Gravity.START;
diff --git a/autojs/src/main/java/com/stardust/autojs/core/graphics/ScriptCanvas.java b/autojs/src/main/java/com/stardust/autojs/core/graphics/ScriptCanvas.java
index 69c1980c..f135315b 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/graphics/ScriptCanvas.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/graphics/ScriptCanvas.java
@@ -93,10 +93,6 @@ public class ScriptCanvas {
return mCanvas.save();
}
- public int save(int saveFlags) {
- return mCanvas.save(saveFlags);
- }
-
public int saveLayer(@Nullable RectF bounds, @Nullable Paint paint, int saveFlags) {
return mCanvas.saveLayer(bounds, paint, saveFlags);
}
diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/OpenCVHelper.java b/autojs/src/main/java/com/stardust/autojs/core/image/OpenCVHelper.java
index 86dfe0b0..06122a98 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/image/OpenCVHelper.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/image/OpenCVHelper.java
@@ -1,8 +1,14 @@
package com.stardust.autojs.core.image;
+import android.app.Activity;
import android.support.annotation.Nullable;
import android.util.Log;
+import com.afollestad.materialdialogs.MaterialDialog;
+
+import org.opencv.android.InstallCallbackInterface;
+import org.opencv.android.LoaderCallbackInterface;
+import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
/**
@@ -11,8 +17,12 @@ import org.opencv.core.Mat;
public class OpenCVHelper {
+ public interface InitializeCallback {
+ void onInitFinish();
+ }
- private static final String LOG_TAG = "OpenCv";
+ private static final String LOG_TAG = "OpenCVHelper";
+ private static boolean mInitialized = false;
public static void release(@Nullable Mat mat) {
if (mat == null)
@@ -20,4 +30,103 @@ public class OpenCVHelper {
mat.release();
}
+ public static void initIfNeeded(Activity activity, InitializeCallback callback) {
+ if (mInitialized) {
+ callback.onInitFinish();
+ return;
+ }
+ mInitialized = true;
+ OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, activity.getApplicationContext(), new LoaderCallback(activity) {
+
+ @Override
+ protected void finish() {
+ callback.onInitFinish();
+ }
+ });
+ }
+
+ public static class LoaderCallback implements LoaderCallbackInterface {
+ private Activity mActivity;
+
+ public LoaderCallback(Activity activity) {
+ this.mActivity = activity;
+ }
+
+ public void onManagerConnected(int status) {
+ switch (status) {
+ case 0:
+ finish();
+ break;
+ case 1:
+ default:
+ Log.e(LOG_TAG, "OpenCV loading failed!");
+ new MaterialDialog.Builder(mActivity)
+ .title("OpenCV error")
+ .content("OpenCV was not initialised correctly. Application will be shut down")
+ .cancelable(false)
+ .positiveText("OK")
+ .onPositive((dialog, which) -> finish())
+ .show();
+ break;
+ case 2:
+ Log.e(LOG_TAG, "Package installation failed!");
+ new MaterialDialog.Builder(mActivity)
+ .title("OpenCV Manager")
+ .content("Package installation failed!")
+ .cancelable(false)
+ .positiveText("OK")
+ .onPositive((dialog, which) -> finish())
+ .show();
+ break;
+ case 3:
+ Log.d(LOG_TAG, "OpenCV library instalation was canceled by user");
+ finish();
+ break;
+ case 4:
+ Log.d(LOG_TAG, "OpenCV Manager Service is uncompatible with this app!");
+ new MaterialDialog.Builder(mActivity)
+ .title("OpenCV Manager")
+ .content("OpenCV Manager service is incompatible with this app. Try to update it via Google Play.")
+ .cancelable(false)
+ .positiveText("OK")
+ .onPositive((dialog, which) -> finish())
+ .show();
+ }
+
+ }
+
+ public void onPackageInstall(int operation, final InstallCallbackInterface callback) {
+ switch (operation) {
+ case 0:
+ new MaterialDialog.Builder(mActivity)
+ .title("Package not found")
+ .content(callback.getPackageName() + " package was not found! Try to install it?")
+ .cancelable(false)
+ .positiveText("Yes")
+ .onPositive((dialog, which) -> callback.install())
+ .negativeText("No")
+ .onNegative(((dialog, which) -> callback.cancel()))
+ .show();
+ break;
+ case 1:
+ new MaterialDialog.Builder(mActivity)
+ .title("OpenCV is not ready")
+ .content("Installation is in progress. Wait or exit?")
+ .cancelable(false)
+ .positiveText("Wait")
+ .onPositive((dialog, which) -> callback.wait_install())
+ .negativeText("Exit")
+ .onNegative(((dialog, which) -> callback.cancel()))
+ .show();
+ default:
+ finish();
+ }
+
+ }
+
+ protected void finish() {
+ mActivity.finish();
+ }
+ }
+
}
diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/LinearLayoutInflater.java b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/LinearLayoutInflater.java
index 81cb5a91..fd150e45 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/LinearLayoutInflater.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/LinearLayoutInflater.java
@@ -19,6 +19,12 @@ public class LinearLayoutInflater extends ViewGroupInfla
.map("vertical", LinearLayout.VERTICAL)
.map("horizontal", LinearLayout.HORIZONTAL);
+ static final ValueMapper SHOW_DIVIDERS = new ValueMapper("showDividers")
+ .map("beginning", LinearLayout.SHOW_DIVIDER_BEGINNING)
+ .map("middle", LinearLayout.SHOW_DIVIDER_MIDDLE)
+ .map("end", LinearLayout.SHOW_DIVIDER_END)
+ .map("none", LinearLayout.SHOW_DIVIDER_NONE);
+
public LinearLayoutInflater(ResourceParser resourceParser) {
super(resourceParser);
}
@@ -44,6 +50,9 @@ public class LinearLayoutInflater extends ViewGroupInfla
case "orientation":
view.setOrientation(ORIENTATIONS.get(value));
break;
+ case "showDividers":
+ view.setShowDividers(SHOW_DIVIDERS.split(value));
+ break;
case "weightSum":
view.setWeightSum(Float.valueOf(value));
break;
diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/TextViewInflater.java b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/TextViewInflater.java
index 0bd1709a..a5eb1e03 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/TextViewInflater.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/ui/inflater/inflaters/TextViewInflater.java
@@ -39,7 +39,7 @@ public class TextViewInflater extends BaseViewInflater {
.map("web", Linkify.WEB_URLS);
private static final ValueMapper ELLIPSIZE = new ValueMapper("ellipsize")
.map("end", TextUtils.TruncateAt.END)
- .map("marquee", TextUtils.TruncateAt.MIDDLE)
+ .map("marquee", TextUtils.TruncateAt.MARQUEE)
.map("none", null)
.map("start", TextUtils.TruncateAt.START)
.map("middle", TextUtils.TruncateAt.MIDDLE);
diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsListView.java b/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsListView.java
index 6c82f017..633a10e4 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsListView.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsListView.java
@@ -2,6 +2,7 @@ package com.stardust.autojs.core.ui.widget;
import android.content.Context;
import android.os.Handler;
+import android.support.v4.view.ViewPager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
diff --git a/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsTabLayout.java b/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsTabLayout.java
index 55571f0c..07551f03 100644
--- a/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsTabLayout.java
+++ b/autojs/src/main/java/com/stardust/autojs/core/ui/widget/JsTabLayout.java
@@ -4,7 +4,9 @@ import android.content.Context;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
+import android.support.v4.widget.DrawerLayout;
import android.util.AttributeSet;
+import android.view.Gravity;
import com.stardust.autojs.runtime.api.UI;
diff --git a/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java
index c2b6243a..fed1877b 100644
--- a/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java
+++ b/autojs/src/main/java/com/stardust/autojs/engine/LoopBasedJavaScriptEngine.java
@@ -5,6 +5,7 @@ import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.MessageQueue;
+import android.util.Log;
import com.stardust.autojs.core.looper.LooperHelper;
import com.stardust.autojs.script.JavaScriptSource;
@@ -44,6 +45,7 @@ public class LoopBasedJavaScriptEngine extends RhinoJavaScriptEngine {
if (callback != null)
callback.onResult(o);
} catch (Exception e) {
+ Log.d("DDDDD", "execute: " + e.getMessage());
if (callback == null) {
throw e;
} else {
diff --git a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java
index 0b620be2..9f491a38 100644
--- a/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java
+++ b/autojs/src/main/java/com/stardust/autojs/engine/RhinoJavaScriptEngine.java
@@ -205,6 +205,7 @@ public class RhinoJavaScriptEngine extends JavaScriptEngine {
@Override
protected void observeInstructionCount(Context cx, int instructionCount) {
if (Thread.currentThread().isInterrupted() && Looper.myLooper() != Looper.getMainLooper()) {
+ Log.d("DDDDD", "thread interrupt: " + Thread.currentThread());
throw new ScriptInterruptedException();
}
}
diff --git a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java
index cdfc3db3..82132b67 100644
--- a/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java
+++ b/autojs/src/main/java/com/stardust/autojs/execution/ScriptExecuteActivity.java
@@ -140,9 +140,11 @@ public class ScriptExecuteActivity extends AppCompatActivity {
protected void onDestroy() {
super.onDestroy();
Log.d(LOG_TAG, "onDestroy");
- mScriptEngine.put("activity", null);
- mScriptEngine.setTag("activity", null);
- mScriptEngine.destroy();
+ if(mScriptEngine != null){
+ mScriptEngine.put("activity", null);
+ mScriptEngine.setTag("activity", null);
+ mScriptEngine.destroy();
+ }
mScriptExecution = null;
}
diff --git a/autojs/src/main/java/com/stardust/autojs/rhino/AndroidClassLoader.java b/autojs/src/main/java/com/stardust/autojs/rhino/AndroidClassLoader.java
index 4538c348..0548a4bb 100644
--- a/autojs/src/main/java/com/stardust/autojs/rhino/AndroidClassLoader.java
+++ b/autojs/src/main/java/com/stardust/autojs/rhino/AndroidClassLoader.java
@@ -3,7 +3,8 @@ package com.stardust.autojs.rhino;
import android.util.Log;
import com.android.dx.command.dexer.Main;
-import com.android.dx.dex.file.DexFile;
+import com.stardust.pio.PFiles;
+import com.stardust.util.MD5;
import net.lingala.zip4j.core.ZipFile;
import net.lingala.zip4j.exception.ZipException;
@@ -16,6 +17,7 @@ import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
@@ -42,7 +44,11 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
public AndroidClassLoader(ClassLoader parent, File dir) {
this.parent = parent;
mCacheDir = dir;
- dir.mkdirs();
+ if (dir.exists()) {
+ PFiles.deleteFilesOfDir(dir);
+ } else {
+ dir.mkdirs();
+ }
}
/**
@@ -53,13 +59,13 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
Log.d(LOG_TAG, "defineClass: name = " + name + " data.length = " + data.length);
File classFile = null;
try {
- classFile = generateTempClassFile(name, false);
+ classFile = generateTempFile(name, false);
final ZipFile zipFile = new ZipFile(classFile);
final ZipParameters parameters = new ZipParameters();
parameters.setFileNameInZip(name.replace('.', '/') + ".class");
parameters.setSourceExternalStream(true);
zipFile.addStream(new ByteArrayInputStream(data), parameters);
- return dexJar(classFile).loadClass(name);
+ return dexJar(classFile, null).loadClass(name);
} catch (IOException | ZipException | ClassNotFoundException e) {
throw new FatalLoadingException(e);
} finally {
@@ -69,7 +75,7 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
}
}
- private File generateTempClassFile(String name, boolean create) throws IOException {
+ private File generateTempFile(String name, boolean create) throws IOException {
File file = new File(mCacheDir, name.hashCode() + System.currentTimeMillis() + ".jar");
if (create) {
if (!file.exists()) {
@@ -83,8 +89,16 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
public void loadJar(File jar) throws IOException {
Log.d(LOG_TAG, "loadJar: jar = " + jar);
+ if (!jar.exists() || !jar.canRead()) {
+ throw new FileNotFoundException("File does not exist or readable: " + jar.getPath());
+ }
+ File dexFile = new File(mCacheDir, generateDexFileName(jar));
+ if (dexFile.exists()) {
+ loadDex(dexFile);
+ return;
+ }
try {
- final File classFile = generateTempClassFile(jar.getPath(), false);
+ final File classFile = generateTempFile(jar.getPath(), false);
final ZipFile zipFile = new ZipFile(classFile);
final ZipFile jarFile = new ZipFile(jar);
//noinspection unchecked
@@ -96,12 +110,22 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
zipFile.addStream(jarFile.getInputStream(header), parameters);
}
}
- dexJar(classFile);
+ dexJar(classFile, dexFile);
+ classFile.delete();
} catch (ZipException e) {
throw new IOException(e);
}
}
+ private String generateDexFileName(File jar) {
+ String message = jar.getPath() + "_" + jar.lastModified();
+ try {
+ return MD5.md5(message);
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
public DexClassLoader loadDex(File file) throws FileNotFoundException {
Log.d(LOG_TAG, "loadDex: file = " + file);
if (!file.exists()) {
@@ -112,15 +136,20 @@ public class AndroidClassLoader extends ClassLoader implements GeneratedClassLoa
return loader;
}
- private DexClassLoader dexJar(File classFile) throws IOException {
+ private DexClassLoader dexJar(File classFile, File dexFile) throws IOException {
final Main.Arguments arguments = new Main.Arguments();
arguments.fileNames = new String[]{classFile.getPath()};
- File dexFile = generateTempClassFile("dex-" + classFile.getPath(), true);
+ boolean isTmpDex = dexFile == null;
+ if (isTmpDex) {
+ dexFile = generateTempFile("dex-" + classFile.getPath(), true);
+ }
arguments.outName = dexFile.getPath();
arguments.jarOutput = true;
Main.run(arguments);
DexClassLoader loader = loadDex(dexFile);
- dexFile.delete();
+ if (isTmpDex) {
+ dexFile.delete();
+ }
return loader;
}
diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java
index d7e0b18e..b26a2279 100644
--- a/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java
+++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/AppUtils.java
@@ -7,9 +7,7 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.support.annotation.Nullable;
-import android.text.TextUtils;
import android.util.Log;
-import android.webkit.MimeTypeMap;
import com.stardust.autojs.annotation.ScriptInterface;
import com.stardust.util.IntentUtil;
@@ -18,8 +16,6 @@ import com.stardust.util.MimeTypes;
import java.lang.ref.WeakReference;
import java.util.List;
-import static com.stardust.pio.PFiles.getExtension;
-
/**
* Created by Stardust on 2017/4/2.
*/
@@ -28,9 +24,16 @@ public class AppUtils {
private Context mContext;
private volatile WeakReference mCurrentActivity = new WeakReference<>(null);
+ private final String mFileProviderAuthority;
public AppUtils(Context context) {
mContext = context;
+ mFileProviderAuthority = null;
+ }
+
+ public AppUtils(Context context, String fileProviderAuthority) {
+ mContext = context;
+ mFileProviderAuthority = fileProviderAuthority;
}
@ScriptInterface
@@ -99,22 +102,14 @@ public class AppUtils {
public void viewFile(String path) {
if (path == null)
throw new NullPointerException("path == null");
- path = "file://" + path;
- String mimeType = MimeTypes.fromFileOr(path, "*/*");
- mContext.startActivity(new Intent(Intent.ACTION_VIEW)
- .setDataAndType(Uri.parse(path), mimeType)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ IntentUtil.viewFile(mContext, path, mFileProviderAuthority);
}
@ScriptInterface
public void editFile(String path) {
if (path == null)
throw new NullPointerException("path == null");
- path = "file://" + path;
- String mimeType = MimeTypes.fromFileOr(path, "*/*");
- mContext.startActivity(new Intent(Intent.ACTION_EDIT)
- .setDataAndType(Uri.parse(path), mimeType)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ IntentUtil.editFile(mContext, path, mFileProviderAuthority);
}
@ScriptInterface
diff --git a/automator/build.gradle b/automator/build.gradle
index 3ca16296..91363f60 100644
--- a/automator/build.gradle
+++ b/automator/build.gradle
@@ -1,12 +1,12 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion 25
- buildToolsVersion '26.0.2'
+ compileSdkVersion versions.compile
+ buildToolsVersion versions.buildTool
defaultConfig {
- minSdkVersion 17
- targetSdkVersion 25
+ minSdkVersion versions.mini
+ targetSdkVersion versions.target
versionCode 1
versionName "1.0"
@@ -33,10 +33,10 @@ repositories {
}
dependencies {
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
- testCompile 'junit:junit:4.12'
- compile 'com.android.support:appcompat-v7:25.4.0'
- compile project(path: ':common')
+ testImplementation 'junit:junit:4.12'
+ api 'com.android.support:appcompat-v7:28.0.0'
+ api project(path: ':common')
}
diff --git a/build.gradle b/build.gradle
index 87c3cfd6..254d63d6 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,12 +1,14 @@
+import groovy.json.JsonSlurper
+
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
- jcenter()
google()
+ jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.0.1'
+ classpath 'com.android.tools.build:gradle:3.1.4'
}
}
@@ -18,9 +20,14 @@ allprojects {
url "https://jitpack.io"
}
google()
+ maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
+
+ext {
+ versions = new JsonSlurper().parse(file('./project-versions.json'))
+}
diff --git a/common/build.gradle b/common/build.gradle
index 00d806fb..445f3e62 100644
--- a/common/build.gradle
+++ b/common/build.gradle
@@ -1,12 +1,12 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion 25
- buildToolsVersion '26.0.2'
+ compileSdkVersion versions.compile
+ buildToolsVersion versions.buildTool
defaultConfig {
- minSdkVersion 17
- targetSdkVersion 25
+ minSdkVersion versions.mini
+ targetSdkVersion versions.target
versionCode 1
versionName "1.0"
@@ -23,10 +23,10 @@ android {
}
dependencies {
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
- testCompile 'junit:junit:4.12'
- compile 'com.android.support:support-annotations:25.4.0'
- compile 'com.github.hyb1996:settingscompat:1.1.5'
+ testImplementation 'junit:junit:4.12'
+ api 'com.android.support:support-annotations:28.0.0'
+ api 'com.github.hyb1996:settingscompat:1.1.5'
}
diff --git a/common/release/output.json b/common/release/output.json
index 25bb428d..93b92607 100644
--- a/common/release/output.json
+++ b/common/release/output.json
@@ -1 +1 @@
-[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":421},"path":"commonRelease-4.0.3 Alpha2.apk","properties":{"packageId":"org.autojs.autojs","split":"","minSdkVersion":"17"}}]
\ No newline at end of file
+[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":424,"versionName":"4.0.3 Alpha5","enabled":true,"outputFile":"commonRelease-4.0.3 Alpha5.apk","fullName":"commonRelease","baseName":"common-release"},"path":"commonRelease-4.0.3 Alpha5.apk","properties":{}}]
\ No newline at end of file
diff --git a/common/src/main/java/com/stardust/app/DialogUtils.java b/common/src/main/java/com/stardust/app/DialogUtils.java
index 4cadcde9..8dd77860 100644
--- a/common/src/main/java/com/stardust/app/DialogUtils.java
+++ b/common/src/main/java/com/stardust/app/DialogUtils.java
@@ -4,6 +4,7 @@ import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.ContextWrapper;
+import android.os.Build;
import android.view.Window;
import android.view.WindowManager;
@@ -15,10 +16,17 @@ public class DialogUtils {
public static T showDialog(T dialog) {
Context context = dialog.getContext();
+
if (!isActivityContext(context)) {
Window window = dialog.getWindow();
+ int type;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+ } else {
+ type = WindowManager.LayoutParams.TYPE_PHONE;
+ }
if (window != null)
- window.setType(WindowManager.LayoutParams.TYPE_PHONE);
+ window.setType(type);
}
dialog.show();
return dialog;
diff --git a/common/src/main/java/com/stardust/pio/PFiles.java b/common/src/main/java/com/stardust/pio/PFiles.java
index 5f2dfc2b..b304b98a 100644
--- a/common/src/main/java/com/stardust/pio/PFiles.java
+++ b/common/src/main/java/com/stardust/pio/PFiles.java
@@ -395,6 +395,19 @@ public class PFiles {
return file.delete();
}
+ public static boolean deleteFilesOfDir(File dir) {
+ if (!dir.isDirectory())
+ throw new IllegalArgumentException("not a directory: " + dir);
+ File[] children = dir.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ if (!deleteRecursively(child))
+ return false;
+ }
+ }
+ return true;
+ }
+
public static boolean remove(String path) {
return new File(path).delete();
}
diff --git a/common/src/main/java/com/stardust/util/IntentUtil.java b/common/src/main/java/com/stardust/util/IntentUtil.java
index 174b9689..a1d0f138 100644
--- a/common/src/main/java/com/stardust/util/IntentUtil.java
+++ b/common/src/main/java/com/stardust/util/IntentUtil.java
@@ -5,6 +5,7 @@ import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.Nullable;
+import android.support.v4.content.FileProvider;
import java.io.File;
@@ -84,20 +85,47 @@ public class IntentUtil {
return goToAppDetailSettings(context, context.getPackageName());
}
- // FIXME: 2018/7/11 Permission denial
- public static void installApk(Context context, String path) {
+ public static void installApk(Context context, String path, String fileProviderAuthority) {
+ Uri uri = getUriOfFile(context, path, fileProviderAuthority);
Intent intent = new Intent(Intent.ACTION_VIEW);
-
- intent.setDataAndType(Uri.fromFile(new File(path)), "application/vnd.android.package-archive");
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setDataAndType(uri, "application/vnd.android.package-archive");
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
context.startActivity(intent);
}
- public static void viewFile(Context context, String path) {
- path = "file://" + path;
+ public static void viewFile(Context context, String path, String fileProviderAuthority) {
String mimeType = MimeTypes.fromFileOr(path, "*/*");
+ viewFile(context, path, mimeType, fileProviderAuthority);
+ }
+
+ public static Uri getUriOfFile(Context context, String path, String fileProviderAuthority) {
+ Uri uri;
+ if (fileProviderAuthority == null) {
+ uri = Uri.parse("file://" + path);
+ } else {
+ uri = FileProvider.getUriForFile(context, fileProviderAuthority, new File(path));
+ }
+ return uri;
+ }
+
+ public static void viewFile(Context context, String path, String mimeType, String fileProviderAuthority) {
+ Uri uri = getUriOfFile(context, path, fileProviderAuthority);
context.startActivity(new Intent(Intent.ACTION_VIEW)
- .setDataAndType(Uri.parse(path), mimeType)
- .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ .setDataAndType(uri, mimeType)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION));
+ }
+
+ public static void editFile(Context context, String path, String fileProviderAuthority) {
+ String mimeType = MimeTypes.fromFileOr(path, "*/*");
+ Uri uri = getUriOfFile(context, path, fileProviderAuthority);
+ context.startActivity(new Intent(Intent.ACTION_EDIT)
+ .setDataAndType(uri, mimeType)
+ .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
+ .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION));
}
}
diff --git a/common/src/main/java/com/stardust/util/MD5.java b/common/src/main/java/com/stardust/util/MD5.java
new file mode 100644
index 00000000..824a37b7
--- /dev/null
+++ b/common/src/main/java/com/stardust/util/MD5.java
@@ -0,0 +1,26 @@
+package com.stardust.util;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class MD5 {
+
+ public static byte[] md5Bytes(String message) throws NoSuchAlgorithmException {
+ MessageDigest md5 = MessageDigest.getInstance("MD5");
+ md5.update(message.getBytes());
+ return md5.digest();
+ }
+
+ public static String md5(String message) throws NoSuchAlgorithmException {
+ byte[] bytes = md5Bytes(message);
+ StringBuilder hexString = new StringBuilder(32);
+ for (byte b : bytes) {
+ String hex = Integer.toHexString(0xFF & b);
+ if (hex.length() == 1) {
+ hexString.append('0');
+ }
+ hexString.append(hex);
+ }
+ return hexString.toString();
+ }
+}
diff --git a/common/src/main/java/com/stardust/util/ObjectHelper.java b/common/src/main/java/com/stardust/util/ObjectHelper.java
new file mode 100644
index 00000000..090e6609
--- /dev/null
+++ b/common/src/main/java/com/stardust/util/ObjectHelper.java
@@ -0,0 +1,16 @@
+package com.stardust.util;
+
+public class ObjectHelper {
+
+ public static void requireNonNull(Object obj, String name){
+ if(obj == null){
+ throw new NullPointerException(name + " should not be null");
+ }
+ }
+
+ public static void requireNonNull(Object obj){
+ if(obj == null){
+ throw new NullPointerException();
+ }
+ }
+}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 6fc53efd..999ec928 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Mon Nov 27 21:40:02 CST 2017
+#Fri Oct 05 23:57:16 CST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
diff --git a/inrt/build.gradle b/inrt/build.gradle
index 7cc9d151..5b3f1ba3 100644
--- a/inrt/build.gradle
+++ b/inrt/build.gradle
@@ -1,15 +1,15 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 25
- buildToolsVersion '26.0.2'
+ compileSdkVersion versions.compile
+ buildToolsVersion versions.buildTool
defaultConfig {
applicationId "com.stardust.auojs.inrt"
- minSdkVersion 17
- targetSdkVersion 23
- versionCode 210
- versionName "4.0.2 Alpha5"
+ minSdkVersion versions.mini
+ targetSdkVersion versions.target
+ versionCode versions.appVersionCode - 200
+ versionName versions.appVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
ndk {
abiFilters 'armeabi-v7a'
@@ -36,6 +36,39 @@ android {
}
}
+
+task buildApkPlugin {
+ doLast {
+ def pluginProjectDirPath = '..\\..\\AutoJsApkBuilderPlugin'
+ def pluginProjectDir = file(pluginProjectDirPath)
+ if(!pluginProjectDir.exists() || !pluginProjectDir.isDirectory()){
+ println 'pluginProjectDir not exists'
+ return
+ }
+ copy {
+ from file('build\\outputs\\apk\\release\\')
+ into new File(pluginProjectDir, 'app\\src\\main\\assets')
+ include "inrt-release-unsigned.apk"
+ rename "inrt-release-unsigned.apk", 'template.apk'
+ }
+ exec {
+ workingDir pluginProjectDir
+ commandLine 'gradlew.bat', 'assembleRelease'
+ }
+ copy {
+ from new File(pluginProjectDir, 'app\\build\\outputs\\apk\\release')
+ into file('..\\common\\release')
+ include '*-release.apk'
+ }
+ }
+}
+
+tasks.whenTaskAdded { task ->
+ if (task.name == 'assembleRelease') {
+ task.finalizedBy 'buildApkPlugin'
+ }
+}
+
repositories {
flatDir {
dirs 'libs'
@@ -44,17 +77,16 @@ repositories {
}
dependencies {
- compile fileTree(dir: 'libs', include: ['*.jar'])
- androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+ androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
- compile 'com.android.support:appcompat-v7:25.4.0'
//Glide
- compile('com.github.bumptech.glide:glide:4.2.0', {
+ implementation('com.github.bumptech.glide:glide:4.2.0', {
exclude group: 'com.android.support'
})
- testCompile 'junit:junit:4.12'
- compile project(':automator')
- compile project(':common')
- compile project(':autojs')
+ testImplementation 'junit:junit:4.12'
+ implementation project(':automator')
+ implementation project(':common')
+ implementation project(':autojs')
}
diff --git a/inrt/src/main/AndroidManifest.xml b/inrt/src/main/AndroidManifest.xml
index 1f081ede..76116e60 100644
--- a/inrt/src/main/AndroidManifest.xml
+++ b/inrt/src/main/AndroidManifest.xml
@@ -26,7 +26,8 @@
android:label="inrt"
android:supportsRtl="true"
android:theme="@style/AppTheme"
- tools:replace="android:label, android:allowBackup">
+ tools:replace="android:label, android:allowBackup"
+ tools:ignore="GoogleAppIndexingWarning">
diff --git a/inrt/src/main/java/com/stardust/auojs/inrt/LogActivity.java b/inrt/src/main/java/com/stardust/auojs/inrt/LogActivity.java
index 423d03f6..b303015f 100644
--- a/inrt/src/main/java/com/stardust/auojs/inrt/LogActivity.java
+++ b/inrt/src/main/java/com/stardust/auojs/inrt/LogActivity.java
@@ -43,9 +43,9 @@ public class LogActivity extends AppCompatActivity {
private void setupView() {
setContentView(R.layout.activity_main);
- Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
+ Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
- ConsoleView consoleView = (ConsoleView) findViewById(R.id.console);
+ ConsoleView consoleView = findViewById(R.id.console);
consoleView.setConsole((StardustConsole) AutoJs.getInstance().getGlobalConsole());
consoleView.findViewById(R.id.input_container).setVisibility(View.GONE);
}
diff --git a/inrt/src/main/java/com/stardust/auojs/inrt/SplashActivity.java b/inrt/src/main/java/com/stardust/auojs/inrt/SplashActivity.java
index 4f9fcf64..63080711 100644
--- a/inrt/src/main/java/com/stardust/auojs/inrt/SplashActivity.java
+++ b/inrt/src/main/java/com/stardust/auojs/inrt/SplashActivity.java
@@ -6,6 +6,7 @@ import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
@@ -14,6 +15,7 @@ import android.widget.TextView;
import com.stardust.auojs.inrt.launch.AssetsProjectLauncher;
import com.stardust.auojs.inrt.launch.GlobalProjectLauncher;
+import com.stardust.autojs.core.image.OpenCVHelper;
import java.util.ArrayList;
import java.util.Arrays;
@@ -29,18 +31,24 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public class SplashActivity extends AppCompatActivity {
private static final int PERMISSION_REQUEST_CODE = 11186;
+ private static final long INIT_TIMEOUT = 2500;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- if (!Pref.isFirstUsing()) {
- main();
- return;
- }
setContentView(R.layout.activity_splash);
- TextView slug = (TextView) findViewById(R.id.slug);
+ TextView slug = findViewById(R.id.slug);
slug.setTypeface(Typeface.createFromAsset(getAssets(), "roboto_medium.ttf"));
- new Handler().postDelayed(this::main, 2500);
+ final long millis = SystemClock.uptimeMillis();
+ OpenCVHelper.initIfNeeded(this, () -> {
+ long delay = INIT_TIMEOUT - (SystemClock.uptimeMillis() - millis);
+ if (!Pref.isFirstUsing() || delay <= 0) {
+ main();
+ return;
+ }
+ new Handler().postDelayed(SplashActivity.this::main, delay);
+ });
+
}
private void main() {
@@ -67,9 +75,7 @@ public class SplashActivity extends AppCompatActivity {
runScript();
}
} else {
- int[] grantResults = new int[permissions.length];
- Arrays.fill(grantResults, PERMISSION_GRANTED);
- onRequestPermissionsResult(PERMISSION_REQUEST_CODE, permissions, grantResults);
+ runScript();
}
}
diff --git a/project-versions.json b/project-versions.json
new file mode 100644
index 00000000..22a2a0b9
--- /dev/null
+++ b/project-versions.json
@@ -0,0 +1,8 @@
+{
+ "appVersionCode": 424,
+ "appVersionName": "4.0.3 Alpha5",
+ "target": 28,
+ "mini": 17,
+ "compile": 28,
+ "buildTool": "28.0.3"
+}
\ No newline at end of file