This commit is contained in:
hyb1996
2017-04-26 13:48:59 +08:00
parent 38fa3b3988
commit 6829c0659e
92 changed files with 3439 additions and 679 deletions

View File

@@ -0,0 +1,71 @@
package com.stardust.scriptdroid.tool;
import android.graphics.Bitmap;
import android.graphics.Matrix;
/**
* Created by Stardust on 2017/4/22.
*/
public class BitmapTool {
public static Bitmap scaleBitmap(Bitmap origin, int newWidth, int newHeight) {
if (origin == null) {
return null;
}
int height = origin.getHeight();
int width = origin.getWidth();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);// 使用后乘
return Bitmap.createBitmap(origin, 0, 0, width, height, matrix, false);
}
/*
public static MatOfDMatch matchesBitmaps(Bitmap bitmap1, Bitmap bitmap2) {
FeatureDetector detector = FeatureDetector.create(FeatureDetector.BRISK);
DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.ORB);
DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);
Mat descriptors1 = computeDescriptors(bitmap1, detector, descriptor);
Mat descriptors2 = computeDescriptors(bitmap2, detector, descriptor);
MatOfDMatch matches = new MatOfDMatch();
matcher.match(descriptors1, descriptors2, matches);
return matches;
}
private static Mat computeDescriptors(Bitmap bitmap, FeatureDetector detector, DescriptorExtractor descriptor) {
Mat mat = bitmapToMat(bitmap.copy(bitmap.getConfig(), true));
Mat descriptors = new Mat();
MatOfKeyPoint keyPoints1 = new MatOfKeyPoint();
detector.detect(mat, keyPoints1);
descriptor.compute(mat, keyPoints1, descriptors);
return descriptors;
}
private static Mat bitmapToMat(Bitmap bmp) {
Mat mat = new Mat(bmp.getWidth(), bmp.getHeight(), CvType.CV_8UC1);
Utils.bitmapToMat(bmp, mat);
return mat;
}
public static Core.MinMaxLocResult templateMatching(Bitmap bitmap, Bitmap tmp, int matchMethod) {
Mat img = bitmapToMat(bitmap);
Mat template = bitmapToMat(tmp);
// / Create the result matrix
int result_cols = img.cols() - template.cols() + 1;
int result_rows = img.rows() - template.rows() + 1;
Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);
// / Do the Matching and Normalize
Imgproc.matchTemplate(img, template, result, matchMethod);
Core.normalize(result, result, 0, 1, Core.NORM_MINMAX, -1, new Mat());
// / Localizing the best match with minMaxLoc
Core.MinMaxLocResult mmr = Core.minMaxLoc(result);
return mmr;
}
*/
}

View File

