feat(app): supports changing default script dir path

This commit is contained in:
hyb1996 2018-06-03 18:05:17 +08:00
parent 7036fa994e
commit 023b8a79d9
22 changed files with 281 additions and 34 deletions

View File

@ -8,8 +8,8 @@ android {
applicationId "org.autojs.autojs"
minSdkVersion 17
targetSdkVersion 23
versionCode 401
versionName "4.0.0 Alpha1"
versionCode 403
versionName "4.0.0 Beta"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
ndk {

View File

@ -1 +1 @@
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":56},"path":"inrt-release.apk","properties":{"packageId":"com.stardust.auojs.inrt","split":"","minSdkVersion":"17"}}]
[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":201},"path":"inrt-release.apk","properties":{"packageId":"com.stardust.auojs.inrt","split":"","minSdkVersion":"17"}}]

View File

@ -1,5 +1,5 @@
auto();
events.observeNotification();
events.observeToast();
events.onToast(function(toast){
var pkg = toast.getPackageName();
log("Toast内容: " + toast.getText() +

View File

@ -6,6 +6,7 @@ import android.preference.PreferenceManager;
import com.stardust.app.GlobalAppContext;
import com.stardust.autojs.runtime.accessibility.AccessibilityConfig;
import org.autojs.autojs.autojs.key.GlobalKeyObserver;
import java.util.concurrent.TimeUnit;
@ -168,7 +169,12 @@ public class Pref {
def().edit().putInt(KEY_EDITOR_TEXT_SIZE, value).apply();
}
public static int getEditorTextSize(int defVlaue) {
return def().getInt(KEY_EDITOR_TEXT_SIZE, defVlaue);
public static int getEditorTextSize(int defValue) {
return def().getInt(KEY_EDITOR_TEXT_SIZE, defValue);
}
public static String getScriptDirPath() {
return def().getString(getString(R.string.key_script_dir_path),
getString(R.string.default_value_script_dir_path));
}
}

View File

@ -51,7 +51,7 @@ public class ScriptIntents {
}
config.executePath(new File(path).getParent());
} else {
config.executePath(StorageFileProvider.DEFAULT_DIRECTORY_PATH);
config.executePath(StorageFileProvider.getDefaultDirectoryPath());
}
if (source == null) {
return false;

View File

@ -43,7 +43,7 @@ public class TaskPrefEditActivity extends AbstractAppCompatPluginActivity {
private void initScriptListRecyclerView() {
mStorageFileProvider = StorageFileProvider.getExternalStorageProvider();
ScriptListView scriptList = (ScriptListView) findViewById(R.id.script_list);
scriptList.setStorageFileProvider(mStorageFileProvider, new ScriptFile(StorageFileProvider.DEFAULT_DIRECTORY));
scriptList.setStorageFileProvider(mStorageFileProvider, new ScriptFile(StorageFileProvider.getDefaultDirectory()));
scriptList.setOnScriptFileClickListener((view, file) -> {
mSelectedScriptFilePath = file.getPath();
finish();

View File

@ -44,7 +44,7 @@ public class ScriptWidgetSettingsActivity extends BaseActivity {
mStorageFileProvider = StorageFileProvider.getExternalStorageProvider();
ScriptListView scriptList = (ScriptListView) findViewById(R.id.script_list);
scriptList.setStorageFileProvider(mStorageFileProvider);
scriptList.setCurrentDirectory(new ScriptFile(StorageFileProvider.DEFAULT_DIRECTORY));
scriptList.setCurrentDirectory(new ScriptFile(StorageFileProvider.getDefaultDirectory()));
scriptList.setOnScriptFileClickListener((view, file) -> {
mSelectedScriptFilePath = file.getPath();
finish();

View File

@ -10,9 +10,8 @@ import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.execution.ScriptExecutionListener;
import com.stardust.autojs.execution.SimpleScriptExecutionListener;
import com.stardust.autojs.runtime.exception.ScriptInterruptedException;
import com.stardust.autojs.script.JavaScriptFileSource;
import com.stardust.autojs.script.ScriptSource;
import org.autojs.autojs.App;
import org.autojs.autojs.R;
import org.autojs.autojs.autojs.AutoJs;
import org.autojs.autojs.external.ScriptIntents;
@ -100,8 +99,8 @@ public class Scripts {
public static ScriptExecution run(ScriptSource source) {
return AutoJs.getInstance().getScriptEngineService().execute(source, new ExecutionConfig()
.executePath(StorageFileProvider.DEFAULT_DIRECTORY_PATH)
.requirePath(StorageFileProvider.DEFAULT_DIRECTORY_PATH));
.executePath(StorageFileProvider.getDefaultDirectoryPath())
.requirePath(StorageFileProvider.getDefaultDirectoryPath()));
}
public static ScriptExecution runWithBroadcastSender(File file) {

View File

@ -9,7 +9,7 @@ import com.stardust.app.GlobalAppContext;
import com.stardust.autojs.execution.ScriptExecution;
import com.stardust.autojs.script.StringScriptSource;
import com.stardust.pio.PFiles;
import org.autojs.autojs.App;
import org.autojs.autojs.R;
import org.autojs.autojs.autojs.AutoJs;
import org.autojs.autojs.model.script.Scripts;
@ -98,7 +98,7 @@ public class DevPluginResponseHandler implements Handler {
if (!name.endsWith(".js")) {
name = name + ".js";
}
PFiles.write(StorageFileProvider.DEFAULT_DIRECTORY_PATH + name, script);
PFiles.write(StorageFileProvider.getDefaultDirectoryPath() + name, script);
GlobalAppContext.toast(R.string.text_script_save_successfully);
}
}

View File

@ -0,0 +1,64 @@
package org.autojs.autojs.storage.file;
import com.stardust.pio.PFiles;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
import io.reactivex.Observable;
import io.reactivex.Observer;
public class FileObservable {
public static Observable<File> copy(String fromPath, String toPath) {
return copy(fromPath, toPath, false);
}
public static Observable<File> move(String fromPath, String toPath) {
return copy(fromPath, toPath, true);
}
private static Observable<File> copy(String fromPath, String toPath, boolean deleteOld) {
return new Observable<File>() {
@Override
protected void subscribeActual(Observer<? super File> observer) {
try {
copy(new File(fromPath), new File(toPath), deleteOld, observer);
observer.onComplete();
} catch (IOException e) {
observer.onError(e);
}
}
};
}
private static void copyDir(File fromDir, File toDir, boolean deleteOld, Observer<? super File> progress) throws IOException {
if (!fromDir.isDirectory()) {
return;
}
File[] files = fromDir.listFiles();
if (files == null || files.length == 0) {
return;
}
for (File file : files) {
copy(file, new File(toDir, file.getName()), deleteOld, progress);
}
}
private static void copy(File fromFile, File toFile, boolean deleteOld, Observer<? super File> progress) throws IOException {
progress.onNext(fromFile);
if (fromFile.isDirectory()) {
copyDir(fromFile, toFile, deleteOld, progress);
} else {
PFiles.ensureDir(toFile.getPath());
FileUtils.copyFile(fromFile, toFile);
}
if (deleteOld) {
fromFile.delete();
}
}
}

View File

@ -4,8 +4,10 @@ import android.os.Environment;
import com.stardust.app.GlobalAppContext;
import com.stardust.pio.PFile;
import org.autojs.autojs.App;
import org.autojs.autojs.Pref;
import org.autojs.autojs.R;
import com.stardust.util.LimitedHashMap;
import org.greenrobot.eventbus.EventBus;
@ -28,8 +30,7 @@ public class StorageFileProvider {
public static final int CREATE = 1;
public static final int CHANGE = 2;
public static final int ALL = 3;
public static final String DEFAULT_DIRECTORY_PATH = Environment.getExternalStorageDirectory() + GlobalAppContext.getString(R.string.folder_name);
public static final PFile DEFAULT_DIRECTORY = new PFile(DEFAULT_DIRECTORY_PATH);
public static final FileFilter SCRIPT_FILTER = file ->
file.isDirectory() || file.getName().endsWith(".js") || file.getName().endsWith(".auto");
@ -74,8 +75,10 @@ public class StorageFileProvider {
}
private static final PFile INITIAL_DIRECTORY_DEFAULT = new PFile("");
private static StorageFileProvider externalStorageProvider;
private static final StorageFileProvider DEFAULT_PROVIDER = new StorageFileProvider(DEFAULT_DIRECTORY, 10, SCRIPT_FILTER);
private static final StorageFileProvider DEFAULT_PROVIDER = new StorageFileProvider(INITIAL_DIRECTORY_DEFAULT, 10, SCRIPT_FILTER);
private EventBus mDirectoryEventBus = new EventBus();
private LimitedHashMap<String, List<PFile>> mPFileCache;
@ -99,7 +102,15 @@ public class StorageFileProvider {
}
public StorageFileProvider() {
this(DEFAULT_DIRECTORY, 10);
this(getDefaultDirectory(), 10);
}
public static String getDefaultDirectoryPath() {
return getDefaultDirectory().getPath();
}
public static PFile getDefaultDirectory() {
return new PFile(Environment.getExternalStorageDirectory(), Pref.getScriptDirPath());
}
public static StorageFileProvider getDefault() {
@ -149,25 +160,28 @@ public class StorageFileProvider {
public void notifyStoragePermissionGranted() {
mPFileCache.clear();
mDirectoryEventBus.post(new DirectoryChangeEvent(mInitialDirectory));
mDirectoryEventBus.post(new DirectoryChangeEvent(getInitialDirectory()));
}
@SuppressWarnings("unchecked")
public void refreshAll() {
Map<String, PFile> files = (Map<String, PFile>) mPFileCache.clone();
mPFileCache.clear();
mDirectoryEventBus.post(new DirectoryChangeEvent(mInitialDirectory));
mDirectoryEventBus.post(new DirectoryChangeEvent(getInitialDirectory()));
for (Map.Entry<String, PFile> file : files.entrySet()) {
mDirectoryEventBus.post(new DirectoryChangeEvent(new PFile(file.getKey())));
}
}
public PFile getInitialDirectory() {
if (mInitialDirectory == INITIAL_DIRECTORY_DEFAULT) {
return getDefaultDirectory();
}
return mInitialDirectory;
}
public Observable<PFile> getInitialDirectoryFiles() {
return getDirectoryFiles(mInitialDirectory);
return getDirectoryFiles(getInitialDirectory());
}
public Observable<PFile> getDirectoryFiles(PFile directory) {

View File

@ -148,7 +148,7 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
private void setupWithSourceFile(ScriptFile file) {
String dir = file.getParent();
if (dir.startsWith(getFilesDir().getPath())) {
dir = StorageFileProvider.DEFAULT_DIRECTORY_PATH;
dir = StorageFileProvider.getDefaultDirectoryPath();
}
mOutputPath.setText(dir);
mAppName.setText(file.getSimplifiedName());
@ -168,7 +168,7 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
new FileChooserDialogBuilder(this)
.title(R.string.text_source_file_path)
.dir(Environment.getExternalStorageDirectory().getPath(),
initialDir == null ? StorageFileProvider.DEFAULT_DIRECTORY_PATH : initialDir)
initialDir == null ? StorageFileProvider.getDefaultDirectoryPath() : initialDir)
.singleChoice(this::setSource)
.show();
}
@ -190,7 +190,7 @@ public class BuildActivity extends BaseActivity implements AutoJsApkBuilder.Prog
@Click(R.id.select_output)
void selectOutputDirPath() {
String initialDir = new File(mOutputPath.getText().toString()).exists() ?
mOutputPath.getText().toString() : StorageFileProvider.DEFAULT_DIRECTORY_PATH;
mOutputPath.getText().toString() : StorageFileProvider.getDefaultDirectoryPath();
new FileChooserDialogBuilder(this)
.title(R.string.text_output_apk_path)
.dir(initialDir)

View File

@ -67,7 +67,7 @@ public class ScriptOperations {
}
public ScriptOperations(Context context, View view) {
this(context, view, new ScriptFile(StorageFileProvider.DEFAULT_DIRECTORY));
this(context, view, new ScriptFile(StorageFileProvider.getDefaultDirectory()));
}
public void newScriptFileForScript(final String script) {

View File

@ -32,7 +32,7 @@ public class FileChooserDialogBuilder extends ThemeColorMaterialDialogBuilder {
}
private FileChooseListView mFileChooseListView;
private PFile mRootDir = StorageFileProvider.DEFAULT_DIRECTORY;
private PFile mRootDir = StorageFileProvider.getDefaultDirectory();
private MultiChoiceCallback mCallback;
public FileChooserDialogBuilder(@NonNull Context context) {
@ -59,7 +59,7 @@ public class FileChooserDialogBuilder extends ThemeColorMaterialDialogBuilder {
public FileChooserDialogBuilder dir(String rootDir, String initialDir) {
mRootDir = new PFile(rootDir);
if (mRootDir.equals(StorageFileProvider.DEFAULT_DIRECTORY)) {
if (mRootDir.equals(StorageFileProvider.getDefaultDirectory())) {
mFileChooseListView.setStorageFileProvider(StorageFileProvider.getDefault());
} else {
mFileChooseListView.setStorageFileProvider(new StorageFileProvider(mRootDir, 10), new ScriptFile(initialDir));

View File

@ -5,7 +5,6 @@ import android.net.Uri;
import android.support.design.widget.BottomSheetDialog;
import android.support.design.widget.Snackbar;
import android.util.AttributeSet;
import android.view.View;
import android.webkit.ValueCallback;
import android.webkit.WebView;
@ -126,7 +125,7 @@ public class CommunityWebView extends EWebView {
}
new FileChooserDialogBuilder(getContext())
.title(R.string.text_select_file_to_upload)
.dir(StorageFileProvider.DEFAULT_DIRECTORY_PATH)
.dir(StorageFileProvider.getDefaultDirectoryPath())
.singleChoice(file -> callback.onReceiveValue(Uri.fromFile(file)))
.cancelListener(dialog -> callback.onReceiveValue(null))
.show();

View File

@ -0,0 +1,125 @@
package org.autojs.autojs.ui.settings;
import android.content.Context;
import android.support.annotation.NonNull;
import android.text.Editable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.Toast;
import com.afollestad.materialdialogs.MaterialDialog;
import com.afollestad.materialdialogs.prefs.MaterialEditTextPreference;
import com.stardust.pio.PFiles;
import org.autojs.autojs.Pref;
import org.autojs.autojs.R;
import org.autojs.autojs.storage.file.FileObservable;
import org.autojs.autojs.storage.file.StorageFileProvider;
import org.autojs.autojs.theme.dialog.ThemeColorMaterialDialogBuilder;
import org.autojs.autojs.tool.SimpleObserver;
import org.autojs.autojs.ui.widget.SimpleTextWatcher;
import java.io.File;
import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
public class ScriptDirPathPreference extends MaterialEditTextPreference {
private RadioGroup mRadioGroup;
public ScriptDirPathPreference(Context context) {
super(context);
}
public ScriptDirPathPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScriptDirPathPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ScriptDirPathPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onAddEditTextToDialogView(@NonNull View dialogView, @NonNull EditText editText) {
super.onAddEditTextToDialogView(dialogView, editText);
mRadioGroup = (RadioGroup) View.inflate(getContext(), R.layout.script_dir_pref_radio_group, null);
editText.addTextChangedListener(new SimpleTextWatcher(this::verifyInput));
((ViewGroup) dialogView).addView(mRadioGroup);
}
private void verifyInput(Editable text) {
}
@Override
protected void onDialogClosed(boolean positiveResult) {
String oldPath = StorageFileProvider.getDefaultDirectoryPath();
super.onDialogClosed(positiveResult);
if (!positiveResult) {
return;
}
String newPath = StorageFileProvider.getDefaultDirectoryPath();
if (TextUtils.equals(oldPath, newPath)) {
return;
}
int id = mRadioGroup.getCheckedRadioButtonId();
if (id == R.id.none) {
StorageFileProvider.getDefault().refreshAll();
return;
}
Observable<File> fileObservable;
if (id == R.id.copy) {
fileObservable = FileObservable.copy(oldPath, newPath);
} else {
fileObservable = FileObservable.move(oldPath, newPath);
}
showFileProgressDialog(fileObservable);
}
private void showFileProgressDialog(Observable<File> observable) {
MaterialDialog dialog = new ThemeColorMaterialDialogBuilder(getContext())
.progress(true, 0)
.progressIndeterminateStyle(true)
.title(R.string.text_on_progress)
.cancelable(false)
.content("")
.show();
observable.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SimpleObserver<File>() {
@Override
public void onNext(File file) {
dialog.setContent(file.getPath());
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
dialog.dismiss();
StorageFileProvider.getDefault().refreshAll();
Toast.makeText(getContext(), getContext().getString(R.string.text_error_copy_file,
e.getMessage()), Toast.LENGTH_LONG).show();
}
@Override
public void onComplete() {
dialog.dismiss();
StorageFileProvider.getDefault().refreshAll();
}
});
}
}

View File

@ -117,7 +117,7 @@ public class UpdateInfoDialogBuilder extends MaterialDialog.Builder {
.title(R.string.text_downloading)
.progress(false, 100)
.show();
final String path = StorageFileProvider.DEFAULT_DIRECTORY_PATH + "AutoJs.apk";
final String path = StorageFileProvider.getDefaultDirectoryPath() + "AutoJs.apk";
final DownloadTask task = new DownloadTask() {
@Override
protected void onProgressUpdate(Integer... values) {

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RadioButton
android:id="@+id/none"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="不执行任何操作"/>
<RadioButton
android:id="@+id/copy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="复制原文件夹内容到新文件夹"/>
<RadioButton
android:id="@+id/move"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="移动原文件夹内容到新文件夹"/>
</RadioGroup>

View File

@ -47,7 +47,6 @@
<string name="text_already_create">Created</string>
<string name="text_delete">Delete</string>
<string name="text_already_delete">Deleted</string>
<string name="folder_name">/Scripts/</string>
<string name="text_error">Error</string>
<string name="text_copy_debug_info">Copy debugging log</string>
<string name="text_it_is_the_developer_of_app">This is a software developer(。・・)</string>
@ -165,5 +164,6 @@
<string name="text_value">Value</string>
<string name="text_show_widget_infomation">View info</string>
<string name="text_show_layout_hierarchy">View in layout bounds\' view</string>
<string name="default_value_script_dir_path">/Scripts/</string>
</resources>

View File

@ -49,7 +49,6 @@
<string name="text_already_create">已创建</string>
<string name="text_delete">删除</string>
<string name="text_already_delete">已删除</string>
<string name="folder_name">/脚本/</string>
<string name="text_error">错误</string>
<string name="text_copy_debug_info">复制调试信息</string>
<string name="text_it_is_the_developer_of_app">这是软件开发者(。・・)</string>
@ -356,4 +355,8 @@
<string name="text_inspect_layout">布局分析</string>
<string name="text_pointer_location">指针位置[Root]</string>
<string name="text_skip">跳过</string>
<string name="text_change_script_dir">更改脚本文件夹路径</string>
<string name="key_script_dir_path">key_script_dir_path</string>
<string name="default_value_script_dir_path">/脚本/</string>
<string name="text_error_copy_file" formatted="true">发生错误: %s</string>
</resources>

View File

@ -118,6 +118,16 @@
android:layout="@layout/preference_custom"
android:title="@string/text_documentation_source"
/>
<org.autojs.autojs.ui.settings.ScriptDirPathPreference
android:entries="@array/keys_documentation_source"
android:entryValues="@array/values_documentation_source"
android:key="@string/key_script_dir_path"
android:defaultValue="@string/default_value_script_dir_path"
android:layout="@layout/preference_custom"
android:title="@string/text_change_script_dir"
/>
android:
</com.stardust.theme.preference.ThemeColorPreferenceCategory>
<com.stardust.theme.preference.ThemeColorPreferenceCategory