Merge branch 'dev' of https://github.com/hyb1996/NoRootScriptDroid into dev
This commit is contained in:
BIN
.idea/caches/build_file_checksums.ser
generated
BIN
.idea/caches/build_file_checksums.ser
generated
Binary file not shown.
103
app/build.gradle
103
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')
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
<!-- Ad SDK Permissions -->
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
|
||||
|
||||
<application
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:name=".App"
|
||||
@@ -34,6 +35,10 @@
|
||||
android:theme="@style/AppTheme"
|
||||
tools:replace="android:label, android:icon, android:allowBackup">
|
||||
|
||||
<meta-data
|
||||
android:name="android.max_aspect"
|
||||
android:value="2.1" />
|
||||
|
||||
<activity
|
||||
android:name=".ui.splash.SplashActivity"
|
||||
android:hardwareAccelerated="true"
|
||||
@@ -64,7 +69,7 @@
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:name=".external.fileprovider.AppFileProvider"
|
||||
android:authorities="org.autojs.autojs.fileprovider"
|
||||
android:exported="false"
|
||||
android:grantUriPermissions="true">
|
||||
@@ -139,11 +144,6 @@
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
<action android:name="android.intent.action.TIME_SET"/>
|
||||
<action android:name="android.intent.action.TIMEZONE_CHANGED"/>
|
||||
<action android:name="android.intent.action.PACKAGE_ADDED"/>
|
||||
<action android:name="android.intent.action.PACKAGE_CHANGED"/>
|
||||
<action android:name="android.intent.action.PACKAGE_DATA_CLEARED"/>
|
||||
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
|
||||
<action android:name="android.intent.action.PACKAGE_RESTARTED"/>
|
||||
<action android:name="android.intent.action.UID_REMOVED"/>
|
||||
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
|
||||
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -48,14 +48,18 @@ public class AutoJsApkBuilder extends ApkBuilder {
|
||||
Callable<Bitmap> 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
16
app/src/main/java/org/autojs/autojs/external/fileprovider/AppFileProvider.java
vendored
Normal file
16
app/src/main/java/org/autojs/autojs/external/fileprovider/AppFileProvider.java
vendored
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> 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<String> mActions = new LinkedHashSet<>();
|
||||
private final List<BroadcastReceiver> mReceivers = new ArrayList<>();
|
||||
private final List<ReceiverRegistry> 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<String> actions) {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
public synchronized void register(List<String> actions) {
|
||||
LinkedHashSet<String> 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<ReceiverRegistry> 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<String> actions) {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
for (String action : actions) {
|
||||
filter.addAction(action);
|
||||
}
|
||||
return filter;
|
||||
}
|
||||
|
||||
private class ReceiverRegistry {
|
||||
BroadcastReceiver receiver;
|
||||
LinkedHashSet<String> actions;
|
||||
|
||||
ReceiverRegistry(LinkedHashSet<String> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,4 +37,12 @@ public class StaticBroadcastReceiver extends BaseBroadcastReceiver {
|
||||
"android.net.conn.CONNECTIVITY_CHANGE"
|
||||
));
|
||||
|
||||
static final List<String> 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"
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
@@ -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<String> 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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@@ -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<TimedTask> getAllTasks() {
|
||||
|
||||
@@ -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());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> 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));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 -> {
|
||||
|
||||
@@ -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<Bitmap> 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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -71,6 +71,7 @@
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
|
||||
<fragment
|
||||
android:id="@+id/fragment_drawer"
|
||||
android:name="org.autojs.autojs.ui.main.drawer.DrawerFragment_"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
@@ -421,4 +421,5 @@
|
||||
<string name="text_run_on_headset_plug">耳机插拔时</string>
|
||||
<string name="text_run_on_time_tick">每分钟一次</string>
|
||||
<string name="text_run_on_config_change">某些设置(屏幕方向,地区等)更改时</string>
|
||||
<string name="error_pattern_syntax">正则表达式错误</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<external-path name="external_files" path="."/>
|
||||
<files-path name="sample" path="sample"/>
|
||||
<root-path name="root_files" path="." />
|
||||
</paths>
|
||||
@@ -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')
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
|
||||
|
||||
<application
|
||||
|
||||
@@ -109,6 +109,10 @@ module.exports = function(runtime, global){
|
||||
"fast": 1
|
||||
}
|
||||
|
||||
const flagsMap = {
|
||||
"findOnUiThread": 1
|
||||
};
|
||||
|
||||
var auto = function(mode){
|
||||
if(mode){
|
||||
global.auto.setMode(mode);
|
||||
@@ -120,14 +124,33 @@ module.exports = function(runtime, global){
|
||||
runtime.accessibilityBridge.waitForServiceEnabled();
|
||||
}
|
||||
|
||||
auto.setMode = function(mode){
|
||||
auto.setMode = function(modeStr){
|
||||
if(typeof(mode) !== "string"){
|
||||
throw new TypeError("mode should be a string");
|
||||
}
|
||||
mode = modes[mode.toLowerCase()] || 0;
|
||||
let mode = modes[modeStr];
|
||||
if(mode == undefined){
|
||||
throw new Error("unknown mode for auto.setMode(): " + modeStr)
|
||||
}
|
||||
runtime.accessibilityBridge.setMode(mode);
|
||||
}
|
||||
|
||||
auto.setFlags = function(flags){
|
||||
if(typeof(flags) !== "string"){
|
||||
throw new TypeError("flags should be a string");
|
||||
}
|
||||
let flagsInt = 0;
|
||||
let flagStrings = flags.split("|");
|
||||
for(let i = 0; i < flagStrings.length; i++){
|
||||
let flag = flagsMap[flagStrings[i]];
|
||||
if(flag == undefined){
|
||||
throw new Error("unknown flag for auto.setFlags(): " + flagStrings[i]);
|
||||
}
|
||||
flagsInt |= flag;
|
||||
}
|
||||
runtime.accessibilityBridge.setFlags(flagsInt);
|
||||
}
|
||||
|
||||
auto.getService = function(){
|
||||
return runtime.accessibilityBridge.getService();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.stardust.app.SimpleActivityLifecycleCallbacks;
|
||||
import com.stardust.autojs.core.accessibility.AccessibilityBridge;
|
||||
import com.stardust.autojs.core.console.GlobalStardustConsole;
|
||||
import com.stardust.autojs.core.console.StardustConsole;
|
||||
import com.stardust.autojs.core.image.OpenCVHelper;
|
||||
import com.stardust.autojs.core.image.capture.ScreenCaptureRequestActivity;
|
||||
import com.stardust.autojs.core.image.capture.ScreenCaptureRequester;
|
||||
import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder;
|
||||
@@ -76,8 +77,6 @@ public abstract class AutoJs {
|
||||
protected void init() {
|
||||
addAccessibilityServiceDelegates();
|
||||
registerActivityLifecycleCallbacks();
|
||||
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_13, mContext, new BaseLoaderCallback(mContext) {
|
||||
});
|
||||
}
|
||||
|
||||
public abstract void ensureAccessibilityServiceEnabled();
|
||||
@@ -111,7 +110,7 @@ public abstract class AutoJs {
|
||||
return new ScriptRuntime.Builder()
|
||||
.setConsole(new StardustConsole(mUiHandler, mGlobalConsole))
|
||||
.setScreenCaptureRequester(mScreenCaptureRequester)
|
||||
.setAccessibilityBridge(new AccessibilityBridgeImpl())
|
||||
.setAccessibilityBridge(new AccessibilityBridgeImpl(mUiHandler))
|
||||
.setUiHandler(mUiHandler)
|
||||
.setAppUtils(mAppUtils)
|
||||
.setEngineService(mScriptEngineService)
|
||||
@@ -183,8 +182,8 @@ public abstract class AutoJs {
|
||||
|
||||
private class AccessibilityBridgeImpl extends AccessibilityBridge {
|
||||
|
||||
public AccessibilityBridgeImpl() {
|
||||
super(createAccessibilityConfig());
|
||||
public AccessibilityBridgeImpl(UiHandler uiHandler) {
|
||||
super(createAccessibilityConfig(), uiHandler);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,11 +7,10 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.view.accessibility.AccessibilityWindowInfo;
|
||||
|
||||
import com.stardust.autojs.runtime.accessibility.AccessibilityConfig;
|
||||
import com.stardust.automator.UiObject;
|
||||
import com.stardust.util.UiHandler;
|
||||
import com.stardust.view.accessibility.AccessibilityInfoProvider;
|
||||
import com.stardust.view.accessibility.AccessibilityNotificationObserver;
|
||||
import com.stardust.view.accessibility.AccessibilityService;
|
||||
import com.stardust.view.accessibility.NotificationListener;
|
||||
|
||||
|
||||
/**
|
||||
@@ -27,12 +26,17 @@ public abstract class AccessibilityBridge {
|
||||
public static final int MODE_NORMAL = 0;
|
||||
public static final int MODE_FAST = 1;
|
||||
|
||||
private int mMode = MODE_NORMAL;
|
||||
private AccessibilityConfig mConfig;
|
||||
private WindowFilter mWindowFilter;
|
||||
public static final int FLAG_FIND_ON_UI_THREAD = 1;
|
||||
|
||||
public AccessibilityBridge(AccessibilityConfig config) {
|
||||
private int mMode = MODE_NORMAL;
|
||||
private int mFlags = 0;
|
||||
private final AccessibilityConfig mConfig;
|
||||
private WindowFilter mWindowFilter;
|
||||
private final UiHandler mUiHandler;
|
||||
|
||||
public AccessibilityBridge(AccessibilityConfig config, UiHandler uiHandler) {
|
||||
mConfig = config;
|
||||
mUiHandler = uiHandler;
|
||||
mConfig.seal();
|
||||
}
|
||||
|
||||
@@ -40,6 +44,10 @@ public abstract class AccessibilityBridge {
|
||||
|
||||
public abstract void waitForServiceEnabled();
|
||||
|
||||
public void post(Runnable r) {
|
||||
mUiHandler.post(r);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public abstract AccessibilityService getService();
|
||||
|
||||
@@ -62,7 +70,7 @@ public abstract class AccessibilityBridge {
|
||||
return activeWindow.getRoot();
|
||||
}
|
||||
}
|
||||
if (mMode == MODE_FAST) {
|
||||
if ((mMode & MODE_FAST) != 0) {
|
||||
return service.fastRootInActiveWindow();
|
||||
}
|
||||
return service.getRootInActiveWindow();
|
||||
@@ -75,11 +83,18 @@ public abstract class AccessibilityBridge {
|
||||
@NonNull
|
||||
public abstract AccessibilityInfoProvider getInfoProvider();
|
||||
|
||||
|
||||
public void setMode(int mode) {
|
||||
mMode = mode;
|
||||
}
|
||||
|
||||
public int getFlags() {
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
public void setFlags(int flags) {
|
||||
mFlags = flags;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public abstract AccessibilityNotificationObserver getNotificationObserver();
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.stardust.autojs.core.accessibility;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
@@ -13,6 +14,7 @@ import com.stardust.automator.UiGlobalSelector;
|
||||
import com.stardust.automator.UiObject;
|
||||
import com.stardust.automator.UiObjectCollection;
|
||||
import com.stardust.automator.filter.DfsFilter;
|
||||
import com.stardust.concurrent.VolatileBox;
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
|
||||
import static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS;
|
||||
@@ -72,6 +74,18 @@ public class UiSelector extends UiGlobalSelector {
|
||||
@ScriptInterface
|
||||
public UiObjectCollection find() {
|
||||
ensureAccessibilityServiceEnabled();
|
||||
if((mAccessibilityBridge.getFlags() & AccessibilityBridge.FLAG_FIND_ON_UI_THREAD)!=0
|
||||
&& Looper.myLooper() != Looper.getMainLooper()){
|
||||
VolatileBox<UiObjectCollection> 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));
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,6 +19,12 @@ public class LinearLayoutInflater<V extends LinearLayout> extends ViewGroupInfla
|
||||
.map("vertical", LinearLayout.VERTICAL)
|
||||
.map("horizontal", LinearLayout.HORIZONTAL);
|
||||
|
||||
static final ValueMapper<Integer> SHOW_DIVIDERS = new ValueMapper<Integer>("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<V extends LinearLayout> 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;
|
||||
|
||||
@@ -39,7 +39,7 @@ public class TextViewInflater<V extends TextView> extends BaseViewInflater<V> {
|
||||
.map("web", Linkify.WEB_URLS);
|
||||
private static final ValueMapper<TextUtils.TruncateAt> ELLIPSIZE = new ValueMapper<TextUtils.TruncateAt>("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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Activity> 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
|
||||
|
||||
@@ -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')
|
||||
}
|
||||
|
||||
11
build.gradle
11
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'))
|
||||
}
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
|
||||
@@ -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"}}]
|
||||
[{"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":{}}]
|
||||
@@ -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 extends Dialog> 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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
26
common/src/main/java/com/stardust/util/MD5.java
Normal file
26
common/src/main/java/com/stardust/util/MD5.java
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
16
common/src/main/java/com/stardust/util/ObjectHelper.java
Normal file
16
common/src/main/java/com/stardust/util/ObjectHelper.java
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -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
|
||||
|
||||
@@ -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')
|
||||
}
|
||||
|
||||
@@ -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">
|
||||
<activity android:name=".LogActivity">
|
||||
|
||||
</activity>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
8
project-versions.json
Normal file
8
project-versions.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"appVersionCode": 424,
|
||||
"appVersionName": "4.0.3 Alpha5",
|
||||
"target": 28,
|
||||
"mini": 17,
|
||||
"compile": 28,
|
||||
"buildTool": "28.0.3"
|
||||
}
|
||||
Reference in New Issue
Block a user