@@ -14,7 +14,6 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.Callable;
/**
* Created by Stardust on 2017/4/3.
@@ -24,14 +23,14 @@ public abstract class DrawableSaver {
private static final String PREFIX = "saved_drawable_";
protected Drawable mOriginalDrawble;
protected Drawable mOriginalDrawable;
private Context mContext;
private String mName;
public DrawableSaver(Context context, String name, Drawable originalDrawble) {
public DrawableSaver(Context context, String name, Drawable originalDrawable) {
mContext = context;
mName = PREFIX + name;
mOriginalDrawble = originalDrawble;
mOriginalDrawable = originalDrawable;
readImageAndApply();
}
@@ -89,7 +88,7 @@ public abstract class DrawableSaver {
}
public void reset() {
applyDrawableToView(mOriginalDrawble);
applyDrawableToView(mOriginalDrawable);
mContext.deleteFile(mName);
}

View File

@@ -0,0 +1,162 @@
package com.stardust.scriptdroid.tool;
/**
* Created by Stardust on 2017/4/23.
*/
import android.graphics.Bitmap;
import com.stardust.mi666.ocr.ColorDetector;
import com.stardust.mi666.ocr.SimpleTextDetector;
import java.util.HashMap;
import java.util.Map;
public class ImagePHash {
private static final String LOG_TAG = "ImagePHash";
private int width = 32;
private int height;
private int smallerWidth = 8;
private int smallerHeight;
public ImagePHash() {
this(32, 8);
}
public ImagePHash(int width, int smallerWidth) {
this(width, width, smallerWidth, smallerWidth);
}
public ImagePHash(int width, int height, int smallerWidth, int smallerHeight) {
this.width = width;
this.height = height;
this.smallerWidth = smallerWidth;
this.smallerHeight = smallerHeight;
initCoefficients();
}
public int distance(boolean[] s1, boolean[] s2) {
int counter = 0;
for (int k = 0; k < s1.length; k++) {
if (s1[k] != s2[k]) {
counter++;
}
}
return counter;
}
public boolean[] getHash(Bitmap img) {
double[][] vals = new double[width][height];
img = BitmapTool.scaleBitmap(img, width, height);
for (int x = 0; x < img.getWidth(); x++) {
for (int y = 0; y < img.getHeight(); y++) {
vals[x][y] = getBlue(img, x, y);
}
}
double[][] dctVals = applyDCT(vals);
double total = 0;
for (int x = 0; x < smallerWidth; x++) {
for (int y = 0; y < smallerHeight; y++) {
total += dctVals[x][y];
}
}
total -= dctVals[0][0];
double avg = total / (double) ((smallerWidth * smallerHeight) - 1);
boolean[] hash = new boolean[smallerWidth * smallerHeight];
int i = 0;
for (int x = 0; x < smallerWidth; x++) {
for (int y = 0; y < smallerHeight; y++) {
if (x != 0 && y != 0) {
hash[i++] = dctVals[x][y] > avg;
}
}
}
return hash;
}
private static int getBlue(Bitmap img, int x, int y) {
return img.getPixel(x, y) & 0xff;
}
private double[] c;
private double[] c2;
private void initCoefficients() {
c = new double[width];
c2 = new double[height];
for (int i = 1; i < width; i++) {
c[i] = 1;
}
for (int i = 1; i < height; i++) {
c2[i] = 1;
}
c[0] = 1 / Math.sqrt(2.0);
c2[0] = 1 / Math.sqrt(2.0);
}
private double[][] applyDCT(double[][] f) {
double[][] F = new double[width][height];
for (int u = 0; u < width; u++) {
for (int v = 0; v < height; v++) {
double sum = 0.0;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
sum += Math.cos(((2 * i + 1) / (2.0 * width)) * u * Math.PI) * Math.cos(((2 * j + 1) / (2.0 * height)) * v * Math.PI) * (f[i][j]);
}
}
sum *= ((c[u] * c2[v]) / 4.0);
F[u][v] = sum;
}
}
return F;
}
public static class OCR implements com.stardust.mi666.ocr.OCR {
private SimpleTextDetector mSimpleTextDetector;
private Map<Character, boolean[]> mChars = new HashMap<>();
private ImagePHash mImagePHash;
public OCR(ColorDetector colorDetector, int size, int smallerSize) {
mSimpleTextDetector = new SimpleTextDetector(colorDetector);
mImagePHash = new ImagePHash(size, smallerSize);
}
public OCR(ColorDetector colorDetector, ImagePHash pHash) {
mSimpleTextDetector = new SimpleTextDetector(colorDetector);
mImagePHash = pHash;
}
@Override
public void addChar(char ch, Bitmap bitmap) {
mChars.put(ch, mImagePHash.getHash(mSimpleTextDetector.detect(bitmap)));
}
@Override
public char detect(Bitmap bitmap) {
bitmap = mSimpleTextDetector.detect(bitmap);
int min = Integer.MAX_VALUE;
boolean[] h = mImagePHash.getHash(bitmap);
char ch = ' ';
for (Map.Entry<Character, boolean[]> entry : mChars.entrySet()) {
int d = mImagePHash.distance(h, entry.getValue());
//Log.i(LOG_TAG, "char: " + entry.getKey() + " distance: " + d);
if (d < min) {
min = d;
ch = entry.getKey();
}
}
return ch;
}
}
}

View File

