This commit is contained in:
hyb1996
2018-10-11 10:11:38 +08:00
69 changed files with 929 additions and 304 deletions

View File

@@ -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"/>

View File

@@ -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;

View File

@@ -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;
}

View 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);
}
}

View 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();
}

View File

@@ -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;
}
}
}

View File

@@ -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"
));
}

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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 {

View File

@@ -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() {

View File

@@ -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());
}

View File

@@ -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()) {

View File

@@ -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);
}

View File

@@ -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));
}
}

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;
}
}
}

View File

@@ -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()) {

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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);
}
});
}

View File

@@ -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);
}

View File

@@ -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));
}
}

View File

@@ -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 -> {

View File

@@ -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;

View File

@@ -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);

View File

@@ -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();

View File

@@ -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"

View File

@@ -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>

View File

@@ -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>