Commit Test
@ -76,6 +76,7 @@ dependencies {
|
||||
compile group:'com.twofortyfouram', name:'android-plugin-client-sdk-for-locale', version:'[4.0.2, 5.0['
|
||||
compile 'com.android.volley:volley:1.0.0'
|
||||
compile 'com.github.hyb1996:EnhancedFloaty:0.11'
|
||||
compile 'com.android.support:multidex:1.0.1'
|
||||
compile(name: 'libtermexec-release', ext: 'aar')
|
||||
compile(name: 'emulatorview-release', ext: 'aar')
|
||||
compile(name: 'term-debug', ext: 'aar')
|
||||
|
||||
@ -77,13 +77,13 @@
|
||||
<activity android:name=".ui.error.ErrorReportActivity"/>
|
||||
<activity android:name=".ui.help.LocalWebViewActivity"/>
|
||||
<activity android:name=".external.tasker.TaskerScriptEditActivity"/>
|
||||
<activity android:name=".ui.edit.ViewSampleActivity"/>
|
||||
|
||||
<activity
|
||||
android:name=".ui.error.IssueReporterActivity"
|
||||
android:theme="@style/IssueReporterTheme"/>
|
||||
|
||||
<service android:name="com.stardust.view.Floaty$FloatHeadService"/>
|
||||
<service android:name="com.stardust.view.ResizableFloaty$FloatingWindowService"/>
|
||||
<service android:name="com.stardust.scriptdroid.external.floating_window.HoverMenuService"/>
|
||||
|
||||
<activity android:name=".external.tasker.TaskPrefEditActivity"/>
|
||||
|
||||
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 18 KiB |
@ -1,29 +0,0 @@
|
||||
importClass(com.stardust.mi666.Cracker);
|
||||
var cracker = new Cracker();
|
||||
const path = "/sdcard/666.png";
|
||||
var count = 1;
|
||||
sleep(2000);
|
||||
while(notStopped()){
|
||||
Screencap(path);
|
||||
sleep(2000);
|
||||
toast("你已经被耍了" + count + "次");
|
||||
var coords = cracker.crack(path);
|
||||
for each(var coord in coords){
|
||||
Tap(coord[0], coord[1]);
|
||||
}
|
||||
sleep(9000);
|
||||
关闭();
|
||||
sleep(2000);
|
||||
console.log(++count);
|
||||
再玩一次();
|
||||
sleep(10000);
|
||||
}
|
||||
|
||||
|
||||
function 关闭(){
|
||||
Tap(933, 660);
|
||||
}
|
||||
|
||||
function 再玩一次(){
|
||||
Tap(521, 1615);
|
||||
}
|
||||
@ -16,6 +16,10 @@ import java.util.List;
|
||||
|
||||
public class FragmentPagerAdapterBuilder {
|
||||
|
||||
public interface OnFragmentInstantiateListener {
|
||||
void OnInstantiate(Fragment fragment);
|
||||
}
|
||||
|
||||
private List<Fragment> mFragments = new ArrayList<>();
|
||||
private List<String> mTitles = new ArrayList<>();
|
||||
private FragmentActivity mActivity;
|
||||
@ -56,6 +60,7 @@ public class FragmentPagerAdapterBuilder {
|
||||
public abstract static class StoredFragmentPagerAdapter extends FragmentPagerAdapter {
|
||||
|
||||
private SparseArray<Fragment> mStoredFragments = new SparseArray<>();
|
||||
private OnFragmentInstantiateListener mOnFragmentInstantiateListener;
|
||||
|
||||
public StoredFragmentPagerAdapter(FragmentManager fm) {
|
||||
super(fm);
|
||||
@ -65,9 +70,13 @@ public class FragmentPagerAdapterBuilder {
|
||||
public Object instantiateItem(ViewGroup container, int position) {
|
||||
Fragment fragment = (Fragment) super.instantiateItem(container, position);
|
||||
mStoredFragments.put(position, fragment);
|
||||
if(mOnFragmentInstantiateListener != null){
|
||||
mOnFragmentInstantiateListener.OnInstantiate(fragment);
|
||||
}
|
||||
return fragment;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void destroyItem(ViewGroup container, int position, Object object) {
|
||||
mStoredFragments.remove(position);
|
||||
@ -77,5 +86,9 @@ public class FragmentPagerAdapterBuilder {
|
||||
public Fragment getStoredFragment(int position) {
|
||||
return mStoredFragments.get(position);
|
||||
}
|
||||
|
||||
public void setOnFragmentInstantiateListener(OnFragmentInstantiateListener onFragmentInstantiateListener) {
|
||||
mOnFragmentInstantiateListener = onFragmentInstantiateListener;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,68 +0,0 @@
|
||||
package com.stardust.mi666;
|
||||
|
||||
import com.stardust.util.ScreenMetrics;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/24.
|
||||
*/
|
||||
|
||||
public class Cracker {
|
||||
|
||||
private OCR mOCR;
|
||||
private Solver mSolver;
|
||||
private int mX, mY, mIntervalX, mIntervalY, mWidth, mHeight;
|
||||
|
||||
private void init(int x, int y, int intervalX, int intervalY, int w, int h) {
|
||||
mOCR = new OCR(x, y, intervalX, intervalY, w, h);
|
||||
mSolver = new Solver();
|
||||
mX = x;
|
||||
mY = y;
|
||||
mIntervalY = intervalY;
|
||||
mIntervalX = intervalX;
|
||||
mWidth = w;
|
||||
mHeight = h;
|
||||
}
|
||||
|
||||
public Cracker() {
|
||||
if (ScreenMetrics.getScreenWidth() == 1080 && ScreenMetrics.getScreenHeight() == 1920) {
|
||||
init(68, 724, 238, 236, 228, 68);
|
||||
} else {
|
||||
double scaleX = 1080 / ScreenMetrics.getScreenWidth();
|
||||
double scaleY = 1920 / ScreenMetrics.getScreenHeight();
|
||||
init((int) (68 * scaleX), (int) (724 * scaleY), (int) (238 * scaleX), (int) (236 * scaleY), (int) (228 * scaleX), (int) (68 * scaleY));
|
||||
}
|
||||
}
|
||||
|
||||
public int[][] crack(String path) {
|
||||
List<Integer> numbers = mOCR.detect(path);
|
||||
mSolver.solve(numbers);
|
||||
if (!mSolver.isSolved()) {
|
||||
return new int[0][];
|
||||
}
|
||||
List<Integer> result = mSolver.getResult();
|
||||
boolean[] used = new boolean[numbers.size()];
|
||||
int[][] coordinates = new int[result.size()][2];
|
||||
for (int i = 0; i < coordinates.length; i++) {
|
||||
int index = indexOf(numbers, used, result.get(i));
|
||||
int row = index / 4;
|
||||
int col = index % 4;
|
||||
int x = mX + mIntervalX * col + mWidth / 2;
|
||||
int y = mY + mIntervalY * row + mHeight / 2;
|
||||
coordinates[i][0] = x;
|
||||
coordinates[i][1] = y;
|
||||
}
|
||||
return coordinates;
|
||||
}
|
||||
|
||||
private int indexOf(List<Integer> numbers, boolean[] used, int integer) {
|
||||
for (int i = 0; i < numbers.size(); i++) {
|
||||
if (numbers.get(i) == integer && !used[i]) {
|
||||
used[i] = true;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -1,81 +0,0 @@
|
||||
package com.stardust.mi666;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.util.Log;
|
||||
|
||||
import com.stardust.mi666.ocr.ColorDetector;
|
||||
import com.stardust.mi666.ocr.SimpleTextSplitter;
|
||||
import com.stardust.mi666.ocr.TemplateMatching;
|
||||
import com.stardust.pio.UncheckedIOException;
|
||||
import com.stardust.util.ViewUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/24.
|
||||
*/
|
||||
|
||||
public class OCR {
|
||||
|
||||
private static com.stardust.mi666.ocr.OCR ocr;
|
||||
private static SimpleTextSplitter textSplitter;
|
||||
|
||||
static {
|
||||
ColorDetector colorDetector = new ColorDetector.SimpleColorDetector(0xff9f826f);
|
||||
ocr = new TemplateMatching.TemplateMatchingOCR(1, colorDetector);
|
||||
textSplitter = new SimpleTextSplitter(colorDetector);
|
||||
}
|
||||
|
||||
private int mX, mY, mIntervalX, mIntervalY, mWidth, mHeight;
|
||||
|
||||
public OCR(int x, int y, int intervalX, int intervalY, int w, int h) {
|
||||
mX = x;
|
||||
mY = y;
|
||||
mIntervalY = intervalY;
|
||||
mIntervalX = intervalX;
|
||||
mWidth = w;
|
||||
mHeight = h;
|
||||
}
|
||||
|
||||
public static void init(Context context) {
|
||||
try {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
Bitmap number = BitmapFactory.decodeStream(context.getAssets().open("numbers/" + i + ".png"));
|
||||
ocr.addChar((char) ('0' + i), number);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Integer> detect(String path) {
|
||||
Bitmap screenshot = BitmapFactory.decodeFile(path);
|
||||
try {
|
||||
List<Integer> numbers = new ArrayList<>(16);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (int j = 0; j < 4; j++) {
|
||||
Bitmap block = getBlockAt(screenshot, i, j);
|
||||
List<Bitmap> bitmaps = textSplitter.split(block);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Bitmap num : bitmaps) {
|
||||
sb.append(ocr.detect(num));
|
||||
}
|
||||
numbers.add(Integer.parseInt(sb.toString()));
|
||||
Log.i("TestOCR", "result = " + sb);
|
||||
}
|
||||
}
|
||||
return numbers;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Bitmap getBlockAt(Bitmap bitmap, int row, int col) {
|
||||
return Bitmap.createBitmap(bitmap, mX + col * mIntervalX, mY + row * mIntervalY, mWidth, mHeight);
|
||||
}
|
||||
}
|
||||
@ -1,55 +0,0 @@
|
||||
package com.stardust.mi666;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/24.
|
||||
*/
|
||||
|
||||
public class Solver {
|
||||
|
||||
private boolean mSolved = false;
|
||||
private List<Integer> mResult = new ArrayList<>();
|
||||
private List<Integer> mTmpList = new ArrayList<>();
|
||||
private int[] value;
|
||||
|
||||
|
||||
void solve(int sum, int index) {
|
||||
if (mSolved || index < 0) return;
|
||||
if (sum == value[index] && mTmpList.size() == 5) {
|
||||
mSolved = true;
|
||||
mTmpList.add(value[index]);
|
||||
mResult.addAll(mTmpList);
|
||||
return;
|
||||
}
|
||||
mTmpList.add(value[index]);
|
||||
solve(sum - value[index], index - 1);
|
||||
mTmpList.remove(mTmpList.size() - 1);
|
||||
solve(sum, index - 1);
|
||||
}
|
||||
|
||||
public void solve(int[] num) {
|
||||
mResult.clear();
|
||||
mTmpList.clear();
|
||||
mSolved = false;
|
||||
value = num;
|
||||
solve(6666, 15);
|
||||
}
|
||||
|
||||
public boolean isSolved() {
|
||||
return mSolved;
|
||||
}
|
||||
|
||||
public List<Integer> getResult() {
|
||||
return mResult;
|
||||
}
|
||||
|
||||
public void solve(List<Integer> numbers) {
|
||||
int[] num = new int[numbers.size()];
|
||||
for (int i = 0; i < num.length; i++) {
|
||||
num[i] = numbers.get(i);
|
||||
}
|
||||
solve(num);
|
||||
}
|
||||
}
|
||||
@ -1,53 +0,0 @@
|
||||
package com.stardust.mi666.ocr;
|
||||
|
||||
import android.graphics.Color;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/23.
|
||||
*/
|
||||
|
||||
public interface ColorDetector {
|
||||
|
||||
boolean isCharPixel(int color);
|
||||
|
||||
class ColorDistanceDetector implements ColorDetector {
|
||||
|
||||
private int mColor;
|
||||
private double mThreshold;
|
||||
|
||||
public ColorDistanceDetector(int color, double threshold) {
|
||||
mColor = color;
|
||||
mThreshold = threshold;
|
||||
}
|
||||
|
||||
public static double distance(int c1, int c2) {
|
||||
double meanR = (Color.red(c1) + Color.red(c2)) / 2;
|
||||
int r = Color.red(c1) - Color.red(c2);
|
||||
int g = Color.green(c1) - Color.green(c2);
|
||||
int b = Color.blue(c1) - Color.blue(c2);
|
||||
double weightR = 2 + meanR / 256;
|
||||
double weightG = 4.0;
|
||||
double weightB = 2 + (255 - meanR) / 256;
|
||||
return Math.sqrt(weightR * r * r + weightG * g * g + weightB * b * b);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCharPixel(int color) {
|
||||
return distance(color, mColor) < mThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleColorDetector implements ColorDetector {
|
||||
|
||||
private int mColor;
|
||||
|
||||
public SimpleColorDetector(int color) {
|
||||
mColor = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCharPixel(int color) {
|
||||
return mColor == color;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,15 +0,0 @@
|
||||
package com.stardust.mi666.ocr;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/23.
|
||||
*/
|
||||
|
||||
public interface OCR {
|
||||
|
||||
void addChar(char ch, Bitmap bitmap);
|
||||
|
||||
char detect(Bitmap bitmap);
|
||||
|
||||
}
|
||||
@ -1,142 +0,0 @@
|
||||
package com.stardust.mi666.ocr;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/23.
|
||||
*/
|
||||
|
||||
public class SimpleOCR implements OCR {
|
||||
|
||||
private static class PixelLine {
|
||||
int start;
|
||||
int end;
|
||||
|
||||
PixelLine(int start, int end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PixelLines {
|
||||
int start = -1;
|
||||
List<PixelLine> lines = new ArrayList<>();
|
||||
|
||||
|
||||
void addLine(PixelLine line) {
|
||||
lines.add(line);
|
||||
if (start == -1 || start > line.start) {
|
||||
start = line.start;
|
||||
}
|
||||
}
|
||||
|
||||
int distanceTo(PixelLines another) {
|
||||
if (lines.size() != another.lines.size()) {
|
||||
return lineWidthSum() + another.lineWidthSum();
|
||||
}
|
||||
int offset = another.start - start;
|
||||
int sum = 0;
|
||||
for (int i = 0; i < lines.size(); i++) {
|
||||
sum += Math.abs(lines.get(i).start + offset - another.lines.get(i).start);
|
||||
sum += Math.abs(lines.get(i).end + offset - another.lines.get(i).end);
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
private int lineWidthSum() {
|
||||
int sum = 0;
|
||||
for (PixelLine line : lines) {
|
||||
sum += line.end - line.start;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class CharFeature {
|
||||
|
||||
private List<PixelLines> mPixelLinesPerRow;
|
||||
|
||||
public CharFeature(int rowNumber) {
|
||||
mPixelLinesPerRow = new ArrayList<>(rowNumber);
|
||||
for (int i = 0; i < rowNumber; i++) {
|
||||
mPixelLinesPerRow.add(new PixelLines());
|
||||
}
|
||||
}
|
||||
|
||||
void addLine(int row, PixelLine line) {
|
||||
mPixelLinesPerRow.get(row).addLine(line);
|
||||
}
|
||||
|
||||
int distanceTo(CharFeature feature) {
|
||||
int sum = 0;
|
||||
if (feature.mPixelLinesPerRow.size() != mPixelLinesPerRow.size()) {
|
||||
for (PixelLines lines : mPixelLinesPerRow) {
|
||||
sum += lines.lines.size();
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
for (int i = 0; i < mPixelLinesPerRow.size(); i++) {
|
||||
sum += mPixelLinesPerRow.get(i).distanceTo(feature.mPixelLinesPerRow.get(i));
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static final String TAG = "SimpleOCR";
|
||||
private Map<Character, CharFeature> mChars = new HashMap<>();
|
||||
private ColorDetector mColorDetector;
|
||||
|
||||
public SimpleOCR(ColorDetector colorDetector) {
|
||||
mColorDetector = colorDetector;
|
||||
}
|
||||
|
||||
public void addChar(char c, Bitmap ch) {
|
||||
mChars.put(c, getCharFeature(ch));
|
||||
}
|
||||
|
||||
public CharFeature getCharFeature(Bitmap bitmap) {
|
||||
CharFeature feature = new CharFeature(bitmap.getHeight());
|
||||
for (int y = 0; y < bitmap.getHeight(); y++) {
|
||||
int mPixelStart = -1;
|
||||
for (int x = 0; x < bitmap.getWidth(); x++) {
|
||||
if (mColorDetector.isCharPixel(bitmap.getPixel(x, y))) {
|
||||
if (mPixelStart == -1) {
|
||||
mPixelStart = x;
|
||||
}
|
||||
} else if (mPixelStart >= 0) {
|
||||
feature.addLine(y, new PixelLine(mPixelStart, x));
|
||||
mPixelStart = -1;
|
||||
}
|
||||
}
|
||||
if (mPixelStart >= 0) {
|
||||
feature.addLine(y, new PixelLine(mPixelStart, bitmap.getWidth()));
|
||||
}
|
||||
}
|
||||
return feature;
|
||||
}
|
||||
|
||||
public char detect(Bitmap bitmap) {
|
||||
CharFeature feature = getCharFeature(bitmap);
|
||||
int min = Integer.MAX_VALUE;
|
||||
char detectedChar = ' ';
|
||||
for (Map.Entry<Character, CharFeature> ch : mChars.entrySet()) {
|
||||
int distance = ch.getValue().distanceTo(feature);
|
||||
Log.d(TAG, "ch=" + ch.getKey() + " distance=" + distance);
|
||||
if (distance < min) {
|
||||
min = distance;
|
||||
detectedChar = ch.getKey();
|
||||
}
|
||||
}
|
||||
return detectedChar;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
package com.stardust.mi666.ocr;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/23.
|
||||
*/
|
||||
|
||||
public class SimpleTextDetector {
|
||||
|
||||
private ColorDetector mColorDetector;
|
||||
|
||||
public SimpleTextDetector(ColorDetector colorDetector) {
|
||||
mColorDetector = colorDetector;
|
||||
}
|
||||
|
||||
public Bitmap detect(Bitmap bitmap) {
|
||||
int minX = bitmap.getWidth();
|
||||
int minY = bitmap.getHeight();
|
||||
int maxX = 0;
|
||||
int maxY = 0;
|
||||
for (int i = 0; i < bitmap.getWidth(); i++) {
|
||||
for (int j = 0; j < bitmap.getHeight(); j++) {
|
||||
if (mColorDetector.isCharPixel(bitmap.getPixel(i, j))) {
|
||||
minX = Math.min(minX, i);
|
||||
minY = Math.min(minY, j);
|
||||
maxX = Math.max(maxX, i);
|
||||
maxY = Math.max(maxY, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
return Bitmap.createBitmap(bitmap, minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
}
|
||||
@ -1,52 +0,0 @@
|
||||
package com.stardust.mi666.ocr;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/24.
|
||||
*/
|
||||
|
||||
public class SimpleTextSplitter {
|
||||
|
||||
private ColorDetector mColorDetector;
|
||||
private SimpleTextDetector mSimpleTextDetector;
|
||||
|
||||
public SimpleTextSplitter(ColorDetector colorDetector) {
|
||||
mColorDetector = colorDetector;
|
||||
mSimpleTextDetector = new SimpleTextDetector(colorDetector);
|
||||
}
|
||||
|
||||
public List<Bitmap> split(Bitmap bitmap) {
|
||||
Bitmap text = mSimpleTextDetector.detect(bitmap);
|
||||
int[] projection = new int[text.getWidth()];
|
||||
for (int i = 0; i < text.getWidth(); i++) {
|
||||
for (int j = 0; j < text.getHeight(); j++) {
|
||||
if (mColorDetector.isCharPixel(text.getPixel(i, j))) {
|
||||
projection[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
int start = -1;
|
||||
List<Bitmap> numbers = new ArrayList<>();
|
||||
for (int i = 0; i < text.getWidth(); i++) {
|
||||
if (projection[i] > 0) {
|
||||
if (start == -1) {
|
||||
start = i;
|
||||
}
|
||||
} else {
|
||||
if (start >= 0) {
|
||||
numbers.add(Bitmap.createBitmap(text, start, 0, i - start, text.getHeight()));
|
||||
start = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (start >= 0) {
|
||||
numbers.add(Bitmap.createBitmap(text, start, 0, text.getWidth() - start, text.getHeight()));
|
||||
}
|
||||
return numbers;
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,109 +0,0 @@
|
||||
package com.stardust.mi666.ocr;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.Log;
|
||||
|
||||
import com.stardust.scriptdroid.tool.BitmapTool;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/23.
|
||||
*/
|
||||
|
||||
public class TemplateMatching {
|
||||
|
||||
private static final String LOG_TAG = "TemplateMatching";
|
||||
|
||||
private int mBlockSize;
|
||||
private ColorDetector mColorDetector;
|
||||
|
||||
|
||||
public TemplateMatching(int blockSize, ColorDetector colorDetector) {
|
||||
mBlockSize = blockSize;
|
||||
mColorDetector = colorDetector;
|
||||
}
|
||||
|
||||
public int[][] getFeature(Bitmap bitmap) {
|
||||
int w = bitmap.getWidth() / mBlockSize;
|
||||
int h = bitmap.getHeight() / mBlockSize;
|
||||
int[][] mat = new int[w][h];
|
||||
for (int i = 0; i < bitmap.getWidth(); i++) {
|
||||
for (int j = 0; j < bitmap.getHeight(); j++) {
|
||||
if (mColorDetector.isCharPixel(bitmap.getPixel(i, j))) {
|
||||
mat[i * w / bitmap.getWidth()][j * h / bitmap.getHeight()]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return mat;
|
||||
}
|
||||
|
||||
public int distance(int[][] f, int[][] template, int offsetX, int offsetY) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < template.length; i++) {
|
||||
for (int j = 0; j < template[i].length; j++) {
|
||||
if (i >= f.length || j >= f[i].length) {
|
||||
sum += template[i].length - j;
|
||||
break;
|
||||
}
|
||||
sum += Math.abs(template[i][j] - f[i + offsetX][j + offsetY]);
|
||||
|
||||
}
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
public int minDistance(int[][] f, int[][] template) {
|
||||
int min = Integer.MAX_VALUE;
|
||||
int i = 0;
|
||||
while (i < template.length && i + template.length - 1 < f.length) {
|
||||
int j = 0;
|
||||
while (j < template[i].length && j + template[i].length - 1 < f[i].length) {
|
||||
int d = distance(f, template, i, j);
|
||||
if (d < min) {
|
||||
min = d;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
public static class TemplateMatchingOCR implements OCR {
|
||||
|
||||
private Map<Character, int[][]> mChars = new HashMap<>();
|
||||
private TemplateMatching mTemplateMatching;
|
||||
private SimpleTextDetector mSimpleTextDetector;
|
||||
|
||||
public TemplateMatchingOCR(int blockSize, ColorDetector colorDetector) {
|
||||
mTemplateMatching = new TemplateMatching(blockSize, colorDetector);
|
||||
mSimpleTextDetector = new SimpleTextDetector(colorDetector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChar(char ch, Bitmap bitmap) {
|
||||
mChars.put(ch, mTemplateMatching.getFeature(mSimpleTextDetector.detect(bitmap)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public char detect(Bitmap bitmap) {
|
||||
int min = Integer.MAX_VALUE;
|
||||
char ch = ' ';
|
||||
for (Map.Entry<Character, int[][]> entry : mChars.entrySet()) {
|
||||
int[][] f = mTemplateMatching.getFeature(BitmapTool.scaleBitmap(bitmap, entry.getValue().length, entry.getValue()[0].length));
|
||||
int d = mTemplateMatching.distance(f, entry.getValue(), 0, 0);
|
||||
Log.d(LOG_TAG, "char: " + entry.getKey() + " distance: " + d);
|
||||
if (d < min) {
|
||||
if (entry.getKey() == '1' && d > 30) {
|
||||
continue;
|
||||
}
|
||||
min = d;
|
||||
ch = entry.getKey();
|
||||
}
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,14 @@
|
||||
package com.stardust.scriptdroid;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Keep;
|
||||
import android.support.multidex.MultiDexApplication;
|
||||
|
||||
import com.squareup.leakcanary.LeakCanary;
|
||||
import com.stardust.app.SimpleActivityLifecycleCallbacks;
|
||||
import com.stardust.app.VolumeChangeObserver;
|
||||
import com.stardust.mi666.OCR;
|
||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
|
||||
import com.stardust.scriptdroid.tool.CrashHandler;
|
||||
@ -26,7 +24,7 @@ import java.lang.ref.WeakReference;
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
|
||||
public class App extends Application {
|
||||
public class App extends MultiDexApplication {
|
||||
|
||||
private static final String TAG = "App";
|
||||
|
||||
@ -65,7 +63,6 @@ public class App extends Application {
|
||||
JsBeautifierFactory.initJsBeautify(this, "js/jsbeautify.js");
|
||||
initVolumeChangeObserver();
|
||||
startService(new Intent(this, AccessibilityWatchDogService.class));
|
||||
OCR.init(this);
|
||||
}
|
||||
|
||||
private void initVolumeChangeObserver() {
|
||||
@ -94,7 +91,6 @@ public class App extends Application {
|
||||
currentActivity = new WeakReference<>(activity);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@ import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
|
||||
import com.stardust.autojs.runtime.api.AutomatorConfig;
|
||||
import com.stardust.automator.AccessibilityEventCommandHost;
|
||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
|
||||
@ -18,11 +19,19 @@ public class Pref {
|
||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
||||
if (key.equals(getString(R.string.key_run_mode))) {
|
||||
AutoJs.getInstance().getCommandHost().setRunMode(getRunModeFromValue(sharedPreferences.getString(key, null)));
|
||||
} else if (key.equals(getString(R.string.key_guard_mode))) {
|
||||
AutomatorConfig.setIsUnintendedGuardEnabled(sharedPreferences.getBoolean(getString(R.string.key_guard_mode), false));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static {
|
||||
AutomatorConfig.setIsUnintendedGuardEnabled(def().getBoolean(getString(R.string.key_guard_mode), false));
|
||||
}
|
||||
|
||||
private static int getRunModeFromValue(String value) {
|
||||
if (value == null)
|
||||
return AccessibilityEventCommandHost.RUN_MODE_THREAD_POOL;
|
||||
switch (value) {
|
||||
case "KEY_THREAD_POOL":
|
||||
return AccessibilityEventCommandHost.RUN_MODE_THREAD_POOL;
|
||||
|
||||
@ -15,7 +15,6 @@ import com.stardust.scriptdroid.scripts.ScriptFile;
|
||||
import com.stardust.scriptdroid.scripts.StorageScriptProvider;
|
||||
import com.stardust.scriptdroid.ui.edit.EditActivity;
|
||||
import com.stardust.scriptdroid.ui.main.script_list.ScriptAndFolderListRecyclerView;
|
||||
import com.stardust.scriptdroid.ui.main.script_list.ScriptListRecyclerView;
|
||||
import com.stardust.scriptdroid.ui.main.script_list.ScriptListWithProgressBarView;
|
||||
import com.stardust.util.MessageEvent;
|
||||
import com.stardust.widget.ViewHolderSupplier;
|
||||
|
||||
@ -37,7 +37,6 @@ public class FloatingLayoutBoundsView extends LayoutBoundsView {
|
||||
showNodeInfo(info);
|
||||
}
|
||||
});
|
||||
setBackgroundColor(0x66000000);
|
||||
setVisibility(GONE);
|
||||
getPaint().setColor(0xFF222222);
|
||||
getPaint().setStrokeWidth(2f);
|
||||
|
||||
@ -1,205 +0,0 @@
|
||||
package com.stardust.scriptdroid.external.floating_window.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.workground.WrapContentLinearLayoutManager;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.scriptdroid.scripts.ScriptFile;
|
||||
import com.stardust.scriptdroid.scripts.ScriptFileList;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.external.floating_window.HoverMenuService;
|
||||
import com.stardust.util.ViewUtil;
|
||||
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
|
||||
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperationPopupMenu;
|
||||
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import com.stardust.util.MessageEvent;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/12.
|
||||
*/
|
||||
|
||||
public class FloatingScriptFileListView extends RecyclerView {
|
||||
|
||||
|
||||
private ScriptFileList mScriptFileList;
|
||||
|
||||
private final OnClickListener mOnItemClickListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int position = getChildViewHolder(v).getAdapterPosition();
|
||||
onItemClicked(v, position);
|
||||
}
|
||||
};
|
||||
|
||||
private final OnClickListener mOnEditIconClickListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int position = getChildViewHolder((View) v.getParent()).getAdapterPosition();
|
||||
onEditIconClick(v, position);
|
||||
}
|
||||
};
|
||||
|
||||
private final OnClickListener mOnMoreIconClickListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
mOperateFileIndex = getChildViewHolder((View) v.getParent()).getAdapterPosition();
|
||||
showOrDismissOperationPopupMenu(v);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
private ScriptFileOperationPopupMenu mScriptFileOperationPopupMenu;
|
||||
private int mOperateFileIndex;
|
||||
|
||||
public FloatingScriptFileListView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setAdapter(new Adapter());
|
||||
setLayoutManager(new WrapContentLinearLayoutManager(getContext()));
|
||||
addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
|
||||
initScriptFileOperationPopupMenu();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void showMessage(ScriptFileOperation.ShowMessageEvent event) {
|
||||
Toast.makeText(getContext(), event.messageResId, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private void initScriptFileOperationPopupMenu() {
|
||||
mScriptFileOperationPopupMenu = new ScriptFileOperationPopupMenu(getContext(), getScriptFileOperations());
|
||||
mScriptFileOperationPopupMenu.setOnItemClickListener(new ScriptFileOperationPopupMenu.OnItemClickListener() {
|
||||
@Override
|
||||
public void onClick(View view, int position, ScriptFileOperation operation) {
|
||||
operation.operate(FloatingScriptFileListView.this, mScriptFileList, mOperateFileIndex);
|
||||
mScriptFileOperationPopupMenu.dismiss();
|
||||
if (!(operation instanceof ScriptFileOperation.Rename))
|
||||
EventBus.getDefault().post(new MessageEvent(HoverMenuService.MESSAGE_COLLAPSE_MENU));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected List<ScriptFileOperation> getScriptFileOperations() {
|
||||
List<ScriptFileOperation> scriptFileOperations = new ArrayList<>();
|
||||
scriptFileOperations.add(new ScriptFileOperation.Run());
|
||||
scriptFileOperations.add(new ScriptFileOperation.Rename() {
|
||||
@Override
|
||||
public void operate(final RecyclerView recyclerView, final ScriptFileList scriptFileList, final int position) {
|
||||
String oldName = scriptFileList.get(position).getSimplifiedName();
|
||||
MaterialDialog dialog = new ThemeColorMaterialDialogBuilder(recyclerView.getContext())
|
||||
.title(R.string.text_rename)
|
||||
.checkBoxPrompt(App.getApp().getString(R.string.text_rename_file_meanwhile), false, null)
|
||||
.input(App.getApp().getString(R.string.text_please_input_new_name), oldName, new MaterialDialog.InputCallback() {
|
||||
@Override
|
||||
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
|
||||
scriptFileList.rename(position, input.toString(), dialog.isPromptCheckBoxChecked());
|
||||
recyclerView.getAdapter().notifyItemChanged(position);
|
||||
}
|
||||
})
|
||||
.build();
|
||||
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||
dialog.show();
|
||||
}
|
||||
});
|
||||
scriptFileOperations.add(new ScriptFileOperation.OpenByOtherApp());
|
||||
scriptFileOperations.add(new ScriptFileOperation.CreateShortcut());
|
||||
scriptFileOperations.add(new ScriptFileOperation.Remove());
|
||||
scriptFileOperations.add(new ScriptFileOperation.Delete());
|
||||
return scriptFileOperations;
|
||||
}
|
||||
|
||||
protected void onItemClicked(View v, int position) {
|
||||
new ScriptFileOperation.Run().operate(this, mScriptFileList, position);
|
||||
EventBus.getDefault().post(new MessageEvent(HoverMenuService.MESSAGE_COLLAPSE_MENU));
|
||||
}
|
||||
|
||||
protected void onEditIconClick(View v, int position) {
|
||||
new ScriptFileOperation.Edit().operate(this, mScriptFileList, position);
|
||||
EventBus.getDefault().post(new MessageEvent(HoverMenuService.MESSAGE_COLLAPSE_MENU));
|
||||
}
|
||||
|
||||
public void setScriptFileList(ScriptFileList scriptFileList) {
|
||||
mScriptFileList = scriptFileList;
|
||||
getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private void showOrDismissOperationPopupMenu(View v) {
|
||||
if (mScriptFileOperationPopupMenu.isShowing()) {
|
||||
mScriptFileOperationPopupMenu.dismiss();
|
||||
} else {
|
||||
mScriptFileOperationPopupMenu.show(v);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
EventBus.getDefault().register(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
EventBus.getDefault().unregister(this);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuCollapsing(MessageEvent event) {
|
||||
if (event.message.equals(HoverMenuService.MESSAGE_MENU_COLLAPSING) && mScriptFileOperationPopupMenu.isShowing()) {
|
||||
mScriptFileOperationPopupMenu.dismiss();
|
||||
}
|
||||
}
|
||||
|
||||
private class Adapter extends RecyclerView.Adapter<ViewHolder> {
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View itemView = LayoutInflater.from(getContext()).inflate(R.layout.floating_script_list_recycler_view_file, parent, false);
|
||||
return new ViewHolder(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
ScriptFile scriptFile = mScriptFileList.get(position);
|
||||
holder.name.setText(scriptFile.getSimplifiedName());
|
||||
holder.path.setText(scriptFile.getSimplifiedPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mScriptFileList.size();
|
||||
}
|
||||
}
|
||||
|
||||
private class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
TextView name, path;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
name = (TextView) itemView.findViewById(R.id.name);
|
||||
path = (TextView) itemView.findViewById(R.id.path);
|
||||
ViewUtil.$(itemView, R.id.edit).setOnClickListener(mOnEditIconClickListener);
|
||||
//ViewUtil.$(itemView, R.id.more).setOnClickListener(mOnMoreIconClickListener);
|
||||
itemView.setOnClickListener(mOnItemClickListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -20,7 +20,7 @@ public class ImportIntentActivity extends BaseActivity {
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
try {
|
||||
handleIntent();
|
||||
handleIntent(getIntent());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(this, R.string.edit_and_run_handle_intent_error, Toast.LENGTH_LONG).show();
|
||||
@ -28,8 +28,12 @@ public class ImportIntentActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleIntent() {
|
||||
Intent intent = getIntent();
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
handleIntent(intent);
|
||||
}
|
||||
|
||||
private void handleIntent(Intent intent) {
|
||||
final String path = intent.getData().getPath();
|
||||
if (!TextUtils.isEmpty(path))
|
||||
MainActivity.importScriptFile(this, path);
|
||||
|
||||
@ -15,6 +15,9 @@ import android.view.View;
|
||||
import com.stardust.scriptdroid.layout_inspector.NodeInfo;
|
||||
import com.stardust.util.ViewUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/10.
|
||||
*/
|
||||
@ -109,13 +112,20 @@ public class LayoutBoundsView extends View {
|
||||
}
|
||||
}
|
||||
|
||||
private NodeInfo findNodeAt(NodeInfo node, int x, int y) {
|
||||
private List<NodeInfo> findNodeAt(NodeInfo node, int x, int y) {
|
||||
List<NodeInfo> list = null;
|
||||
for (NodeInfo child : node.getChildren()) {
|
||||
if (child != null && child.getBoundsInScreen().contains(x, y)) {
|
||||
return findNodeAt(child, x, y);
|
||||
if (list == null)
|
||||
list = findNodeAt(child, x, y);
|
||||
else
|
||||
list.addAll(findNodeAt(child, x, y));
|
||||
}
|
||||
}
|
||||
return node;
|
||||
if (list == null)
|
||||
list = new ArrayList<>();
|
||||
list.add(node);
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,10 +1,12 @@
|
||||
package com.stardust.scriptdroid.scripts.sample;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/3/13.
|
||||
*/
|
||||
|
||||
public class Sample {
|
||||
public class Sample implements Serializable {
|
||||
public String name;
|
||||
public String path;
|
||||
|
||||
@ -12,4 +14,5 @@ public class Sample {
|
||||
this.name = name;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,162 +0,0 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -22,19 +22,15 @@ import timber.log.Timber;
|
||||
public class TimberConsole implements Console {
|
||||
|
||||
static {
|
||||
try {
|
||||
Timber.plant(new ConsoleTree.Builder()
|
||||
.minPriority(Log.VERBOSE)
|
||||
.verboseColor(0xff909090)
|
||||
.debugColor(0xffc88b48)
|
||||
.infoColor(0xffc9c9c9)
|
||||
.warnColor(0xffa97db6)
|
||||
.errorColor(0xffff534e)
|
||||
.assertColor(0xffff5540)
|
||||
.build());
|
||||
} catch (Exception e) {
|
||||
// FIXME: 2017/4/26 java.lang.NoClassDefFoundError: com.jraska.console.timber.ConsoleTree at android4.4
|
||||
}
|
||||
Timber.plant(new ConsoleTree.Builder()
|
||||
.minPriority(Log.VERBOSE)
|
||||
.verboseColor(0xff909090)
|
||||
.debugColor(0xffc88b48)
|
||||
.infoColor(0xffc9c9c9)
|
||||
.warnColor(0xffa97db6)
|
||||
.errorColor(0xffff534e)
|
||||
.assertColor(0xffff5540)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
package com.stardust.scriptdroid.ui.edit;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -14,51 +13,49 @@ import android.util.SparseArray;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethod;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.autojs.engine.JavaScriptEngine;
|
||||
import com.stardust.autojs.ScriptExecutionListener;
|
||||
import com.stardust.autojs.script.FileScriptSource;
|
||||
import com.stardust.autojs.script.JsBeautifier;
|
||||
import com.stardust.autojs.script.ScriptSource;
|
||||
import com.stardust.autojs.script.StringScriptSource;
|
||||
import com.stardust.enhancedfloaty.ResizableFloatyService;
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.scriptdroid.Pref;
|
||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
import com.stardust.scriptdroid.external.floating_window.FloatingConsole;
|
||||
import com.stardust.scriptdroid.scripts.ScriptFile;
|
||||
import com.stardust.scriptdroid.tool.JsBeautifierFactory;
|
||||
import com.stardust.scriptdroid.tool.MaterialDialogFactory;
|
||||
import com.stardust.scriptdroid.ui.BaseActivity;
|
||||
import com.stardust.scriptdroid.ui.console.ConsoleActivity;
|
||||
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Activity;
|
||||
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Utils;
|
||||
import com.stardust.scriptdroid.ui.edit.sidemenu.EditSideMenuFragment;
|
||||
import com.stardust.scriptdroid.ui.edit.sidemenu.FunctionListRecyclerView;
|
||||
import com.stardust.scriptdroid.ui.help.HelpCatalogueActivity;
|
||||
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import com.stardust.util.SparseArrayEntries;
|
||||
import com.stardust.view.ViewBinding;
|
||||
import com.stardust.widget.ToolbarMenuItem;
|
||||
import com.jecelyin.editor.v2.common.Command;
|
||||
import com.jecelyin.editor.v2.common.SaveListener;
|
||||
import com.jecelyin.editor.v2.core.widget.TextView;
|
||||
import com.jecelyin.editor.v2.ui.EditorDelegate;
|
||||
import com.jecelyin.editor.v2.view.EditorView;
|
||||
import com.jecelyin.editor.v2.view.menu.MenuDef;
|
||||
import com.stardust.autojs.ScriptExecutionListener;
|
||||
import com.stardust.autojs.engine.JavaScriptEngine;
|
||||
import com.stardust.autojs.script.FileScriptSource;
|
||||
import com.stardust.autojs.script.JsBeautifier;
|
||||
import com.stardust.autojs.script.ScriptSource;
|
||||
import com.stardust.autojs.script.StringScriptSource;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.Pref;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
import com.stardust.scriptdroid.scripts.ScriptFile;
|
||||
import com.stardust.scriptdroid.tool.JsBeautifierFactory;
|
||||
import com.stardust.scriptdroid.tool.MaterialDialogFactory;
|
||||
import com.stardust.scriptdroid.ui.BaseActivity;
|
||||
import com.stardust.scriptdroid.ui.console.ConsoleActivity;
|
||||
import com.stardust.scriptdroid.ui.edit.completion.InputMethodEnhanceBar;
|
||||
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Activity;
|
||||
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Utils;
|
||||
import com.stardust.scriptdroid.ui.help.HelpCatalogueActivity;
|
||||
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
|
||||
import com.stardust.theme.ThemeColorManager;
|
||||
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import com.stardust.util.SparseArrayEntries;
|
||||
import com.stardust.view.ViewBinder;
|
||||
import com.stardust.view.ViewBinding;
|
||||
import com.stardust.widget.ToolbarMenuItem;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import static com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation.ACTION_ON_RUN_FINISHED;
|
||||
import static com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation.EXTRA_EXCEPTION_MESSAGE;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/29.
|
||||
*/
|
||||
@ -94,43 +91,10 @@ public class EditActivity extends Editor920Activity {
|
||||
|
||||
public static final String EXTRA_CONTENT = "Still Love Eating 17.4.5";
|
||||
|
||||
private static final String ACTION_ON_RUN_FINISHED = "ACTION_ON_RUN_FINISHED";
|
||||
private static final String EXTRA_EXCEPTION_MESSAGE = "EXTRA_EXCEPTION_MESSAGE";
|
||||
|
||||
|
||||
private static final ScriptExecutionListener SCRIPT_EXECUTION_LISTENER = new ScriptExecutionListener() {
|
||||
|
||||
@Override
|
||||
public void onStart(JavaScriptEngine engine, ScriptSource source) {
|
||||
AutoJs.getInstance().getScriptEngineService().getDefaultListener().onStart(engine, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(JavaScriptEngine engine, ScriptSource source, Object result) {
|
||||
App.getApp().sendBroadcast(new Intent(ACTION_ON_RUN_FINISHED));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(JavaScriptEngine engine, ScriptSource source, Exception e) {
|
||||
App.getApp().sendBroadcast(new Intent(ACTION_ON_RUN_FINISHED)
|
||||
.putExtra(EXTRA_EXCEPTION_MESSAGE, e.getMessage()));
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public static void editFile(Context context, String path) {
|
||||
editFile(context, null, path);
|
||||
}
|
||||
|
||||
public static void view(Context context, String name, String content) {
|
||||
context.startActivity(new Intent(context, EditActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.putExtra("readOnly", true)
|
||||
.putExtra("content", content)
|
||||
.putExtra("name", name));
|
||||
}
|
||||
|
||||
public static void editFile(Context context, String name, String path) {
|
||||
context.startActivity(new Intent(context, EditActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
@ -145,7 +109,6 @@ public class EditActivity extends Editor920Activity {
|
||||
private String mName;
|
||||
private File mFile;
|
||||
private View mView;
|
||||
private DrawerLayout mDrawerLayout;
|
||||
private EditorDelegate mEditorDelegate;
|
||||
private SparseArray<ToolbarMenuItem> mMenuMap;
|
||||
private boolean mReadOnly = false;
|
||||
@ -175,23 +138,6 @@ public class EditActivity extends Editor920Activity {
|
||||
registerReceiver(mOnRunFinishedReceiver, new IntentFilter(ACTION_ON_RUN_FINISHED));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
openDrawerIfFirstUse();
|
||||
}
|
||||
|
||||
private void openDrawerIfFirstUse() {
|
||||
if (Pref.isEditActivityFirstUsing()) {
|
||||
mDrawerLayout.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mDrawerLayout.openDrawer(GravityCompat.END);
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleIntent(Intent intent) {
|
||||
String path = intent.getStringExtra("path");
|
||||
mName = intent.getStringExtra("name");
|
||||
@ -214,25 +160,11 @@ public class EditActivity extends Editor920Activity {
|
||||
|
||||
private void setUpUI() {
|
||||
ThemeColorManager.addActivityStatusBar(this);
|
||||
mDrawerLayout = (DrawerLayout) mView.findViewById(R.id.drawer_layout);
|
||||
initSideMenuFragment();
|
||||
setUpToolbar();
|
||||
initMenuItem();
|
||||
ViewBinder.bind(this);
|
||||
}
|
||||
|
||||
private void initSideMenuFragment() {
|
||||
EditSideMenuFragment.setFragment(EditActivity.this, R.id.fragment_edit_side_menu)
|
||||
.setOnFunctionClickListener(new FunctionListRecyclerView.OnFunctionClickListener() {
|
||||
@Override
|
||||
public void onClick(FunctionListRecyclerView.Function function, int position) {
|
||||
if (!mReadOnly)
|
||||
insertText(function.name);
|
||||
mDrawerLayout.closeDrawer(GravityCompat.END);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setUpEditor() {
|
||||
final EditorView editorView = (EditorView) findViewById(R.id.editor);
|
||||
mEditorDelegate.setEditorView(editorView);
|
||||
@ -284,9 +216,9 @@ public class EditActivity extends Editor920Activity {
|
||||
Snackbar.make(mView, R.string.text_start_running, Snackbar.LENGTH_SHORT).show();
|
||||
setMenuStatus(R.id.run, MenuDef.STATUS_DISABLED);
|
||||
if (mFile != null) {
|
||||
AutoJs.getInstance().getScriptEngineService().execute(new FileScriptSource(mName, mFile), SCRIPT_EXECUTION_LISTENER);
|
||||
ScriptFileOperation.runOnEditView(new FileScriptSource(mName, mFile));
|
||||
} else {
|
||||
AutoJs.getInstance().getScriptEngineService().execute(new StringScriptSource(mName, mEditorDelegate.getText()), SCRIPT_EXECUTION_LISTENER);
|
||||
ScriptFileOperation.runOnEditView(new StringScriptSource(mName, mEditorDelegate.getText()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,11 +276,19 @@ public class EditActivity extends Editor920Activity {
|
||||
case R.id.action_beautify:
|
||||
beautifyCode();
|
||||
return true;
|
||||
|
||||
case R.id.action_open_by_other_apps:
|
||||
openByOtherApps();
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void openByOtherApps() {
|
||||
if (mFile != null)
|
||||
ScriptFileOperation.openByOtherApps(mFile.getPath());
|
||||
|
||||
}
|
||||
|
||||
private void beautifyCode() {
|
||||
final MaterialDialog dialog = MaterialDialogFactory.showProgress(this);
|
||||
mJsBeautifier.beautify(mEditorDelegate.getText(), new JsBeautifier.Callback() {
|
||||
@ -365,6 +305,7 @@ public class EditActivity extends Editor920Activity {
|
||||
|
||||
@Override
|
||||
public void onException(Exception e) {
|
||||
dialog.dismiss();
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
|
||||
@ -0,0 +1,171 @@
|
||||
package com.stardust.scriptdroid.ui.edit;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.util.SparseArray;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.jecelyin.editor.v2.common.Command;
|
||||
import com.jecelyin.editor.v2.ui.EditorDelegate;
|
||||
import com.jecelyin.editor.v2.view.EditorView;
|
||||
import com.jecelyin.editor.v2.view.menu.MenuDef;
|
||||
import com.stardust.autojs.script.StringScriptSource;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.scripts.sample.Sample;
|
||||
import com.stardust.scriptdroid.ui.BaseActivity;
|
||||
import com.stardust.scriptdroid.ui.console.ConsoleActivity;
|
||||
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Activity;
|
||||
import com.stardust.scriptdroid.ui.edit.editor920.Editor920Utils;
|
||||
import com.stardust.scriptdroid.ui.help.HelpCatalogueActivity;
|
||||
import com.stardust.scriptdroid.ui.main.MainActivity;
|
||||
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
|
||||
import com.stardust.theme.ThemeColorManager;
|
||||
import com.stardust.util.AssetsCache;
|
||||
import com.stardust.util.SparseArrayEntries;
|
||||
import com.stardust.view.ViewBinder;
|
||||
import com.stardust.view.ViewBinding;
|
||||
import com.stardust.widget.ToolbarMenuItem;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import static com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation.ACTION_ON_RUN_FINISHED;
|
||||
import static com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation.EXTRA_EXCEPTION_MESSAGE;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/29.
|
||||
*/
|
||||
|
||||
public class ViewSampleActivity extends Editor920Activity {
|
||||
|
||||
public static void view(Context context, Sample sample) {
|
||||
context.startActivity(new Intent(context, ViewSampleActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
.putExtra("sample", sample));
|
||||
}
|
||||
|
||||
private View mView;
|
||||
private Sample mSample;
|
||||
private EditorDelegate mEditorDelegate;
|
||||
private SparseArray<ToolbarMenuItem> mMenuMap;
|
||||
private BroadcastReceiver mOnRunFinishedReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(ACTION_ON_RUN_FINISHED)) {
|
||||
setMenuStatus(R.id.run, MenuDef.STATUS_NORMAL);
|
||||
String msg = intent.getStringExtra(EXTRA_EXCEPTION_MESSAGE);
|
||||
if (msg != null) {
|
||||
Snackbar.make(mView, getString(R.string.text_error) + ": " + msg, Snackbar.LENGTH_LONG).show();
|
||||
Timber.e(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public void onCreate(Bundle b) {
|
||||
super.onCreate(b);
|
||||
setTheme(R.style.EditorTheme);
|
||||
mView = View.inflate(this, R.layout.activity_view_sample, null);
|
||||
setContentView(mView);
|
||||
handleIntent(getIntent());
|
||||
setUpUI();
|
||||
setUpEditor();
|
||||
registerReceiver(mOnRunFinishedReceiver, new IntentFilter(ACTION_ON_RUN_FINISHED));
|
||||
}
|
||||
|
||||
private void handleIntent(Intent intent) {
|
||||
mSample = (Sample) intent.getSerializableExtra("sample");
|
||||
String content = AssetsCache.get(this, mSample.path);
|
||||
mEditorDelegate = new EditorDelegate(0, mSample.name, content);
|
||||
}
|
||||
|
||||
private void setUpUI() {
|
||||
ThemeColorManager.addActivityStatusBar(this);
|
||||
setUpToolbar();
|
||||
initMenuItem();
|
||||
ViewBinder.bind(this);
|
||||
}
|
||||
|
||||
private void setUpEditor() {
|
||||
final EditorView editorView = (EditorView) findViewById(R.id.editor);
|
||||
mEditorDelegate.setEditorView(editorView);
|
||||
Editor920Utils.setLang(mEditorDelegate, "JavaScript");
|
||||
editorView.getEditText().setReadOnly(true);
|
||||
editorView.getEditText().setHorizontallyScrolling(true);
|
||||
}
|
||||
|
||||
private void setUpToolbar() {
|
||||
BaseActivity.setToolbarAsBack(this, R.id.toolbar, mSample.name);
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.run)
|
||||
private void run() {
|
||||
Snackbar.make(mView, R.string.text_start_running, Snackbar.LENGTH_SHORT).show();
|
||||
setMenuStatus(R.id.run, MenuDef.STATUS_DISABLED);
|
||||
ScriptFileOperation.runOnEditView(new StringScriptSource(mSample.name, mEditorDelegate.getText()));
|
||||
}
|
||||
|
||||
private void initMenuItem() {
|
||||
mMenuMap = new SparseArrayEntries<ToolbarMenuItem>()
|
||||
.entry(R.id.run, (ToolbarMenuItem) findViewById(R.id.run))
|
||||
.sparseArray();
|
||||
}
|
||||
|
||||
public void setMenuStatus(int menuResId, int status) {
|
||||
ToolbarMenuItem menuItem = mMenuMap.get(menuResId);
|
||||
if (menuItem == null)
|
||||
return;
|
||||
boolean disabled = status == MenuDef.STATUS_DISABLED;
|
||||
menuItem.setEnabled(!disabled);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_view_sample, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_console:
|
||||
startActivity(new Intent(getContext(), ConsoleActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
return true;
|
||||
case R.id.action_help:
|
||||
HelpCatalogueActivity.showMainCatalogue(this);
|
||||
return true;
|
||||
case R.id.action_import:
|
||||
MainActivity.importSample(this, mSample);
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(Command command) {
|
||||
mEditorDelegate.doCommand(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
unregisterReceiver(mOnRunFinishedReceiver);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||
try {
|
||||
super.onRestoreInstanceState(savedInstanceState);
|
||||
} catch (RuntimeException e) {
|
||||
// FIXME: 2017/3/20
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,7 +9,9 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.design.widget.TabLayout;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
@ -29,6 +31,7 @@ import com.stardust.scriptdroid.BuildConfig;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.scripts.ScriptFile;
|
||||
import com.stardust.scriptdroid.scripts.StorageScriptProvider;
|
||||
import com.stardust.scriptdroid.scripts.sample.Sample;
|
||||
import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
|
||||
import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
|
||||
import com.stardust.scriptdroid.tool.DrawableSaver;
|
||||
@ -50,6 +53,8 @@ import com.stardust.widget.SlidingUpPanel;
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class MainActivity extends BaseActivity {
|
||||
|
||||
@ -61,6 +66,9 @@ public class MainActivity extends BaseActivity {
|
||||
private static final String ACTION_IMPORT_SCRIPT = "ACTION_IMPORT_SCRIPT";
|
||||
private static final String ARGUMENT_SCRIPT = "ARGUMENT_SCRIPT";
|
||||
private static final String ARGUMENT_PATH = "ARGUMENT_PATH";
|
||||
private static final String ACTION_IMPORT_SAMPLE = "I cannot find the way back to you...Eating...17.4.29";
|
||||
private static final String ARGUMENT_SAMPLE = "Take a chance on me...ok...?";
|
||||
|
||||
|
||||
private DrawerLayout mDrawerLayout;
|
||||
@ViewBinding.Id(R.id.bottom_menu)
|
||||
@ -70,6 +78,7 @@ public class MainActivity extends BaseActivity {
|
||||
private OnActivityResultDelegate.Intermediary mActivityResultIntermediary = new OnActivityResultDelegate.Intermediary();
|
||||
private DrawableSaver mDrawerHeaderBackgroundSaver, mAppbarBackgroundSaver;
|
||||
private VersionGuard mVersionGuard;
|
||||
private Intent mIntentToHandle;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
@ -77,13 +86,12 @@ public class MainActivity extends BaseActivity {
|
||||
setUpUI();
|
||||
checkPermissions();
|
||||
registerBackPressHandlers();
|
||||
handleIntent(getIntent());
|
||||
mIntentToHandle = getIntent();
|
||||
EventBus.getDefault().register(this);
|
||||
mVersionGuard = new VersionGuard(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void registerBackPressHandlers() {
|
||||
registerBackPressedHandler(new BackPressedHandler() {
|
||||
@Override
|
||||
@ -164,6 +172,15 @@ public class MainActivity extends BaseActivity {
|
||||
viewPager.setAdapter(mPagerAdapter);
|
||||
viewPager.setOffscreenPageLimit(mPagerAdapter.getCount());
|
||||
tabLayout.setupWithViewPager(viewPager);
|
||||
mPagerAdapter.setOnFragmentInstantiateListener(new FragmentPagerAdapterBuilder.OnFragmentInstantiateListener() {
|
||||
@Override
|
||||
public void OnInstantiate(Fragment fragment) {
|
||||
if (fragment instanceof MyScriptListFragment && mIntentToHandle != null) {
|
||||
handleIntent(mIntentToHandle);
|
||||
mIntentToHandle = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.add)
|
||||
@ -183,13 +200,14 @@ public class MainActivity extends BaseActivity {
|
||||
|
||||
@ViewBinding.Click(R.id.import_from_file)
|
||||
private void showFileChooser() {
|
||||
final StorageScriptProvider provider = StorageScriptProvider.getExternalStorageProvider();
|
||||
new ScriptFileChooserDialogBuilder(this)
|
||||
.scriptProvider(StorageScriptProvider.getExternalStorageProvider())
|
||||
.scriptProvider(provider)
|
||||
.fileCallback(new ScriptFileChooserDialogBuilder.FileCallback() {
|
||||
@Override
|
||||
public void onFileSelection(MaterialDialog dialog, ScriptFile file) {
|
||||
dialog.dismiss();
|
||||
StorageScriptProvider.getExternalStorageProvider().clearCacheExceptInitialDirectory();
|
||||
provider.clearCacheExceptInitialDirectory();
|
||||
getMyScriptListFragment().importFile(file.getPath());
|
||||
}
|
||||
})
|
||||
@ -203,7 +221,7 @@ public class MainActivity extends BaseActivity {
|
||||
if (which == DialogAction.POSITIVE) {
|
||||
dialog.dismiss();
|
||||
} else {
|
||||
StorageScriptProvider.getExternalStorageProvider().refreshAll();
|
||||
provider.refreshAll();
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -225,6 +243,12 @@ public class MainActivity extends BaseActivity {
|
||||
mDrawerHeaderBackgroundSaver.select(this, mActivityResultIntermediary);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mVersionGuard.checkDeprecateAndUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
@ -242,9 +266,22 @@ public class MainActivity extends BaseActivity {
|
||||
case ACTION_IMPORT_SCRIPT:
|
||||
getMyScriptListFragment().importFile(intent.getStringExtra(ARGUMENT_PATH));
|
||||
break;
|
||||
case ACTION_IMPORT_SAMPLE:
|
||||
importSample((Sample) intent.getSerializableExtra(ARGUMENT_SAMPLE));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void importSample(Sample sample) {
|
||||
try {
|
||||
getMyScriptListFragment().importFile(sample.name, getAssets().open(sample.path));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Snackbar.make(mDrawerLayout, R.string.text_import_fail, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void handleRecordedScript(final String script) {
|
||||
new ThemeColorMaterialDialogBuilder(this)
|
||||
.title(R.string.text_recorded)
|
||||
@ -280,6 +317,13 @@ public class MainActivity extends BaseActivity {
|
||||
.putExtra(ARGUMENT_PATH, path));
|
||||
}
|
||||
|
||||
public static void importSample(Context context, Sample sample) {
|
||||
context.startActivity(new Intent(context, MainActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
||||
.putExtra(EXTRA_ACTION, ACTION_IMPORT_SAMPLE)
|
||||
.putExtra(ARGUMENT_SAMPLE, sample));
|
||||
}
|
||||
|
||||
public MyScriptListFragment getMyScriptListFragment() {
|
||||
return ((MyScriptListFragment) mPagerAdapter.getStoredFragment(0));
|
||||
}
|
||||
@ -308,12 +352,6 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mVersionGuard.checkDeprecateAndUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
|
||||
@ -2,23 +2,26 @@ package com.stardust.scriptdroid.ui.main.operation;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.design.widget.Snackbar;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.squareup.haha.perflib.Main;
|
||||
import com.stardust.autojs.ScriptExecutionListener;
|
||||
import com.stardust.autojs.engine.JavaScriptEngine;
|
||||
import com.stardust.autojs.script.FileScriptSource;
|
||||
import com.stardust.autojs.script.ScriptSource;
|
||||
import com.stardust.autojs.script.StringScriptSource;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
import com.stardust.scriptdroid.scripts.ScriptFile;
|
||||
import com.stardust.scriptdroid.scripts.ScriptFileList;
|
||||
import com.stardust.scriptdroid.external.CommonUtils;
|
||||
import com.stardust.scriptdroid.external.shortcut.Shortcut;
|
||||
import com.stardust.scriptdroid.external.shortcut.ShortcutActivity;
|
||||
import com.stardust.scriptdroid.scripts.ScriptFile;
|
||||
import com.stardust.scriptdroid.scripts.sample.Sample;
|
||||
import com.stardust.scriptdroid.ui.edit.EditActivity;
|
||||
import com.stardust.theme.dialog.ThemeColorMaterialDialogBuilder;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.ui.main.MainActivity;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/23.
|
||||
@ -26,17 +29,34 @@ import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
public abstract class ScriptFileOperation {
|
||||
|
||||
public static final String ACTION_ON_RUN_FINISHED = "ACTION_ON_RUN_FINISHED";
|
||||
public static final String EXTRA_EXCEPTION_MESSAGE = "EXTRA_EXCEPTION_MESSAGE";
|
||||
|
||||
public static class ShowMessageEvent {
|
||||
public int messageResId;
|
||||
|
||||
public ShowMessageEvent(int message) {
|
||||
this.messageResId = message;
|
||||
private static final ScriptExecutionListener SCRIPT_EXECUTION_LISTENER = new ScriptExecutionListener() {
|
||||
|
||||
@Override
|
||||
public void onStart(JavaScriptEngine engine, ScriptSource source) {
|
||||
AutoJs.getInstance().getScriptEngineService().getDefaultListener().onStart(engine, source);
|
||||
}
|
||||
}
|
||||
|
||||
public static void openByOtherApps(ScriptFile scriptFile) {
|
||||
Uri uri = Uri.parse("file://" + scriptFile.getPath());
|
||||
@Override
|
||||
public void onSuccess(JavaScriptEngine engine, ScriptSource source, Object result) {
|
||||
App.getApp().sendBroadcast(new Intent(ACTION_ON_RUN_FINISHED));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onException(JavaScriptEngine engine, ScriptSource source, Exception e) {
|
||||
App.getApp().sendBroadcast(new Intent(ACTION_ON_RUN_FINISHED)
|
||||
.putExtra(EXTRA_EXCEPTION_MESSAGE, e.getMessage()));
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
public static void openByOtherApps(String path) {
|
||||
Uri uri = Uri.parse("file://" + path);
|
||||
App.getApp().startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(uri, "text/plain").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
}
|
||||
|
||||
@ -53,149 +73,12 @@ public abstract class ScriptFileOperation {
|
||||
EditActivity.editFile(App.getApp(), file.getSimplifiedName(), file.getPath());
|
||||
}
|
||||
|
||||
|
||||
public abstract void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position);
|
||||
|
||||
private String mName;
|
||||
|
||||
public ScriptFileOperation(String name, int iconResId) {
|
||||
mName = name;
|
||||
mIconResId = iconResId;
|
||||
public static void run(ScriptFile file) {
|
||||
AutoJs.getInstance().getScriptEngineService().execute(new FileScriptSource(file));
|
||||
}
|
||||
|
||||
private int mIconResId;
|
||||
|
||||
public String getName() {
|
||||
return mName;
|
||||
public static void runOnEditView(ScriptSource scriptSource) {
|
||||
AutoJs.getInstance().getScriptEngineService().execute(scriptSource, SCRIPT_EXECUTION_LISTENER);
|
||||
}
|
||||
|
||||
public int getIconResId() {
|
||||
return mIconResId;
|
||||
}
|
||||
|
||||
public static class Run extends ScriptFileOperation {
|
||||
|
||||
public Run() {
|
||||
super(App.getApp().getString(R.string.text_run), R.drawable.ic_play_green);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) {
|
||||
EventBus.getDefault().post(new ShowMessageEvent(R.string.text_start_running));
|
||||
ScriptFile scriptFile = scriptFileList.get(position);
|
||||
AutoJs.getInstance().getScriptEngineService().execute(new FileScriptSource(scriptFile));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Edit extends ScriptFileOperation {
|
||||
|
||||
private static Edit instance = new Edit();
|
||||
|
||||
public Edit() {
|
||||
super(App.getApp().getString(R.string.text_edit), R.drawable.ic_edit_green_48dp);
|
||||
}
|
||||
|
||||
public static Edit getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void setInstance(Edit instance) {
|
||||
Edit.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) {
|
||||
ScriptFile scriptFile = scriptFileList.get(position);
|
||||
EditActivity.editFile(App.getApp(), scriptFile.getSimplifiedName(), scriptFile.getPath());
|
||||
//脚本
|
||||
//任务&控制台
|
||||
//教程
|
||||
//
|
||||
}
|
||||
}
|
||||
|
||||
public static class OpenByOtherApp extends ScriptFileOperation {
|
||||
|
||||
public OpenByOtherApp() {
|
||||
super(App.getApp().getString(R.string.text_open_by_other_apps), R.drawable.ic_open_in_new_green_48dp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) {
|
||||
ScriptFile scriptFile = scriptFileList.get(position);
|
||||
Uri uri = Uri.parse("file://" + scriptFile.getPath());
|
||||
App.getApp().startActivity(new Intent(Intent.ACTION_VIEW).setDataAndType(uri, "text/plain").addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
|
||||
}
|
||||
}
|
||||
|
||||
public static class Rename extends ScriptFileOperation {
|
||||
|
||||
public Rename() {
|
||||
super(App.getApp().getString(R.string.text_rename), R.drawable.ic_rename_green);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operate(final RecyclerView recyclerView, final ScriptFileList scriptFileList, final int position) {
|
||||
String oldName = scriptFileList.get(position).getSimplifiedName();
|
||||
new ThemeColorMaterialDialogBuilder(recyclerView.getContext())
|
||||
.title(R.string.text_rename)
|
||||
.checkBoxPrompt(App.getApp().getString(R.string.text_rename_file_meanwhile), false, null)
|
||||
.input(App.getApp().getString(R.string.text_please_input_new_name), oldName, new MaterialDialog.InputCallback() {
|
||||
@Override
|
||||
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
|
||||
scriptFileList.rename(position, input.toString(), dialog.isPromptCheckBoxChecked());
|
||||
recyclerView.getAdapter().notifyItemChanged(position);
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
public static class CreateShortcut extends ScriptFileOperation {
|
||||
|
||||
public CreateShortcut() {
|
||||
super(App.getApp().getString(R.string.text_send_shortcut), R.drawable.ic_shortcut_green);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) {
|
||||
ScriptFile scriptFile = scriptFileList.get(position);
|
||||
new Shortcut(App.getApp()).name(scriptFile.getSimplifiedName())
|
||||
.targetClass(ShortcutActivity.class)
|
||||
.icon(R.drawable.ic_robot_green)
|
||||
.extras(new Intent().putExtra("path", scriptFile.getPath()))
|
||||
.send();
|
||||
EventBus.getDefault().post(R.string.text_already_create);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Remove extends ScriptFileOperation {
|
||||
|
||||
public Remove() {
|
||||
super(App.getApp().getString(R.string.text_delete), R.drawable.ic_delete_green_48dp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) {
|
||||
scriptFileList.remove(position);
|
||||
recyclerView.getAdapter().notifyItemRemoved(position);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Delete extends ScriptFileOperation {
|
||||
|
||||
public Delete() {
|
||||
super(App.getApp().getString(R.string.text_delete_absolutly), R.drawable.ic_delete_forever_green_48dp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void operate(RecyclerView recyclerView, ScriptFileList scriptFileList, int position) {
|
||||
boolean succeed = scriptFileList.deleteFromFileSystem(position);
|
||||
EventBus.getDefault().post(new ShowMessageEvent(succeed ? R.string.text_already_delete : R.string.text_delete_failed));
|
||||
if (succeed)
|
||||
recyclerView.getAdapter().notifyItemRemoved(position);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@ -1,174 +0,0 @@
|
||||
package com.stardust.scriptdroid.ui.main.operation;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.widget.PopupWindowCompat;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.PopupWindow;
|
||||
import android.widget.TextView;
|
||||
import android.workground.WrapContentLinearLayoutManager;
|
||||
|
||||
import com.stardust.util.ViewUtil;
|
||||
import com.stardust.scriptdroid.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/24.
|
||||
*/
|
||||
|
||||
public class ScriptFileOperationPopupMenu extends PopupWindow {
|
||||
|
||||
|
||||
public interface OnItemClickListener {
|
||||
void onClick(View view, int position, ScriptFileOperation operation);
|
||||
}
|
||||
|
||||
private Context mContext;
|
||||
private ScriptFileOperationListRecyclerView mOperationListRecyclerView;
|
||||
private OnItemClickListener mOnItemClickListener;
|
||||
|
||||
|
||||
private List<ScriptFileOperation> mScriptFileOperationList;
|
||||
|
||||
private final View.OnClickListener mOnItemClickRealListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (mOnItemClickListener != null) {
|
||||
int position = mOperationListRecyclerView.getChildViewHolder(v).getAdapterPosition();
|
||||
mOnItemClickListener.onClick(v, position, mScriptFileOperationList.get(position));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public ScriptFileOperationPopupMenu(Context context, List<ScriptFileOperation> scriptFileOperationList) {
|
||||
super(context);
|
||||
mContext = context;
|
||||
mScriptFileOperationList = scriptFileOperationList;
|
||||
init();
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
|
||||
mOnItemClickListener = onItemClickListener;
|
||||
}
|
||||
|
||||
public void show(View anchor) {
|
||||
int y = (int) (getScreenHeight() - anchor.getHeight() - getYInScreen(anchor) - getContentHeight());
|
||||
y = Math.min(y, -anchor.getHeight());
|
||||
PopupWindowCompat.showAsDropDown(this, anchor, 0, y, Gravity.LEFT | Gravity.BOTTOM);
|
||||
}
|
||||
|
||||
private int getContentHeight() {
|
||||
getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
return getContentView().getMeasuredHeight();
|
||||
}
|
||||
|
||||
private int getYInScreen(View anchor) {
|
||||
int[] location = new int[2];
|
||||
anchor.getLocationInWindow(location);
|
||||
return location[1];
|
||||
}
|
||||
|
||||
|
||||
private float getScreenHeight() {
|
||||
DisplayMetrics displaymetrics = new DisplayMetrics();
|
||||
((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displaymetrics);
|
||||
return displaymetrics.heightPixels;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
|
||||
setBackgroundDrawable(new ColorDrawable());
|
||||
setOutsideTouchable(true);
|
||||
setAnimationStyle(-1);
|
||||
initContentView();
|
||||
}
|
||||
|
||||
private void initContentView() {
|
||||
View contentView = View.inflate(mContext, R.layout.script_file_operation_popup_menu_content, null);
|
||||
setContentView(contentView);
|
||||
mOperationListRecyclerView = ViewUtil.$(contentView, R.id.operation_list);
|
||||
mOperationListRecyclerView.setOnItemClickListener(mOnItemClickRealListener);
|
||||
mOperationListRecyclerView.setScriptFileOperationList(mScriptFileOperationList);
|
||||
}
|
||||
|
||||
|
||||
public static class ScriptFileOperationListRecyclerView extends RecyclerView {
|
||||
|
||||
private OnClickListener mOnItemClickListener;
|
||||
|
||||
private List<ScriptFileOperation> mScriptFileOperationList;
|
||||
|
||||
public ScriptFileOperationListRecyclerView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public ScriptFileOperationListRecyclerView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ScriptFileOperationListRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setScriptFileOperationList(List<ScriptFileOperation> scriptFileOperationList) {
|
||||
mScriptFileOperationList = scriptFileOperationList;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setLayoutManager(new WrapContentLinearLayoutManager(getContext()));
|
||||
setAdapter(new Adapter<ViewHolder>() {
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View itemView = LayoutInflater.from(getContext()).inflate(R.layout.script_file_operation_popup_menu_item, parent, false);
|
||||
return new ViewHolder(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
ScriptFileOperation operation = mScriptFileOperationList.get(position);
|
||||
holder.operationName.setText(operation.getName());
|
||||
holder.icon.setImageResource(operation.getIconResId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mScriptFileOperationList.size();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnClickListener onItemClickListener) {
|
||||
mOnItemClickListener = onItemClickListener;
|
||||
}
|
||||
|
||||
private class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
TextView operationName;
|
||||
ImageView icon;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
itemView.setOnClickListener(mOnItemClickListener);
|
||||
operationName = ViewUtil.$(itemView, R.id.name);
|
||||
icon = ViewUtil.$(itemView, R.id.icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,13 +9,11 @@ import android.view.ViewGroup;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.app.Fragment;
|
||||
import com.stardust.pio.PFile;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.scripts.sample.Sample;
|
||||
import com.stardust.scriptdroid.scripts.sample.SampleFileManager;
|
||||
import com.stardust.scriptdroid.ui.edit.EditActivity;
|
||||
import com.stardust.scriptdroid.ui.edit.ViewSampleActivity;
|
||||
import com.stardust.scriptdroid.ui.main.MainActivity;
|
||||
import com.stardust.util.AssetsCache;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@ -67,6 +65,7 @@ public class SampleScriptListFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void copySampleToMyScripts(Sample sample) {
|
||||
MainActivity.importSample(getActivity(), sample);
|
||||
try {
|
||||
((MainActivity) getActivity()).getMyScriptListFragment().
|
||||
importFile(sample.name, getActivity().getAssets().open(sample.path));
|
||||
@ -77,7 +76,7 @@ public class SampleScriptListFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void viewSample(Sample sample) {
|
||||
EditActivity.view(getContext(), sample.name, AssetsCache.get(getActivity(), sample.path));
|
||||
ViewSampleActivity.view(getContext(), sample);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@ import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@ -37,6 +38,8 @@ public class MyScriptListFragment extends Fragment {
|
||||
|
||||
public static final String MESSAGE_SCRIPT_FILE_ADDED = "MESSAGE_SCRIPT_FILE_ADDED";
|
||||
|
||||
private static final String TAG = "MyScriptListFragment";
|
||||
|
||||
private ScriptAndFolderListRecyclerView mScriptListRecyclerView;
|
||||
private ScriptListWithProgressBarView mScriptListWithProgressBarView;
|
||||
private View mNoScriptHint;
|
||||
@ -45,7 +48,7 @@ public class MyScriptListFragment extends Fragment {
|
||||
private ScriptFile mSelectedScriptFile;
|
||||
private MaterialDialog.InputCallback mFileNameInputCallback = new InputCallback(false);
|
||||
private MaterialDialog.InputCallback mDirectoryNameInputCallback = new InputCallback(true);
|
||||
private int mSelectedPosition;
|
||||
private String mFilePathToImport;
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
@ -67,6 +70,10 @@ public class MyScriptListFragment extends Fragment {
|
||||
mNoScriptHint = $(R.id.hint_no_script);
|
||||
initScriptListRecyclerView();
|
||||
initDialogs();
|
||||
if (mFilePathToImport != null) {
|
||||
importFile(mFilePathToImport);
|
||||
mFilePathToImport = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void initScriptListRecyclerView() {
|
||||
@ -91,7 +98,6 @@ public class MyScriptListFragment extends Fragment {
|
||||
@Override
|
||||
public void onLongClick(ScriptFile file, int position) {
|
||||
mSelectedScriptFile = file;
|
||||
mSelectedPosition = position;
|
||||
if (file.isDirectory()) {
|
||||
mDirectoryOperationDialog.show();
|
||||
} else {
|
||||
@ -147,6 +153,10 @@ public class MyScriptListFragment extends Fragment {
|
||||
}
|
||||
|
||||
public void importFile(final String pathFrom) {
|
||||
if (getActivity() == null) {
|
||||
mFilePathToImport = pathFrom;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
importFile(PFile.getNameWithoutExtension(pathFrom), new FileInputStream(pathFrom));
|
||||
} catch (FileNotFoundException e) {
|
||||
@ -245,7 +255,7 @@ public class MyScriptListFragment extends Fragment {
|
||||
@ViewBinding.Click(R.id.open_by_other_apps)
|
||||
private void openByOtherApps() {
|
||||
dismissDialogs();
|
||||
ScriptFileOperation.openByOtherApps(mSelectedScriptFile);
|
||||
ScriptFileOperation.openByOtherApps(mSelectedScriptFile.getPath());
|
||||
onScriptFileOperated();
|
||||
}
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@ import com.stardust.scriptdroid.autojs.AutoJs;
|
||||
import com.stardust.scriptdroid.scripts.ScriptFile;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.scripts.StorageScriptProvider;
|
||||
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
|
||||
import com.stardust.widget.ViewHolderMutableAdapter;
|
||||
import com.stardust.widget.ViewHolderSupplier;
|
||||
import com.yqritc.recyclerviewflexibledivider.HorizontalDividerItemDecoration;
|
||||
@ -107,7 +108,7 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
|
||||
public void onClick(View v) {
|
||||
int position = getChildViewHolder((View) v.getParent()).getAdapterPosition();
|
||||
ScriptFile file = mAdapter.getScriptFileAt(position);
|
||||
AutoJs.getInstance().getScriptEngineService().execute(new FileScriptSource(file));
|
||||
ScriptFileOperation.run(file);
|
||||
}
|
||||
};
|
||||
private final ViewHolderSupplier<ViewHolder> mDefaultViewHolderSupplier = new ViewHolderSupplier<ViewHolder>() {
|
||||
@ -188,6 +189,10 @@ public class ScriptAndFolderListRecyclerView extends RecyclerView {
|
||||
setRootDirectory(mStorageScriptProvider.getInitialDirectory());
|
||||
}
|
||||
|
||||
public StorageScriptProvider getStorageScriptProvider() {
|
||||
return mStorageScriptProvider;
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnScriptFileClickListener onItemClickListener) {
|
||||
mOnItemClickListener = onItemClickListener;
|
||||
}
|
||||
|
||||
@ -1,151 +0,0 @@
|
||||
package com.stardust.scriptdroid.ui.main.script_list;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.ThemeColorRecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import android.workground.WrapContentLinearLayoutManager;
|
||||
|
||||
import com.stardust.scriptdroid.scripts.ScriptFile;
|
||||
import com.stardust.scriptdroid.scripts.ScriptFileList;
|
||||
import com.stardust.util.ViewUtil;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.ui.main.operation.ScriptFileOperation;
|
||||
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/23.
|
||||
*/
|
||||
|
||||
public class ScriptListRecyclerView extends ThemeColorRecyclerView {
|
||||
|
||||
public interface OnItemClickListener {
|
||||
|
||||
void OnItemClick(View v, int position);
|
||||
|
||||
}
|
||||
|
||||
private ScriptFileList mScriptFileList;
|
||||
|
||||
private OnItemClickListener mOnItemClickListener;
|
||||
|
||||
private final OnClickListener mOnItemClickListenerProxy = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int position = getChildViewHolder(v).getAdapterPosition();
|
||||
if (mOnItemClickListener != null) {
|
||||
mOnItemClickListener.OnItemClick(v, position);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private final OnClickListener mOnEditIconClickListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int position = getChildViewHolder((View) v.getParent()).getAdapterPosition();
|
||||
onEditIconClick(v, position);
|
||||
}
|
||||
};
|
||||
|
||||
private final OnClickListener mOnRunIconClickListener = new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int position = getChildViewHolder((View) v.getParent()).getAdapterPosition();
|
||||
//onRunIconClick(v, position);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
public ScriptListRecyclerView(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
public ScriptListRecyclerView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public ScriptListRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
init();
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
|
||||
mOnItemClickListener = onItemClickListener;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
setAdapter(new Adapter());
|
||||
setLayoutManager(new WrapContentLinearLayoutManager(getContext()));
|
||||
addItemDecoration(new DividerItemDecoration(getContext(), DividerItemDecoration.VERTICAL));
|
||||
}
|
||||
|
||||
|
||||
protected void onEditIconClick(View v, int position) {
|
||||
ScriptFileOperation.Edit.getInstance().operate(ScriptListRecyclerView.this, mScriptFileList, position);
|
||||
}
|
||||
|
||||
public void setScriptFileList(ScriptFileList scriptFileList) {
|
||||
mScriptFileList = scriptFileList;
|
||||
getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void showMessage(ScriptFileOperation.ShowMessageEvent event) {
|
||||
Snackbar.make(this, event.messageResId, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private class Adapter extends RecyclerView.Adapter<ViewHolder> {
|
||||
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View itemView = LayoutInflater.from(getContext()).inflate(R.layout.script_list_recycler_view_item, parent, false);
|
||||
return new ViewHolder(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder holder, int position) {
|
||||
ScriptFile scriptFile = mScriptFileList.get(position);
|
||||
holder.name.setText(scriptFile.getSimplifiedName());
|
||||
holder.path.setText(scriptFile.getSimplifiedPath());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return mScriptFileList.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerAdapterDataObserver(AdapterDataObserver observer) {
|
||||
super.registerAdapterDataObserver(observer);
|
||||
}
|
||||
}
|
||||
|
||||
private class ViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
TextView name, path;
|
||||
|
||||
ViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
name = (TextView) itemView.findViewById(R.id.name);
|
||||
path = (TextView) itemView.findViewById(R.id.path);
|
||||
ViewUtil.$(itemView, R.id.edit).setOnClickListener(mOnEditIconClickListener);
|
||||
ViewUtil.$(itemView, R.id.run).setOnClickListener(mOnRunIconClickListener);
|
||||
itemView.setOnClickListener(mOnItemClickListenerProxy);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -7,6 +7,7 @@ import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.RequiresApi;
|
||||
import android.support.annotation.StyleRes;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
@ -23,6 +24,7 @@ public class ScriptListWithProgressBarView extends FrameLayout {
|
||||
|
||||
private View mProgressBar;
|
||||
private ScriptAndFolderListRecyclerView mScriptAndFolderListRecyclerView;
|
||||
private SwipeRefreshLayout mSwipeRefreshLayout;
|
||||
|
||||
public ScriptListWithProgressBarView(@NonNull Context context) {
|
||||
super(context);
|
||||
@ -47,6 +49,7 @@ public class ScriptListWithProgressBarView extends FrameLayout {
|
||||
|
||||
private void init() {
|
||||
inflate(getContext(), R.layout.script_and_folder_list_view, this);
|
||||
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);
|
||||
mProgressBar = findViewById(R.id.progressBar);
|
||||
mScriptAndFolderListRecyclerView = (ScriptAndFolderListRecyclerView) findViewById(R.id.script_list_recycler_view);
|
||||
mScriptAndFolderListRecyclerView.setFileProcessListener(new ScriptAndFolderListRecyclerView.FileProcessListener() {
|
||||
@ -60,6 +63,12 @@ public class ScriptListWithProgressBarView extends FrameLayout {
|
||||
hideProgressBar();
|
||||
}
|
||||
});
|
||||
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
mScriptAndFolderListRecyclerView.getStorageScriptProvider().refreshAll();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -82,11 +91,13 @@ public class ScriptListWithProgressBarView extends FrameLayout {
|
||||
|
||||
|
||||
public void showProgressBar() {
|
||||
mProgressBar.setVisibility(VISIBLE);
|
||||
mSwipeRefreshLayout.setRefreshing(true);
|
||||
mScriptAndFolderListRecyclerView.setEnabled(false);
|
||||
}
|
||||
|
||||
public void hideProgressBar() {
|
||||
mProgressBar.setVisibility(GONE);
|
||||
mSwipeRefreshLayout.setRefreshing(false);
|
||||
mScriptAndFolderListRecyclerView.setEnabled(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -115,6 +115,7 @@ public class SettingsActivity extends BaseActivity {
|
||||
@Override
|
||||
public void run() {
|
||||
EventBus.getDefault().post(new MessageEvent(MainActivity.MESSAGE_CLEAR_BACKGROUND_SETTINGS));
|
||||
Toast.makeText(getActivity(), R.string.text_already_reset, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
})
|
||||
.entry(getString(R.string.text_check_update), new Runnable() {
|
||||
|
||||
@ -6,6 +6,7 @@ import android.support.annotation.NonNull;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.scriptdroid.BuildConfig;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.tool.UpdateChecker;
|
||||
import com.stardust.scriptdroid.tool.VersionInfo;
|
||||
@ -43,7 +44,7 @@ public class VersionGuard {
|
||||
if (isCurrentVersionDeprecated) {
|
||||
showDeprecatedDialogIfNeeded();
|
||||
} else {
|
||||
showUpdateInfo(info);
|
||||
showUpdateInfoIfNeeded(info);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -51,10 +52,12 @@ public class VersionGuard {
|
||||
}
|
||||
}
|
||||
|
||||
private void showUpdateInfo(UpdateChecker.UpdateInfo info) {
|
||||
new UpdateInfoDialogBuilder(mActivity, info)
|
||||
.showDoNotAskAgain()
|
||||
.show();
|
||||
private void showUpdateInfoIfNeeded(UpdateChecker.UpdateInfo info) {
|
||||
if (BuildConfig.VERSION_CODE < info.versionCode) {
|
||||
new UpdateInfoDialogBuilder(mActivity, info)
|
||||
.showDoNotAskAgain()
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void showDeprecatedDialogIfNeeded() {
|
||||
|
||||
@ -50,6 +50,7 @@ public class SlidingUpPanel extends FrameLayout {
|
||||
|
||||
public void show() {
|
||||
setVisibility(VISIBLE);
|
||||
setClickable(true);
|
||||
mContentContainer.startAnimation(mSlideUpAnimation);
|
||||
mShowing = true;
|
||||
}
|
||||
|
||||
@ -63,20 +63,6 @@
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<android.support.v4.widget.DrawerLayout
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include layout="@layout/content_edit"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fragment_edit_side_menu"
|
||||
android:layout_width="280dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="end"
|
||||
android:background="@android:color/white"
|
||||
android:clickable="true"/>
|
||||
</android.support.v4.widget.DrawerLayout>
|
||||
<include layout="@layout/content_edit"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
86
app/src/main/res/layout/activity_view_sample.xml
Normal file
@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context="com.stardust.scriptdroid.ui.edit.EditActivity">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<com.stardust.theme.widget.ThemeColorToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:title="@string/_app_name"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="right"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.stardust.widget.ToolbarMenuItem
|
||||
android:id="@+id/run"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="match_parent"
|
||||
app:icon="@drawable/ic_play_arrow_white_48dp"
|
||||
app:icon_color="@android:color/white"
|
||||
app:text="@string/text_run"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.stardust.theme.widget.ThemeColorToolbar>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#ffffffff"
|
||||
android:orientation="vertical"
|
||||
tools:showIn="@layout/activity_edit">
|
||||
|
||||
<com.jecelyin.editor.v2.view.EditorView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/editor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
|
||||
<com.jecelyin.editor.v2.core.widget.JecEditText
|
||||
android:id="@+id/edit_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#ffffffff"
|
||||
android:enabled="true"
|
||||
android:gravity="start|top"
|
||||
android:inputType="textMultiLine"
|
||||
android:padding="5dp"
|
||||
android:scrollbarThumbVertical="@android:color/transparent"
|
||||
android:scrollbarTrackVertical="@null"
|
||||
android:scrollbars="vertical"/>
|
||||
|
||||
<me.zhanghai.android.materialprogressbar.MaterialProgressBar
|
||||
android:id="@+id/progress_view"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="90dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="gone"/>
|
||||
|
||||
</com.jecelyin.editor.v2.view.EditorView>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@ -36,7 +36,7 @@
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/air_toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?actionBarSize"/>
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
@ -52,12 +52,12 @@
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/air_baseline_card"
|
||||
android:clipToPadding="false">
|
||||
android:padding="@dimen/air_baseline_card">
|
||||
|
||||
<include
|
||||
layout="@layout/air_card_report"
|
||||
layout="@layout/air_card_report_compat"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
@ -82,8 +82,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:layout_margin="@dimen/air_baseline"
|
||||
app:srcCompat="@drawable/air_ic_send_light"
|
||||
app:backgroundTint="?colorAccent"/>
|
||||
app:srcCompat="@drawable/air_ic_send_light"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
|
||||
120
app/src/main/res/layout/air_card_report_compat.xml
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2017 Jan Heinrich Reimer
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in all
|
||||
~ copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
~ SOFTWARE.
|
||||
-->
|
||||
|
||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:cardBackgroundColor="?cardBackgroundColor">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:padding="@dimen/air_baseline">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/air_title_issue"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/air_baseline">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/air_inputTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/air_label_issue_title"
|
||||
android:inputType="textCapSentences"
|
||||
android:maxLines="1"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/air_baseline_half">
|
||||
|
||||
<android.support.design.widget.TextInputEditText
|
||||
android:id="@+id/air_inputDescription"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/air_label_issue_description"
|
||||
android:inputType="textMultiLine|textCapSentences"
|
||||
android:lines="2"
|
||||
android:scrollbars="vertical"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/air_baseline"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/air_label_device_info"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Subhead"/>
|
||||
|
||||
<android.support.v7.widget.AppCompatImageButton
|
||||
android:id="@+id/air_buttonDeviceInfo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/air_label_device_info"
|
||||
android:padding="@dimen/air_icon_padding"
|
||||
android:tint="#ee000000"
|
||||
app:srcCompat="@drawable/air_ic_expand_more"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<com.github.aakira.expandablelayout.ExpandableRelativeLayout
|
||||
android:id="@+id/air_layoutDeviceInfo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:ael_expanded="false"
|
||||
app:ael_interpolator="fastOutSlowIn"
|
||||
app:ael_orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.AppCompatTextView
|
||||
android:id="@+id/air_textDeviceInfo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/air_baseline_half"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||
android:textColor="?android:textColorSecondary"/>
|
||||
|
||||
</com.github.aakira.expandablelayout.ExpandableRelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
||||
@ -4,10 +4,17 @@
|
||||
android:layout_height="match_parent"
|
||||
android:background="#fefefe">
|
||||
|
||||
<com.stardust.scriptdroid.ui.main.script_list.ScriptAndFolderListRecyclerView
|
||||
android:id="@+id/script_list_recycler_view"
|
||||
<android.support.v4.widget.SwipeRefreshLayout
|
||||
android:id="@+id/swipe_refresh_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.stardust.scriptdroid.ui.main.script_list.ScriptAndFolderListRecyclerView
|
||||
android:id="@+id/script_list_recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/progressBar"
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:drawable/dialog_holo_light_frame"
|
||||
android:orientation="vertical">
|
||||
|
||||
<view
|
||||
android:id="@+id/operation_list"
|
||||
class="com.stardust.scriptdroid.ui.main.operation.ScriptFileOperationPopupMenu$ScriptFileOperationListRecyclerView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:background="?android:selectableItemBackground"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
<com.stardust.theme.widget.ThemeColorImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:contentDescription="@string/_app_name"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/name"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_toRightOf="@id/icon"
|
||||
android:textColor="@android:color/secondary_text_light"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
@ -9,15 +9,21 @@
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_help"
|
||||
android:id="@+id/action_console"
|
||||
android:orderInCategory="200"
|
||||
android:title="@string/text_console"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_help"
|
||||
android:orderInCategory="300"
|
||||
android:title="@string/text_help"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_console"
|
||||
android:orderInCategory="300"
|
||||
android:title="@string/text_console"
|
||||
android:id="@+id/action_open_by_other_apps"
|
||||
android:orderInCategory="400"
|
||||
android:title="@string/text_open_by_other_apps"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
</menu>
|
||||
23
app/src/main/res/menu/menu_view_sample.xml
Normal file
@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_console"
|
||||
android:orderInCategory="200"
|
||||
android:title="@string/text_console"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_help"
|
||||
android:orderInCategory="300"
|
||||
android:title="@string/text_help"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
<item
|
||||
android:id="@+id/action_import"
|
||||
android:orderInCategory="400"
|
||||
android:title="@string/text_copy_to_my_scripts"
|
||||
app:showAsAction="never"/>
|
||||
|
||||
</menu>
|
||||
@ -1,5 +1,5 @@
|
||||
<resources>
|
||||
<string name="_app_name">UiAutomator</string>
|
||||
<string name="_app_name">AutoJs</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="action_disable_service">Disable Service</string>
|
||||
<string name="text_accessibility_service_description">Required by the script automatic operation (click, long press, slide, etc.).</string>
|
||||
@ -38,8 +38,6 @@
|
||||
<string name="text_do_not_remind_again">Don\'t show again</string>
|
||||
<string name="copyright">Copyright©2016 All right reserves.</string>
|
||||
<string name="developer">Stardust</string>
|
||||
<string name="qq">946994919</string>
|
||||
<string name="email">hybbbb1996@gmail.com</string>
|
||||
<string name="github">Source Code</string>
|
||||
<string name="text_already_copy_to_clip">Copied</string>
|
||||
<string name="donate_developer">Donate</string>
|
||||
@ -122,7 +120,7 @@
|
||||
<string name="text_layout_hierarchy">View layout hierarchy</string>
|
||||
<string name="text_layout_bounds">View layout bounds</string>
|
||||
<string name="text_no_accessibility_permission_to_capture">Accessibility service is not activated</string>
|
||||
<string name="text_sample_script">Sample Scripts</string>
|
||||
<string name="text_sample_script">Samples</string>
|
||||
<string name="text_my_script">My Scripts</string>
|
||||
<string name="hint_no_script">Click ADD to create your first script~(。・・)ノ</string>
|
||||
<string name="text_reset_background">Reset background settings</string>
|
||||
@ -155,15 +153,15 @@
|
||||
<string name="summary_command_run_mode">If the app responses slowly when running script, choose Thread Pool or Create Thread. But it may causes rebooting of the device</string>
|
||||
<string name="text_on">ON</string>
|
||||
<string name="text_off">OFF</string>
|
||||
<string name="text_please_choose_file_to_import">请选择要导入的脚本</string>
|
||||
<string name="text_refresh">刷新</string>
|
||||
<string name="notice_no_running_script"><![CDATA[没有正在运行的脚本 φ(>ω<*)]]></string>
|
||||
<string name="text_checking_update">正在检查更新</string>
|
||||
<string name="text_new_version">新版本</string>
|
||||
<string name="text_is_latest_version">已经是最新版本</string>
|
||||
<string name="text_version_too_old">版本过低</string>
|
||||
<string name="warning_version_too_old">这个版本已经不能再使用了哦</string>
|
||||
<string name="text_release_notes">更新日志</string>
|
||||
<string name="text_please_choose_file_to_import">Select script file to import</string>
|
||||
<string name="text_refresh">Refresh</string>
|
||||
<string name="notice_no_running_script"><![CDATA[No running script φ(>ω<*)]]></string>
|
||||
<string name="text_checking_update">Checking for updates</string>
|
||||
<string name="text_new_version">New Version</string>
|
||||
<string name="text_is_latest_version">No newer version found</string>
|
||||
<string name="text_version_too_old">Version too old</string>
|
||||
<string name="warning_version_too_old">This version is deprecated</string>
|
||||
<string name="text_release_notes">Release Notes</string>
|
||||
<string-array name="record_control_keys">
|
||||
<item>None</item>
|
||||
<item>Volume Up</item>
|
||||
@ -176,5 +174,15 @@
|
||||
<item>Create New Thread Every Time</item>
|
||||
<item>Thread Pool</item>
|
||||
</string-array>
|
||||
<string name="text_update">Update</string>
|
||||
<string name="text_task_manage">Tasks</string>
|
||||
<string name="text_script">Script</string>
|
||||
<string name="text_root_script_record"></string>
|
||||
<string name="text_processing">Processing</string>
|
||||
<string name="text_re_import_succeed"></string>
|
||||
<string name="text_pre_execute_script">Pre-execute script</string>
|
||||
<string name="text_check_update">Check for updates</string>
|
||||
<string name="text_new_directory">New Directory</string>
|
||||
<string name="text_already_reset">已重置</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<resources>
|
||||
<string name="_app_name">免Root脚本精灵</string>
|
||||
<string name="_app_name">AutoJs</string>
|
||||
<string name="action_settings">设置</string>
|
||||
<string name="action_disable_service">关闭服务</string>
|
||||
<string name="text_accessibility_service_description">使脚本自动操作(点击、长按、滑动等)所需,若关闭则只能执行不涉及自动操作的脚本。</string>
|
||||
@ -12,7 +12,7 @@
|
||||
<string name="text_please_input_name">请输入名称</string>
|
||||
<string name="text_name">名称</string>
|
||||
<string name="text_go_to_setting">去设置</string>
|
||||
<string name="explain_accessibility_permission">软件需要打开\"自动操作服务\"才能运行,请在随后的设置中选择\"免Root脚本精灵\"并开启服务。\n您也可以稍后在侧拉菜单中设置。</string>
|
||||
<string name="explain_accessibility_permission">软件需要打开\"自动操作服务\"才能运行,请在随后的设置中选择\"AutoJs\"并开启服务。\n您也可以稍后在侧拉菜单中设置。</string>
|
||||
<string name="text_cancel">取消</string>
|
||||
<string name="text_path_is_empty">路径为空</string>
|
||||
<string name="text_file_not_exists">文件不存在</string>
|
||||
@ -42,14 +42,14 @@
|
||||
<string name="text_sample_simple_calculator">示例:简单计算器</string>
|
||||
<string name="copyright">Copyright©2016 All right reserves.</string>
|
||||
<string name="developer">星尘幻影</string>
|
||||
<string name="qq">946994919</string>
|
||||
<string name="qq">2732014414</string>
|
||||
<string name="email">hybbbb1996@gmail.com</string>
|
||||
<string name="github">软件源代码</string>
|
||||
<string name="text_already_copy_to_clip">已复制到剪贴板</string>
|
||||
<string name="donate_developer">打赏作者</string>
|
||||
<string name="text_email">邮箱</string>
|
||||
<string name="my_github">https://github.com/hyb1996/NoRootScriptDroid</string>
|
||||
<string name="share_app">[免Root脚本精灵]下载地址:http://www.coolapk.com/apk/com.stardust.scriptdroid </string>
|
||||
<string name="share_app">[AutoJs]下载地址:http://www.coolapk.com/apk/com.stardust.scriptdroid </string>
|
||||
<string name="text_floating_window">悬浮窗</string>
|
||||
<string name="text_assist_service_notification">通知栏点击区域辅助开关</string>
|
||||
<string name="text_others">其他</string>
|
||||
@ -165,7 +165,7 @@
|
||||
<string name="key_stop_record_trigger">key_stop_record_trigger</string>
|
||||
<string name="text_current_activity">当前活动:</string>
|
||||
<string name="text_current_package">当前应用包名:</string>
|
||||
<string name="go_to_accessibility_settings"><![CDATA[请打开设置->无障碍服务->免Root脚本精灵并开启]]></string>
|
||||
<string name="go_to_accessibility_settings"><![CDATA[请打开设置->无障碍服务->AutoJs并开启]]></string>
|
||||
<string name="text_script_running">脚本运行</string>
|
||||
<string name="key_use_volume_control_running">key_use_volume_control_running</string>
|
||||
<string name="text_use_volume_to_stop_running">每次音量键变化停止所有脚本</string>
|
||||
@ -210,6 +210,10 @@
|
||||
<string name="text_do_not_ask_again_for_this_version">此版本不再提示</string>
|
||||
<string name="text_code_beautify">格式化代码</string>
|
||||
<string name="text_processing">处理中</string>
|
||||
<string name="text_already_reset">已重置</string>
|
||||
<string name="text_guard_mode">保护模式</string>
|
||||
<string name="summary_guard_mode">在本软件界面无法运行自动操作命令以免误触</string>
|
||||
<string name="key_guard_mode">key_guard_mode</string>
|
||||
|
||||
<string-array name="record_control_keys">
|
||||
<item>无</item>
|
||||
|
||||
@ -35,6 +35,12 @@
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_use_volume_control_running"
|
||||
android:title="@string/text_use_volume_to_stop_running"/>
|
||||
|
||||
<com.stardust.theme.preference.ThemeColorSwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_guard_mode"
|
||||
android:summary="@string/summary_guard_mode"
|
||||
android:title="@string/text_guard_mode"/>
|
||||
</com.stardust.theme.preference.ThemeColorPreferenceCategory>
|
||||
|
||||
<com.stardust.theme.preference.ThemeColorPreferenceCategory android:title="@string/text_edit">
|
||||
@ -60,26 +66,12 @@
|
||||
<Preference android:title="@string/text_reset_background"/>
|
||||
</com.stardust.theme.preference.ThemeColorPreferenceCategory>
|
||||
|
||||
<com.stardust.theme.preference.ThemeColorPreferenceCategory android:title="@string/text_advanced">
|
||||
|
||||
<com.afollestad.materialdialogs.prefs.MaterialListPreference
|
||||
android:defaultValue="@string/key_single_thread"
|
||||
android:entries="@array/run_mode_keys"
|
||||
android:entryValues="@array/run_mode_values"
|
||||
android:key="@string/key_run_mode"
|
||||
android:summary="@string/summary_command_run_mode"
|
||||
android:title="@string/text_command_run_mode"
|
||||
/>
|
||||
</com.stardust.theme.preference.ThemeColorPreferenceCategory>
|
||||
|
||||
<com.stardust.theme.preference.ThemeColorPreferenceCategory android:title="@string/text_about">
|
||||
|
||||
<Preference android:title="@string/text_check_update"/>
|
||||
|
||||
<Preference android:title="@string/text_issue_report"/>
|
||||
|
||||
<Preference android:title="@string/text_join_qq_group"/>
|
||||
|
||||
<Preference android:title="@string/text_about"/>
|
||||
|
||||
<Preference android:title="@string/text_licenses"/>
|
||||
|
||||
@ -85,8 +85,7 @@ public abstract class JavaScriptEngineManager {
|
||||
|
||||
void removeEngine(JavaScriptEngine engine) {
|
||||
synchronized (mEngines) {
|
||||
mEngines.remove(engine);
|
||||
if (mEngineLifecycleCallback != null) {
|
||||
if (mEngines.remove(engine) && mEngineLifecycleCallback != null) {
|
||||
mEngineLifecycleCallback.onEngineRemove(engine);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
package com.stardust.autojs.engine;
|
||||
|
||||
import android.os.Looper;
|
||||
import android.util.Log;
|
||||
|
||||
import com.stardust.autojs.rhino_android.AndroidContextFactory;
|
||||
import com.stardust.autojs.rhino_android.RhinoAndroidHelper;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.autojs.runtime.ScriptStopException;
|
||||
import com.stardust.autojs.script.ScriptSource;
|
||||
import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
@ -17,7 +17,6 @@ import org.mozilla.javascript.ScriptableObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
@ -36,6 +35,7 @@ public class RhinoJavaScriptEngine implements JavaScriptEngine {
|
||||
private Thread mThread;
|
||||
private RhinoJavaScriptEngineManager mEngineManager;
|
||||
private Map<String, Object> mTags = new Hashtable<>();
|
||||
private boolean mDestroyed = false;
|
||||
|
||||
public RhinoJavaScriptEngine(RhinoJavaScriptEngineManager engineManager) {
|
||||
mEngineManager = engineManager;
|
||||
@ -67,7 +67,7 @@ public class RhinoJavaScriptEngine implements JavaScriptEngine {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
public synchronized void destroy() {
|
||||
Context.exit();
|
||||
// TODO: 2017/4/6 XXX :在这里回收内存池并不好
|
||||
final AccessibilityNodeInfoAllocator allocator = (AccessibilityNodeInfoAllocator) getTag("allocator");
|
||||
@ -75,6 +75,7 @@ public class RhinoJavaScriptEngine implements JavaScriptEngine {
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
// FIXME: 2017/4/28
|
||||
//allocator.recycleAll();
|
||||
}
|
||||
}, 1000);
|
||||
@ -136,14 +137,13 @@ public class RhinoJavaScriptEngine implements JavaScriptEngine {
|
||||
@Override
|
||||
protected void observeInstructionCount(Context cx, int instructionCount) {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
|
||||
Context.exit();
|
||||
throw new ScriptStopException(new InterruptedException());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Context makeContext() {
|
||||
|
||||
Context cx = super.makeContext();
|
||||
cx.setInstructionObserverThreshold(10000);
|
||||
return cx;
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
package com.stardust.autojs.runtime.api;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/29.
|
||||
*/
|
||||
|
||||
public class AutomatorConfig {
|
||||
|
||||
private static boolean isUnintendedGuardEnabled = false;
|
||||
|
||||
|
||||
public static boolean isUnintendedGuardEnabled() {
|
||||
return isUnintendedGuardEnabled;
|
||||
}
|
||||
|
||||
public static void setIsUnintendedGuardEnabled(boolean isUnintendedGuardEnabled) {
|
||||
AutomatorConfig.isUnintendedGuardEnabled = isUnintendedGuardEnabled;
|
||||
}
|
||||
}
|
||||
@ -2,6 +2,7 @@ package com.stardust.autojs.runtime.api;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.Log;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
@ -87,7 +88,8 @@ public class UiSelector extends UiGlobalSelector {
|
||||
@JavascriptInterface
|
||||
public UiObjectCollection find() {
|
||||
ensureAccessibilityServiceEnabled();
|
||||
if (isRunningPackageSelf()) {
|
||||
if (AutomatorConfig.isUnintendedGuardEnabled() && isRunningPackageSelf()) {
|
||||
Log.d(TAG, "isSelfPackage return null");
|
||||
return null;
|
||||
}
|
||||
AccessibilityService service = mAccessibilityBridge.getService();
|
||||
@ -105,7 +107,7 @@ public class UiSelector extends UiGlobalSelector {
|
||||
}
|
||||
|
||||
private boolean isRunningPackageSelf() {
|
||||
return DeveloperUtils.isRunningPackageSelf(mAccessibilityBridge.getInfoProvider().getLatestPackage());
|
||||
return DeveloperUtils.isSelfPackage(mAccessibilityBridge.getInfoProvider().getLatestPackage());
|
||||
}
|
||||
|
||||
|
||||
@ -115,6 +117,7 @@ public class UiSelector extends UiGlobalSelector {
|
||||
UiObjectCollection uiObjectCollection;
|
||||
do {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
Log.d(TAG, "Thread isInterrupted");
|
||||
throw new ScriptStopException(new InterruptedException());
|
||||
}
|
||||
uiObjectCollection = find();
|
||||
|
||||
@ -11,6 +11,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import com.stardust.autojs.runtime.AccessibilityBridge;
|
||||
import com.stardust.autojs.runtime.JavascriptInterface;
|
||||
import com.stardust.autojs.runtime.ScriptRuntime;
|
||||
import com.stardust.autojs.runtime.api.AutomatorConfig;
|
||||
import com.stardust.automator.AccessibilityEventCommandHost;
|
||||
import com.stardust.automator.simple_action.SimpleAction;
|
||||
import com.stardust.automator.simple_action.ActionFactory;
|
||||
@ -24,6 +25,8 @@ import com.stardust.view.accessibility.AccessibilityNodeInfoAllocator;
|
||||
|
||||
public class SimpleActionAutomator {
|
||||
|
||||
private static final String TAG = "SimpleActionAutomator";
|
||||
|
||||
@Deprecated
|
||||
private static class PerformGlobalActionCommand extends AccessibilityEventCommandHost.AbstractCommand {
|
||||
|
||||
@ -185,7 +188,8 @@ public class SimpleActionAutomator {
|
||||
@SuppressWarnings("unchecked")
|
||||
private boolean performAction(SimpleAction simpleAction) {
|
||||
ensureAccessibilityServiceEnabled();
|
||||
if (isRunningPackageSelf()) {
|
||||
if (AutomatorConfig.isUnintendedGuardEnabled() && isRunningPackageSelf()) {
|
||||
Log.i(TAG, "performAction: running package is self. return false");
|
||||
return false;
|
||||
}
|
||||
AccessibilityService service = mAccessibilityBridge.getService();
|
||||
@ -203,6 +207,6 @@ public class SimpleActionAutomator {
|
||||
}
|
||||
|
||||
private boolean isRunningPackageSelf() {
|
||||
return DeveloperUtils.isRunningPackageSelf(mAccessibilityBridge.getInfoProvider().getLatestPackage());
|
||||
return DeveloperUtils.isSelfPackage(mAccessibilityBridge.getInfoProvider().getLatestPackage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
package com.stardust.pio;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/4/29.
|
||||
*/
|
||||
|
||||
public class PRandomAccessBinaryFile extends RandomAccessFile {
|
||||
|
||||
|
||||
private RandomAccessFile mRandomAccessFile;
|
||||
|
||||
public PRandomAccessBinaryFile(String name, String mode) throws FileNotFoundException {
|
||||
super(name, mode);
|
||||
}
|
||||
|
||||
public PRandomAccessBinaryFile(File file, String mode) throws FileNotFoundException {
|
||||
super(file, mode);
|
||||
}
|
||||
|
||||
public String readline() throws IOException {
|
||||
return super.readLine();
|
||||
}
|
||||
|
||||
}
|
||||
@ -16,7 +16,7 @@ public class DeveloperUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isRunningPackageSelf(@Nullable String runningPackage) {
|
||||
public static boolean isSelfPackage(@Nullable String runningPackage) {
|
||||
return PACKAGE_NAME.equals(runningPackage);
|
||||
}
|
||||
}
|
||||
|
||||