@@ -2,9 +2,6 @@ package com.stardust.scriptdroid.tool;
import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import com.stardust.app.OnActivityResultDelegate;
import com.stardust.scriptdroid.R;
@@ -22,6 +19,8 @@ public class ImageSelector implements OnActivityResultDelegate {
void onImageSelected(ImageSelector selector, InputStream path);
}
private static final String TAG = ImageSelector.class.getSimpleName();
private static final int REQUEST_CODE = "LOVE EATING".hashCode() >> 16;
private Activity mActivity;
private ImageSelectorCallback mCallback;

View File

@@ -0,0 +1,20 @@
package com.stardust.scriptdroid.tool;
import android.content.Context;
import android.widget.Toast;
import com.stardust.scriptdroid.R;
import com.stardust.util.IntentUtil;
/**
* Created by Stardust on 2017/4/12.
*/
public class IntentTool {
public static void browse(Context context, String url){
if (!IntentUtil.browse(context, url)) {
Toast.makeText(context, R.string.text_no_brower, Toast.LENGTH_SHORT).show();
}
}
}

View File

@@ -0,0 +1,25 @@
package com.stardust.scriptdroid.tool;
import android.annotation.SuppressLint;
import android.app.Application;
import com.stardust.autojs.script.JsBeautifier;
/**
* Created by Stardust on 2017/4/18.
*/
public class JsBeautifierFactory {
@SuppressLint("StaticFieldLeak")
private static JsBeautifier jsBeautifier;
public static JsBeautifier getJsBeautify() {
return jsBeautifier;
}
public static void initJsBeautify(Application context, String path) {
jsBeautifier = new JsBeautifier(context, path);
jsBeautifier.prepare();
}
}

View File

@@ -0,0 +1,26 @@
package com.stardust.scriptdroid.tool;
import android.content.Context;
import com.afollestad.materialdialogs.MaterialDialog;
import com.stardust.scriptdroid.R;
/**
* Created by Stardust on 2017/4/18.
*/
public class MaterialDialogFactory {
public static MaterialDialog createProgress(Context context) {
return new MaterialDialog.Builder(context)
.progress(true, 0)
.cancelable(false)
.content(R.string.text_processing)
.build();
}
public static MaterialDialog showProgress(Context context) {
MaterialDialog dialog = createProgress(context);
dialog.show();
return dialog;
}
}

View File

