Refactor: split into modules autojs, common, app and automator

This commit is contained in:
hyb1996
2017-04-03 00:43:15 +08:00
parent e7500e6e21
commit bfabef6a0e
182 changed files with 2521 additions and 5840 deletions

View File

@@ -8,6 +8,7 @@ import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import com.stardust.util.Shell;
import com.stardust.view.accessibility.AccessibilityServiceUtils;
import static com.stardust.view.accessibility.AccessibilityServiceUtils.isAccessibilityServiceEnabled;

View File

@@ -1,86 +0,0 @@
package com.stardust.scriptdroid.tool;
import android.app.Activity;
import android.support.v4.widget.DrawerLayout;
import android.view.Gravity;
import android.widget.Toast;
import com.stardust.scriptdroid.R;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Stardust on 2017/2/3.
*/
public interface BackPressedHandler {
boolean onBackPressed(Activity activity);
class Observer implements BackPressedHandler {
private List<BackPressedHandler> mBackPressedHandlers = new ArrayList<>();
@Override
public boolean onBackPressed(Activity activity) {
for (BackPressedHandler handler : mBackPressedHandlers) {
if (handler.onBackPressed(activity)) {
return true;
}
}
return false;
}
public void registerHandler(BackPressedHandler handler) {
mBackPressedHandlers.add(handler);
}
}
class DoublePressExit implements BackPressedHandler {
private final Activity mActivity;
private long mLastPressedMillis;
private long mDoublePressInterval = 1000;
public DoublePressExit(Activity activity) {
mActivity = activity;
}
public DoublePressExit doublePressInterval(long doublePressInterval) {
mDoublePressInterval = doublePressInterval;
return this;
}
@Override
public boolean onBackPressed(Activity activity) {
if (System.currentTimeMillis() - mLastPressedMillis < mDoublePressInterval) {
mActivity.finish();
} else {
mLastPressedMillis = System.currentTimeMillis();
Toast.makeText(mActivity, R.string.text_press_again_to_exit, Toast.LENGTH_SHORT).show();
}
return true;
}
}
class DrawerAutoClose implements BackPressedHandler {
private DrawerLayout mDrawerLayout;
private int mGravity;
public DrawerAutoClose(DrawerLayout drawerLayout, int gravity){
mDrawerLayout = drawerLayout;
mGravity = gravity;
}
@Override
public boolean onBackPressed(Activity activity) {
if (mDrawerLayout.isDrawerOpen(mGravity)) {
mDrawerLayout.closeDrawer(mGravity);
return true;
}
return false;
}
}
}

View File