@@ -0,0 +1,161 @@
package com.stardust.scriptdroid.tool;
import android.content.Context;
import android.preference.PreferenceManager;
import com.stardust.pio.UncheckedIOException;
import com.stardust.scriptdroid.App;
import java.io.IOException;
import jackpal.androidterm.ShellTermSession;
import jackpal.androidterm.emulatorview.TermSession;
import jackpal.androidterm.util.TermSettings;
/**
* Created by Stardust on 2017/4/24.
*/
public class Shell {
private TermSession mTermSession;
private String mOutput;
public Shell(boolean root) {
this(App.getApp(), root ? "su\n" : "sh\n");
}
public Shell(Context context, String initialCommand) {
TermSettings settings = new TermSettings(context.getResources(), PreferenceManager.getDefaultSharedPreferences(context));
try {
mTermSession = new MyShellTermSession(settings, initialCommand);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
public String execAndWaitFor(String command) {
mTermSession.write(command + "\n");
mOutput = null;
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return mOutput;
}
public String execAndWaitFor(String command, int millis) {
mTermSession.write(command + "\n");
mOutput = null;
synchronized (this) {
try {
wait(millis);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
return mOutput;
}
public void exec(String command) {
mTermSession.write(command);
}
public void execute(String command) {
mTermSession.write(command);
}
public void Tap(int x, int y) {
execute("input tap " + x + " " + y);
}
public void Swipe(int x1, int y1, int x2, int y2) {
execute("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2);
}
public void Swipe(int x1, int y1, int x2, int y2, long duration) {
execute("input swipe " + x1 + " " + y1 + " " + x2 + " " + y2 + " " + duration);
}
public void KeyCode(int keyCode) {
execute("input keyevent " + keyCode);
}
public void KeyCode(String keyCode) {
execute("input keyevent " + keyCode);
}
public void Home() {
KeyCode(3);
}
public void Back() {
KeyCode(4);
}
public void Power() {
KeyCode(26);
}
public void Up() {
KeyCode(19);
}
public void Down() {
KeyCode(20);
}
public void Left() {
KeyCode(21);
}
public void Right() {
KeyCode(22);
}
public void OK() {
KeyCode(23);
}
public void VolumeUp() {
KeyCode(24);
}
public void VolumeDown() {
KeyCode(25);
}
public void Menu() {
KeyCode(1);
}
public void Camera() {
KeyCode(27);
}
public void Text(String text) {
execute("input text " + text);
}
private class MyShellTermSession extends ShellTermSession {
public MyShellTermSession(TermSettings settings, String initialCommand) throws IOException {
super(settings, initialCommand);
}
@Override
protected void processInput(byte[] data, int offset, int count) {
mOutput = new String(data, offset, count);
synchronized (Shell.this) {
Shell.this.notifyAll();
}
appendToEmulator(data, offset, count);
}
}
}

View File

@@ -13,7 +13,7 @@ import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.stardust.pio.UncheckedIOException;
import com.stardust.scriptdroid.BuildConfig;
import java.lang.reflect.Type;
import java.util.List;
@@ -28,37 +28,40 @@ public class UpdateChecker implements Response.Listener<String>, Response.ErrorL
private RequestQueue mRequestQueue;
private static final String UPDATE_URL = "https://raw.githubusercontent.com/hyb1996/NoRootScriptDroid/master/version.json";
public interface Callback {
void onSuccess(CheckResult result);
void onSuccess(UpdateInfo result);
void onError(Exception exception);
}
private Callback mCallback;
private final int mTimeOut = 3000;
public static UpdateInfo savedResult;
public UpdateChecker(Context context, Callback callback) {
mCallback = callback;
private final int mTimeOut = 3000;
private Callback mCallback;
public UpdateChecker(Context context) {
mRequestQueue = Volley.newRequestQueue(context);
}
private CheckResult parse(String json) {
private UpdateInfo parse(String json) {
Gson gson = new Gson();
Type type = new TypeToken<CheckResult>() {
Type type = new TypeToken<UpdateInfo>() {
}.getType();
CheckResult result = gson.fromJson(json, type);
UpdateInfo result = gson.fromJson(json, type);
Log.i(LOG_TAG, result.toString());
return result;
}
public void check() {
public void check(final Callback callback) {
mCallback = callback;
StringRequest request = new StringRequest(Request.Method.GET, UPDATE_URL, this, this);
request.setRetryPolicy(new DefaultRetryPolicy(mTimeOut, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
request.setTag("update-check");
request.setShouldCache(false);
mRequestQueue.add(request);
}
@@ -66,12 +69,16 @@ public class UpdateChecker implements Response.Listener<String>, Response.ErrorL
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
mCallback.onError(error);
mCallback = null;
}
@Override
public void onResponse(String response) {
try {
CheckResult result = parse(response);
UpdateInfo result = parse(response);
savedResult = result;
if (mCallback == null)
return;
if (result.isValid()) {
mCallback.onSuccess(result);
} else {
@@ -81,13 +88,14 @@ public class UpdateChecker implements Response.Listener<String>, Response.ErrorL
e.printStackTrace();
mCallback.onError(e);
}
mCallback = null;
}
public void cancel() {
mRequestQueue.cancelAll("update-check");
}
public static class CheckResult {
public static class UpdateInfo {
public int versionCode;
public String releaseNotes;
@@ -95,25 +103,34 @@ public class UpdateChecker implements Response.Listener<String>, Response.ErrorL
public List<Download> downloads;
public List<OldVersion> oldVersions;
public int deprecated;
public String downloadUrl;
public boolean isValid() {
return downloads != null && !downloads.isEmpty() && versionCode > 0
&& !TextUtils.isEmpty(versionName) && !TextUtils.isEmpty(releaseNotes);
}
public OldVersion getOldVersion(int versionCode) {
for (OldVersion oldVersion : oldVersions) {
if (oldVersion.versionCode == versionCode) {
return oldVersion;
}
}
return null;
}
@Override
public String toString() {
return "CheckResult{" +
return "UpdateInfo{" +
"versionCode=" + versionCode +
", releaseNotes='" + releaseNotes + '\'' +
", versionName='" + versionName + '\'' +
", downloads=" + downloads +
", oldVersions=" + oldVersions +
", deprecated=" + deprecated +
", downloadUrl='" + downloadUrl + '\'' +
'}';
}
}
public static class OldVersion {

View File

@@ -0,0 +1,129 @@
package com.stardust.scriptdroid.tool;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import com.stardust.scriptdroid.BuildConfig;
import com.stardust.util.NetworkUtils;
/**
* Created by Stardust on 2017/4/9.
*/
public class VersionInfo {
private static final String KEY_DEPRECATED = "Still loving you...Can we go back...";
private static final String KEY_DEPRECATED_VERSION_CODE = "I miss you so much tonight...Baby don't let me cry...";
public interface OnReceiveUpdateResultCallback {
void onReceive(UpdateChecker.UpdateInfo info, boolean isCurrentVersionDeprecated);
}
private static VersionInfo instance = new VersionInfo();
public static VersionInfo getInstance() {
return instance;
}
private boolean mDeprecated = false;
private UpdateChecker.UpdateInfo mUpdateInfo;
private final int mReconnectTimes = 2;
private int mReconnectCount = 0;
private OnReceiveUpdateResultCallback mOnReceiveUpdateResultCallback;
private SharedPreferences mSharedPreferences;
public void readDeprecatedFromPref(Context context) {
mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
if (mSharedPreferences.getInt(KEY_DEPRECATED_VERSION_CODE, 0) < BuildConfig.VERSION_CODE) {
mSharedPreferences.edit().remove(KEY_DEPRECATED_VERSION_CODE)
.putBoolean(KEY_DEPRECATED, false)
.apply();
}
mDeprecated = mSharedPreferences.getBoolean(KEY_DEPRECATED, false);
}
public void readDeprecatedFromPrefIfNeeded(Context context) {
if (mSharedPreferences == null) {
readDeprecatedFromPref(context);
}
}
public boolean isCurrentVersionDeprecated() {
return mDeprecated;
}
public UpdateChecker.UpdateInfo getUpdateInfo() {
return mUpdateInfo;
}
public String getCurrentVersionIssues() {
if (mUpdateInfo == null)
return null;
UpdateChecker.OldVersion oldVersion = mUpdateInfo.getOldVersion(BuildConfig.VERSION_CODE);
if (oldVersion == null)
return null;
return oldVersion.issues;
}
public void checkUpdateIfNeeded(Context context) {
if (mUpdateInfo == null) {
checkUpdateIfUsingWifi(context);
}
}
public void setOnReceiveUpdateResultCallback(OnReceiveUpdateResultCallback onReceiveUpdateResultCallback) {
mOnReceiveUpdateResultCallback = onReceiveUpdateResultCallback;
}
private void checkUpdateIfUsingWifi(Context context) {
if (NetworkUtils.isWifiAvailable(context)) {
checkUpdate(context);
}
}
public void checkUpdate(Context context) {
mReconnectCount = 0;
checkUpdateInner(context);
}
private void checkUpdateInner(final Context context) {
mReconnectCount++;
new UpdateChecker(context).check(new UpdateChecker.Callback() {
@Override
public void onSuccess(UpdateChecker.UpdateInfo result) {
if (result.isValid()) {
setUpdateInfo(result);
} else if (mReconnectCount < mReconnectTimes) {
checkUpdate(context);
}
}
@Override
public void onError(Exception exception) {
if (mReconnectCount < mReconnectTimes) {
checkUpdate(context);
}
}
});
}
private void setUpdateInfo(UpdateChecker.UpdateInfo result) {
mDeprecated = BuildConfig.VERSION_CODE <= result.deprecated;
mUpdateInfo = result;
if (mDeprecated) {
mSharedPreferences.edit().putBoolean(KEY_DEPRECATED, mDeprecated)
.putInt(KEY_DEPRECATED_VERSION_CODE, BuildConfig.VERSION_CODE)
.apply();
}
if (mOnReceiveUpdateResultCallback != null) {
mOnReceiveUpdateResultCallback.onReceive(result, mDeprecated);
}
}
}