@@ -1,22 +0,0 @@
package com.stardust.scriptdroid.tool;
/**
* Created by Stardust on 2017/1/23.
*/
public class ClassTool {
public static void loadClass(Class c) {
try {
Class.forName(c.getName());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static void loadClasses(Class... classes) {
for (Class c : classes) {
loadClass(c);
}
}
}

View File

@@ -1,19 +0,0 @@
package com.stardust.scriptdroid.tool;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import com.stardust.scriptdroid.App;
/**
* Created by Stardust on 2017/3/10.
*/
public class ClipboardTool {
public static void setClip(CharSequence text) {
((ClipboardManager) App.getApp().getSystemService(Context.CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("", text));
}
}

View File

@@ -0,0 +1,74 @@
package com.stardust.scriptdroid.tool;
/**
* Created by Stardust on 2017/2/2.
*/
import android.content.Intent;
import android.util.Log;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.Thread.UncaughtExceptionHandler;
public class CrashHandler implements UncaughtExceptionHandler {
private static final String TAG = "CrashHandler";
private static int crashCount = 0;
private static long firstCrashMillis = 0;
private final Class<?> mErrorReportClass;
public CrashHandler(Class<?> errorReportClass) {
this.mErrorReportClass = errorReportClass;
}
public void uncaughtException(Thread thread, Throwable ex) {
try {
Log.e(TAG, "Uncaught Exception", ex);
if (crashTooManyTimes())
return;
String msg = App.getApp().getString(R.string.sorry_for_crash) + ex.toString();
startErrorReportActivity(msg, throwableToString(ex));
System.exit(0);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
private void startErrorReportActivity(String msg, String detail) {
Intent intent = new Intent(App.getApp(), this.mErrorReportClass);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("message", msg);
intent.putExtra("error", detail);
App.getApp().startActivity(intent);
}
private boolean crashTooManyTimes() {
if (crashIntervalTooLong()) {
resetCrashCount();
return false;
}
crashCount++;
return crashCount >= 5;
}
private void resetCrashCount() {
firstCrashMillis = System.currentTimeMillis();
crashCount = 0;
}
private boolean crashIntervalTooLong() {
return System.currentTimeMillis() - firstCrashMillis > 3000;
}
public static String throwableToString(Throwable throwable) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
throwable.printStackTrace();
throwable.printStackTrace(pw);
return sw.toString();
}
}

View File

@@ -1,263 +0,0 @@
package com.stardust.scriptdroid.tool;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.URISyntaxException;
/**
* Created by Stardust on 2017/1/23.
*/
public class FileUtils {
private static final int BUFFER_SIZE = 1024 * 100;
public static String getPath(Context context, Uri uri) throws URISyntaxException {
if ("content".equalsIgnoreCase(uri.getScheme())) {
String[] projection = {"_data"};
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, null, null, null);
int column_index = cursor.getColumnIndexOrThrow("_data");
if (cursor.moveToFirst()) {
return cursor.getString(column_index);
}
} catch (Exception e) {
// Eat it
}
} else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
public static String getPath(InputStream inputStream) {
if (inputStream instanceof FileInputStream) {
FileInputStream fis = (FileInputStream) inputStream;
try {
Field field = fis.getClass().getDeclaredField("path");
field.setAccessible(true);
return (String) field.get(fis);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
return null;
}
public static boolean createFileIfNotExists(String path) {
ensureFolder(path);
File file = new File(path);
if (!file.exists()) {
try {
return file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
private static boolean ensureFolder(String path) {
int i = path.lastIndexOf("\\");
if (i < 0)
i = path.lastIndexOf("/");
if (i >= 0) {
String folder = path.substring(0, i);
File file = new File(folder);
if (file.exists())
return true;
return file.mkdirs();
} else {
return false;
}
}
public static String readString(File file, String encoding) {
try {
return readString(new FileInputStream(file), encoding);
} catch (FileNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static String readString(File file) {
return readString(file, "utf-8");
}
public static String readString(InputStream is, String encoding) {
try {
byte[] bytes = new byte[is.available()];
is.read(bytes);
return new String(bytes, encoding);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static String readString(InputStream inputStream) {
return readString(inputStream, "utf-8");
}
public static boolean copy(int rawId, String path) {
InputStream is = App.getApp().getResources().openRawResource(rawId);
return copy(is, path);
}
public static boolean copy(InputStream is, String path) {
if (!ensureFolder(path))
return false;
File file = new File(path);
try {
if (!file.exists())
if (!file.createNewFile())
return false;
FileOutputStream fos = new FileOutputStream(file);
return copy(is, fos);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
private static boolean copy(InputStream is, OutputStream os) {
byte[] buffer = new byte[BUFFER_SIZE];
try {
while (is.available() > 0) {
int n = is.read(buffer);
os.write(buffer, 0, n);
}
is.close();
os.close();
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public static boolean copy(String pathFrom, String pathTo) {
try {
return copy(new FileInputStream(pathFrom), pathTo);
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
}
public static boolean copyAsset(String assetFile, String path) {
try {
return copy(App.getApp().getAssets().open(assetFile), path);
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public static String renameWithoutExtension(String path, String newName) {
File file = new File(path);
File newFile = new File(file.getParent(), newName + "." + getExtension(file.getName()));
file.renameTo(newFile);
return newFile.getAbsolutePath();
}
public static String getExtension(String fileName) {
int i = fileName.lastIndexOf('.');
if (i < 0)
return "";
return fileName.substring(i + 1);
}
public static boolean writeString(String path, String text) {
return writeString(new File(path), text);
}
public static boolean writeString(File file, String text) {
try {
return writeString(new FileOutputStream(file), text);
} catch (FileNotFoundException e) {
e.printStackTrace();
return false;
}
}
public static boolean writeString(OutputStream outputStream, String text) {
try {
outputStream.write(text.getBytes());
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
public static String generateNotExistingPath(String path, String extension) {
if (!new File(path + extension).exists())
return path + extension;
int i = 0;
while (true) {
String pathI = path + "(" + i + ")" + extension;
if (!new File(pathI).exists())
return pathI;
i++;
}
}
public static String getNameWithoutExtension(String fileName) {
int a = fileName.lastIndexOf('/');
if (a < 0)
a = fileName.lastIndexOf('\\');
int b = fileName.lastIndexOf('.');
if (a < 0)
a = -1;
if (b < 0)
b = fileName.length();
fileName = fileName.substring(a + 1, b);
return fileName;
}
public static File copyAssetToTmpFile(Context context, String path) {
String extension = getExtension(path);
String name = getNameWithoutExtension(path);
if (name.length() < 5) {
name += name.hashCode();
}
try {
File tmpFile = File.createTempFile(name, "." + extension, context.getCacheDir());
copyAsset(path, tmpFile.getPath());
return tmpFile;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static boolean deleteAll(File file) {
if (file.isFile())
return file.delete();
for (File child : file.listFiles()) {
if (!deleteAll(child))
return false;
}
return file.delete();
}
}

View File

@@ -1,97 +0,0 @@
package com.stardust.scriptdroid.tool;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.Nullable;
import com.stardust.scriptdroid.App;
import com.stardust.scriptdroid.R;
/**
* Intent工具用于Activity之间的跳转调起其他应用程序等
*/
public class IntentTool {
public static boolean goToQQ(Context context, String qq) {
try {
String url = "mqqwpa://im/chat?chat_type=wpa&uin=" + qq;
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
return true;
} catch (Exception exception) {
exception.printStackTrace();
return false;
}
}
/****************
* 发起添加群流程。群号免Root脚本精灵交流群(556928653) 的 key 为: vjHXzZlpGcXNe-YEWzQ85mm_z8y-curC
* 调用 joinQQGroup(vjHXzZlpGcXNe-YEWzQ85mm_z8y-curC) 即可发起手Q客户端申请加群 免Root脚本精灵交流群(556928653)
*
* @param key 由官网生成的key
* @return 返回true表示呼起手Q成功返回false表示呼起失败
******************/
public static boolean joinQQGroup(Context context, String key) {
Intent intent = new Intent().addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D" + key));
// 此Flag可根据具体产品需要自定义如设置则在加群界面按返回返回手Q主界面不设置按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
try {
context.startActivity(intent);
return true;
} catch (Exception e) {
return false;
}
}
public static void goToMail(Context context, String sendTo, @Nullable String title, @Nullable String content) {
Uri uri = Uri.parse("mailto:" + sendTo);
String[] email = {sendTo};
Intent intent = new Intent(Intent.ACTION_SENDTO, uri).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_CC, email);
if (title != null)
intent.putExtra(Intent.EXTRA_SUBJECT, title);
if (content != null)
intent.putExtra(Intent.EXTRA_TEXT, content);
context.startActivity(Intent.createChooser(intent, context.getString(R.string.text_choose_email_app)));
}
public static void goToMail(Context context, String sendTo) {
goToMail(context, sendTo, null, null);
}
public static boolean goToLink(Context context, String link) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
return true;
} catch (ActivityNotFoundException ignored) {
return false;
}
}
public static void shareText(Context context, String text) {
context.startActivity(new Intent(Intent.ACTION_SEND)
.putExtra(Intent.EXTRA_TEXT, text)
.setType("text/plain"));
}
public static boolean goToAppSetting(Context context, String packageName) {
try {
Intent i = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.setData(Uri.parse("package:" + packageName));
context.startActivity(i);
return true;
} catch (ActivityNotFoundException ignored) {
return false;
}
}
public static boolean goToAppSetting(Context context) {
return goToAppSetting(context, context.getPackageName());
}
}

View File

@@ -1,266 +0,0 @@
package com.stardust.scriptdroid.tool;
import android.app.Activity;
import android.preference.PreferenceManager;
import android.util.Log;
import com.stardust.scriptdroid.App;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import jackpal.androidterm.ShellTermSession;
import jackpal.androidterm.util.TermSettings;
/**
* Created by Stardust on 2017/1/20.
* <p>
* 来自网络~~
*/
public class Shell {
private static final String TAG = "Shell";
private final static String COMMAND_SU = "su";
private final static String COMMAND_SH = "sh";
private final static String COMMAND_EXIT = "exit\n";
private final static String COMMAND_LINE_END = "\n";
private Process mProcess;
private DataOutputStream mCommandOutputStream;
private BufferedReader mSucceedReader;
private BufferedReader mErrorReader;
private StringBuilder mSucceedOutput = new StringBuilder();
private StringBuilder mErrorOutput = new StringBuilder();
public Shell() {
this(false);
}
public Shell(boolean root) {
try {
mProcess = new ProcessBuilder(root ? COMMAND_SU : COMMAND_SH).redirectErrorStream(true).start();
mCommandOutputStream = new DataOutputStream(mProcess.getOutputStream());
mSucceedReader = new BufferedReader(new InputStreamReader(mProcess.getInputStream()));
mErrorReader = new BufferedReader(new InputStreamReader(mProcess.getErrorStream()));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public Shell execute(String command) {
try {
mCommandOutputStream.writeBytes(command);
if (!command.endsWith(COMMAND_LINE_END)) {
mCommandOutputStream.writeBytes(COMMAND_LINE_END);
}
mCommandOutputStream.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
return this;
}
public Shell exitAndWaitFor() {
exit();
try {
mProcess.waitFor();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return this;
}
public Shell readAll() {
return readSucceedOutput().readErrorOutput();
}
public Shell readSucceedOutput() {
try {
while (mSucceedReader.ready()) {
String line = mSucceedReader.readLine();
mSucceedOutput.append(line).append("\n");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return this;
}
public Shell readErrorOutput() {
String line;
try {
while ((line = mErrorReader.readLine()) != null) {
mErrorOutput.append(line).append("\n");
}
} catch (IOException e) {
throw new RuntimeException(e);
}
return this;
}
public StringBuilder getSucceedOutput() {
return mSucceedOutput;
}
public StringBuilder getErrorOutput() {
return mErrorOutput;
}
public Shell exit() {
execute(COMMAND_EXIT);
return this;
}
public Shell destroy() {
mProcess.destroy();
return this;
}
public Process getProcess() {
return mProcess;
}
public BufferedReader getSucceedReader() {
return mSucceedReader;
}
public BufferedReader getErrorReader() {
return mErrorReader;
}
public int waitFor() {
try {
return mProcess.waitFor();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
/**
* Command执行结果
*
* @author Mountain
*/
public static class CommandResult {
public int code = -1;
public String error;
public String result;
@Override
public String toString() {
return "ShellResult{" +
"code=" + code +
", error='" + error + '\'' +
", result='" + result + '\'' +
'}';
}
}
/**
* 执行命令—单条
*
* @param command
* @param isRoot
* @return
*/
public static CommandResult execCommand(String command, boolean isRoot) {
String[] commands = command.split("\n");
return execCommand(commands, isRoot);
}
/**
* 执行命令-多条
*
* @param commands
* @param isRoot
* @return
*/
public static CommandResult execCommand(String[] commands, boolean isRoot) {
CommandResult commandResult = new CommandResult();
if (commands == null || commands.length == 0) return commandResult;
Process process = null;
DataOutputStream os = null;
BufferedReader successResult = null;
BufferedReader errorResult = null;
StringBuilder successMsg = null;
StringBuilder errorMsg = null;
try {
process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
os = new DataOutputStream(process.getOutputStream());
for (String command : commands) {
if (command != null) {
os.write(command.getBytes());
os.writeBytes(COMMAND_LINE_END);
os.flush();
}
}
os.writeBytes(COMMAND_EXIT);
os.flush();
commandResult.code = process.waitFor();
//获取错误信息
successMsg = new StringBuilder();
errorMsg = new StringBuilder();
successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String s;
while ((s = successResult.readLine()) != null) successMsg.append(s);
while ((s = errorResult.readLine()) != null) errorMsg.append(s);
commandResult.result = successMsg.toString();
commandResult.error = errorMsg.toString();
Log.i(TAG, commandResult.toString());
} catch (Exception e) {
String errmsg = e.getMessage();
if (errmsg != null) {
Log.e(TAG, errmsg);
} else {
e.printStackTrace();
}
} finally {
try {
if (os != null) os.close();
if (successResult != null) successResult.close();
if (errorResult != null) errorResult.close();
} catch (IOException e) {
String errmsg = e.getMessage();
if (errmsg != null) {
Log.e(TAG, errmsg);
} else {
e.printStackTrace();
}
}
if (process != null) process.destroy();
}
return commandResult;
}
public static Process exec(String[] commands, boolean isRoot) {
try {
Process process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
DataOutputStream os = new DataOutputStream(process.getOutputStream());
for (String command : commands) {
if (command != null) {
os.write(command.getBytes());
os.writeBytes(COMMAND_LINE_END);
os.flush();
}
}
os.writeBytes(COMMAND_EXIT);
os.flush();
os.close();
return process;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public static Process exec(String command, boolean isRoot) {
return exec(command.split("\n"), isRoot);
}
}

View File

@@ -1,29 +0,0 @@
package com.stardust.scriptdroid.tool;
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.support.annotation.IdRes;
import android.view.View;
import android.view.Window;
/**
* Created by Stardust on 2017/1/24.
*/
public class ViewTool {
@SuppressWarnings("unchecked")
public static <V extends View> V $(View view, @IdRes int resId) {
return (V) view.findViewById(resId);
}
public static int getStatusBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
}