Merge pull request #211 from hyb1996/new_ui

release 2.0.14 Beta
This commit is contained in:
Stardust
2017-07-12 14:05:22 +08:00
committed by GitHub
48 changed files with 800 additions and 150 deletions

View File

@@ -9,8 +9,8 @@ android {
applicationId "com.stardust.scriptdroid" applicationId "com.stardust.scriptdroid"
minSdkVersion 17 minSdkVersion 17
targetSdkVersion 23 targetSdkVersion 23
versionCode 145 versionCode 146
versionName "2.0.13 Beta3" versionName "2.0.14 Beta"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true multiDexEnabled true
ndk { ndk {

View File

@@ -80,6 +80,11 @@
<activity android:name=".ui.help.LocalWebViewActivity"/> <activity android:name=".ui.help.LocalWebViewActivity"/>
<activity android:name=".external.tasker.TaskerScriptEditActivity_"/> <activity android:name=".external.tasker.TaskerScriptEditActivity_"/>
<activity android:name=".ui.edit.ViewSampleActivity"/> <activity android:name=".ui.edit.ViewSampleActivity"/>
<activity android:name=".external.widget.ScriptWidgetSettingsActivity_">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</intent-filter>
</activity>
<activity <activity
android:name="com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity" android:name="com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity"
android:taskAffinity="com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity" android:taskAffinity="com.stardust.autojs.runtime.api.image.ScreenCaptureRequestActivity"
@@ -241,6 +246,15 @@
</intent-filter> </intent-filter>
</activity> </activity>
<receiver android:name=".external.widget.ScriptWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/script_widget_config"/>
</receiver>
<!-- 声明广告SDK所需要的组件 --> <!-- 声明广告SDK所需要的组件 -->
<service <service
android:name="com.qq.e.comm.DownloadService" android:name="com.qq.e.comm.DownloadService"

View File

@@ -1,3 +0,0 @@
module.exports = function(){
}

View File

@@ -0,0 +1,66 @@
"auto";
var 好友验证信息 = "AutoJs自动添加群好友";
var 延迟 = 500;
toast("请打开群成员列表");
var added = {};
while(true){
var list = className("AbsListView").findOne();
list.children().each(function(child){
if(child.className() != "android.widget.FrameLayout"){
return;
}
if(!isGroupMember(child)){
return;
}
if(isMyself(child)){
return;
}
child.child(0).click();
sleep(500);
addAsFriend();
sleep(延迟);
});
className("AbsListView").findOne().scrollForward();
}
function isGroupMember(child){
if(child.childCount() != 1){
return false;
}
return child.child(0) && child.child(0).className() == "android.widget.FrameLayout";
}
function isMyself(child){
var l = child.findByText("我");
return l && l.size() > 0;
}
function addAsFriend(){
var qq = getQQ();
if(added[qq]){
while(!click("返回"));
return;
}
added[qq] = true;
if(click("加好友")){
sleep(800);
setText(0, 好友验证信息);
while(!click("发送"));
sleep(800);
if(click("取消")){
sleep(400);
}
back();
}else{
back();
}
}
function getQQ(){
var qq = textMatches("\\d{5,12}").findOne().text();
return qq;
}

View File

@@ -5,21 +5,29 @@ function 下滑(){
} }
function (){ function (){
className("ImageView").desc("赞").click(); var like = className("ImageView").desc("赞").find();
if(like){
like.click();
return true;
}
return false;
} }
function 显示更多(){ function 显示更多(){
for(let i = 0; i < 2;i++){ for(let i = 0; i < 2;i++){
click("显示更多"); click("显示更多");
} }
} }
toast("请打开自己的资料页,点击点赞图标"); toast("请打开自己的资料页,点击点赞图标");
sleep(100); sleep(100);
waitForActivity("com.tencent.mobileqq.activity.VisitorsActivity");
while(notStopped()){ while(notStopped()){
for(let i = 0; i < 10; i++){ var i = 0;
(); while(i < 10){
i += () ? 1 : 0;
click("取消");
} }
显示更多(); 显示更多();
下滑(); 下滑();

View File

@@ -1,49 +0,0 @@
"auto";
var 延迟 = 0;
function 点赞(){
className("AbsListView").findOne()
.children().each(function(ss){
try{
var 一行 = 找到图标那一行(ss);
if(一行){
一行.child(1).click();
if(延迟 > 0){
sleep(延迟);
}
}
}catch(e){}
});
}
function 找到图标那一行(s){
for(let i = 0; i < s.getChildCount(); i++){
var child = s.child(i);
if(child && child.className()
.endsWith("RelativeLayout") &&
child.getChildCount() >= 4){
if(是图片(child.child(1)) &&
是图片(child.child(2)) &&
是图片(child.child(3))){
return child;
}
}
}
}
function 是图片(item){
return item &&
item.className().endsWith("ImageView");
}
function 下滑(){
className("AbsListView").findOne()
.scrollForward();
}
while(true){
点赞();
下滑();
}

View File

@@ -0,0 +1,71 @@
"auto";
var 延迟 = 0;
if(!requestScreenCapture()){
toast("请求截图失败");
stop();
}
var capture;
function like(){
capture = captureScreen();
className("AbsListView").findOne()
.children().each(function(ss){
try{
var iconLine = findIconLine(ss);
if(iconLine){
var likeIcon = iconLine.child(1).child(0);
if(notLiked(likeIcon)){
likeIcon.click();
}
if(延迟 > 0){
sleep(延迟);
}
}
}catch(e){
log(e);
}
});
}
function findIconLine(s){
for(let i = 0; i < s.getChildCount(); i++){
var child = s.child(i);
if(child && child.className()
.endsWith("RelativeLayout") &&
child.getChildCount() >= 4){
if(isImage(child.child(1)) &&
isImage(child.child(2)) &&
isImage(child.child(3))){
return child;
}
}
}
}
function isImage(item){
if(!item){
return false;
}
if(item.className().endsWith("ImageView")){
return true;
}
if(item.childCount() == 1){
return isImage(item.child(0));
}
return false;
}
function notLiked(likeIcon){
var x = likeIcon.bounds().centerX();
var y = likeIcon.bounds().centerY();
return images.detectsColor(capture, x, y, 0x767886);
}
toast("请打开QQ空间并慢慢下滑");
while(true){
like();
}

View File

@@ -1,5 +1,6 @@
"auto"; "auto";
//漏赞过多请稍微调大延迟 //漏赞过多请稍微调大延迟
var 延迟 = 200; var 延迟 = 200;

View File

@@ -1,10 +1,11 @@
"auto"; "auto";
toast("请打开一个聊天窗口"); toast("请打开一个聊天窗口");
sleep(500); sleep(500);
while(true){ while(true){
input("我喜欢你"); setText("我喜欢你");
click("发送"); click("发送");
sleep(200); sleep(200);
} }

View File

@@ -3,8 +3,8 @@
launchApp("网易云音乐"); launchApp("网易云音乐");
toast("打开一个歌曲的评论页面"); toast("打开一个歌曲的评论页面");
//循环直至当前为评论页面 //等待当前为评论页面
waitActivity("com.netease.cloudmusic.activity.ResourceCommentActivity"); waitForActivity("com.netease.cloudmusic.activity.ResourceCommentActivity");
while(true){ while(true){

View File

@@ -0,0 +1,12 @@
if(!requestScreenCapture()){
toast("请求截图失败");
}
sleep(2000);
var x = 760;
var y = 180;
//获取在点(x, y)处的颜色
var c = images.pixel(captureScreen(), x, y);
//显示该颜色
toast((c >>> 0).toString(16));
//检测在点(x, y)处是否有颜色0x73bdb6 (模糊比较)
toast(images.detectsColor(captureScreen(), x, y, 0x73bdb6))

View File

@@ -83,10 +83,6 @@ public class App extends MultiDexApplication {
} }
public static String getResString(int id) {
return getApp().getString(id);
}
public VolumeChangeObserver getVolumeChangeObserver() { public VolumeChangeObserver getVolumeChangeObserver() {
return mVolumeChangeObserver; return mVolumeChangeObserver;
} }

View File

@@ -8,15 +8,13 @@ import com.stardust.autojs.runtime.api.AutomatorConfig;
import com.stardust.automator.AccessibilityEventCommandHost; import com.stardust.automator.AccessibilityEventCommandHost;
import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.autojs.AutoJs;
import org.mozilla.javascript.tools.debugger.Dim;
import org.mozilla.javascript.tools.debugger.GuiCallback;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
/** /**
* Created by Stardust on 2017/1/31. * Created by Stardust on 2017/1/31.
*/ */
public class Pref { public class Pref {
private static final boolean enableRemoveAdOption = true;
private static final SharedPreferences DISPOSABLE_BOOLEAN = App.getApp().getSharedPreferences("DISPOSABLE_BOOLEAN", Context.MODE_PRIVATE); private static final SharedPreferences DISPOSABLE_BOOLEAN = App.getApp().getSharedPreferences("DISPOSABLE_BOOLEAN", Context.MODE_PRIVATE);
private static final String KEY_SERVER_ADDRESS = "Still love you...17.5.14"; private static final String KEY_SERVER_ADDRESS = "Still love you...17.5.14";
@@ -99,7 +97,7 @@ public class Pref {
} }
private static String getString(int id) { private static String getString(int id) {
return App.getResString(id); return App.getApp().getString(id);
} }
public static int getMaxTextLengthForCodeCompletion() { public static int getMaxTextLengthForCodeCompletion() {
@@ -147,6 +145,9 @@ public class Pref {
def().edit().putLong(KEY_LAST_SHOW_AD_MILLIS, System.currentTimeMillis()).apply(); def().edit().putLong(KEY_LAST_SHOW_AD_MILLIS, System.currentTimeMillis()).apply();
return true; return true;
case "Off": case "Off":
if (enableRemoveAdOption) {
return false;
}
lastShowMillis = def().getLong(KEY_LAST_SHOW_AD_MILLIS, 0); lastShowMillis = def().getLong(KEY_LAST_SHOW_AD_MILLIS, 0);
if (System.currentTimeMillis() - lastShowMillis < TimeUnit.DAYS.toMillis(2)) { if (System.currentTimeMillis() - lastShowMillis < TimeUnit.DAYS.toMillis(2)) {
return false; return false;

View File

@@ -51,15 +51,17 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
@BindView(R.id.text_start_or_pause) @BindView(R.id.text_start_or_pause)
TextView mStartOrPauseRecordText; TextView mStartOrPauseRecordText;
@BindView(R.id.stop_record) @BindView(R.id.stop_record)
View mStopRecord; View mStopRecord;
@BindView(R.id.discard_record)
View mDiscardRecord;
private Recorder mRecorder; private Recorder mRecorder;
private Context mContext; private Context mContext;
private boolean mDiscard = false;
private KeyObserver mKeyObserver; private KeyObserver mKeyObserver;
private VolumeChangeObserver.OnVolumeChangeListener mOnVolumeChangeListener = new VolumeChangeObserver.OnVolumeChangeListener() { private VolumeChangeObserver.OnVolumeChangeListener mOnVolumeChangeListener = new VolumeChangeObserver.OnVolumeChangeListener() {
@Override @Override
public void onVolumeChange() { public void onVolumeChange() {
@@ -123,6 +125,12 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
} }
} }
@OnClick(R.id.discard_record)
void discardRecord() {
mDiscard = true;
stopRecord();
}
private void resumeRecord() { private void resumeRecord() {
mRecorder.resume(); mRecorder.resume();
setState(Recorder.STATE_RECORDING); setState(Recorder.STATE_RECORDING);
@@ -135,6 +143,7 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
} }
private void startRecord() { private void startRecord() {
mDiscard = false;
mRecorder = mRecordedByRootSwitch.isChecked() ? new TouchRecorder(mContext) : AutoJs.getInstance().getAccessibilityActionRecorder(); mRecorder = mRecordedByRootSwitch.isChecked() ? new TouchRecorder(mContext) : AutoJs.getInstance().getAccessibilityActionRecorder();
mRecorder.setOnStateChangedListener(this); mRecorder.setOnStateChangedListener(this);
mRecorder.start(); mRecorder.start();
@@ -144,6 +153,7 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
private void setState(int state) { private void setState(int state) {
mStopRecord.setVisibility(state == Recorder.STATE_STOPPED ? View.GONE : View.VISIBLE); mStopRecord.setVisibility(state == Recorder.STATE_STOPPED ? View.GONE : View.VISIBLE);
mDiscardRecord.setVisibility(state == Recorder.STATE_STOPPED ? View.GONE : View.VISIBLE);
mStartOrPauseRecordIcon.setImageResource(state == Recorder.STATE_RECORDING ? R.drawable.ic_pause_white_24dp : R.drawable.ic_play_arrow_white_48dp); mStartOrPauseRecordIcon.setImageResource(state == Recorder.STATE_RECORDING ? R.drawable.ic_pause_white_24dp : R.drawable.ic_play_arrow_white_48dp);
//我知道这样写代码会被打 但我懒... //我知道这样写代码会被打 但我懒...
mStartOrPauseRecordText.setText(state == Recorder.STATE_RECORDING ? R.string.text_pause_record : mStartOrPauseRecordText.setText(state == Recorder.STATE_RECORDING ? R.string.text_pause_record :
@@ -191,7 +201,9 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat
@Override @Override
public void onStop() { public void onStop() {
MainActivity.onRecordStop(mContext, mRecorder.getCode()); if (!mDiscard) {
MainActivity.onRecordStop(mContext, mRecorder.getCode());
}
mRecorder = null; mRecorder = null;
} }

View File

@@ -27,8 +27,8 @@ public class LayoutInspector {
mCapture = null; mCapture = null;
} else { } else {
final AccessibilityNodeInfo root = service.getRootInActiveWindow(); final AccessibilityNodeInfo root = service.getRootInActiveWindow();
Log.d(LOG_TAG, "captureCurrentWindow: root = null");
if (root == null) { if (root == null) {
Log.d(LOG_TAG, "captureCurrentWindow: root = null");
mCapture = null; mCapture = null;
} else { } else {
mExecutor.execute(new Runnable() { mExecutor.execute(new Runnable() {

View File

@@ -1,6 +1,7 @@
package com.stardust.scriptdroid.external.open; package com.stardust.scriptdroid.external.open;
import android.content.Intent; import android.content.Intent;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.text.TextUtils; import android.text.TextUtils;
@@ -10,6 +11,8 @@ import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.main.MainActivity; import com.stardust.scriptdroid.ui.main.MainActivity;
import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.R;
import java.io.FileNotFoundException;
/** /**
* Created by Stardust on 2017/2/2. * Created by Stardust on 2017/2/2.
*/ */
@@ -30,13 +33,25 @@ public class ImportIntentActivity extends BaseActivity {
@Override @Override
protected void onNewIntent(Intent intent) { protected void onNewIntent(Intent intent) {
handleIntent(intent); try {
handleIntent(intent);
} catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(this, R.string.edit_and_run_handle_intent_error, Toast.LENGTH_LONG).show();
finish();
}
} }
private void handleIntent(Intent intent) { private void handleIntent(Intent intent) throws FileNotFoundException {
final String path = intent.getData().getPath(); Uri uri = intent.getData();
if (!TextUtils.isEmpty(path)) if (uri != null && "content".equals(uri.getScheme())) {
MainActivity.importScriptFile(this, path); MainActivity.importScriptFileByInputStream(this, getContentResolver().openInputStream(uri));
} else {
final String path = intent.getData().getPath();
if (!TextUtils.isEmpty(path)) {
MainActivity.importScriptFile(this, path);
}
}
finish(); finish();
} }

View File

@@ -0,0 +1,58 @@
package com.stardust.scriptdroid.external.widget;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
import com.stardust.pio.PFile;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.external.CommonUtils;
import com.stardust.scriptdroid.external.open.RunIntentActivity;
import java.util.HashSet;
import java.util.Set;
/**
* Created by Stardust on 2017/7/11.
*/
public class ScriptWidget extends AppWidgetProvider {
private static final String LOG_TAG = "ScriptWidget";
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
Set<Integer> appWidgetIdSet = new HashSet<>();
for (int appWidgetId : appWidgetIds) {
updateWidget(context, appWidgetId, ScriptWidgets.getPathForAppWidgetId(appWidgetId));
appWidgetIdSet.add(appWidgetId);
}
if (appWidgetIdSet.size() > 1)
ScriptWidgets.removeAllNotIn(appWidgetIdSet);
}
static boolean updateWidget(Context context, int widgetId, String path) {
if (TextUtils.isEmpty(path) || widgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
return false;
}
String name = PFile.getNameWithoutExtension(path);
int requestCode = ScriptWidgets.getRequestCodeForAppWidgetId(widgetId);
Log.d(LOG_TAG, "updateWidget: id = " + widgetId + ", requestCode = " + requestCode + ", path = " + path);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_script_shortcut);
views.setOnClickPendingIntent(R.id.widget, PendingIntent.getActivity(context, requestCode,
new Intent(context, RunIntentActivity.class)
.putExtra(CommonUtils.EXTRA_KEY_PATH, path)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK), PendingIntent.FLAG_UPDATE_CURRENT));
views.setTextViewText(R.id.name, name);
appWidgetManager.updateAppWidget(widgetId, views);
ScriptWidgets.setPathForAppWidgetId(widgetId, path);
return true;
}
}

View File

@@ -0,0 +1,100 @@
package com.stardust.scriptdroid.external.widget;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.RemoteViews;
import android.widget.Toast;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.external.CommonUtils;
import com.stardust.scriptdroid.external.open.RunIntentActivity;
import com.stardust.scriptdroid.external.tasker.TaskerScriptEditActivity;
import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.scriptdroid.script.StorageScriptProvider;
import com.stardust.scriptdroid.ui.BaseActivity;
import com.stardust.scriptdroid.ui.main.script_list.ScriptAndFolderListRecyclerView;
import com.stardust.scriptdroid.ui.main.script_list.ScriptListWithProgressBarView;
import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EActivity;
/**
* Created by Stardust on 2017/7/11.
*/
@EActivity(R.layout.activity_script_widget_settings)
public class ScriptWidgetSettingsActivity extends BaseActivity {
private String mSelectedScriptFilePath;
private StorageScriptProvider mStorageScriptProvider;
private int mAppWidgetId;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAppWidgetId = getIntent().getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
@AfterViews
void setUpViews() {
BaseActivity.setToolbarAsBack(this, R.id.toolbar, getString(R.string.text_please_choose_a_script));
initScriptListRecyclerView();
}
private void initScriptListRecyclerView() {
mStorageScriptProvider = StorageScriptProvider.getExternalStorageProvider();
ScriptListWithProgressBarView scriptList = (ScriptListWithProgressBarView) findViewById(R.id.script_list);
scriptList.setScriptFileOperationEnabled(false);
scriptList.setStorageScriptProvider(mStorageScriptProvider);
scriptList.setCurrentDirectory(StorageScriptProvider.DEFAULT_DIRECTORY);
scriptList.setOnItemClickListener(new ScriptAndFolderListRecyclerView.OnScriptFileClickListener() {
@Override
public void onClick(ScriptFile file, int position) {
mSelectedScriptFilePath = file.getPath();
finish();
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.action_refresh) {
mStorageScriptProvider.refreshAll();
} else if (item.getItemId() == R.id.action_clear_file_selection) {
mSelectedScriptFilePath = null;
}
return true;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.script_widget_settings_menu, menu);
return true;
}
@Override
public void finish() {
if (ScriptWidget.updateWidget(this, mAppWidgetId, mSelectedScriptFilePath)) {
setResult(RESULT_OK, new Intent()
.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId));
} else {
setResult(RESULT_CANCELED, new Intent()
.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId));
}
super.finish();
}
}

View File

@@ -0,0 +1,72 @@
package com.stardust.scriptdroid.external.widget;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import com.stardust.scriptdroid.App;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Created by Stardust on 2017/7/11.
*/
public class ScriptWidgets {
private static final String LOG_TAG = "ScriptWidgets";
private static SharedPreferences widgets = App.getApp().getSharedPreferences("ScriptWidgets", Context.MODE_PRIVATE);
private static final Pattern ID_PATTERN = Pattern.compile("[a-zA-Z]+_([0-9])+");
static String getPathForAppWidgetId(int id) {
return widgets.getString("path_" + id, null);
}
static void setPathForAppWidgetId(int id, String path) {
widgets.edit().putString("path_" + id, path).apply();
}
static int getRequestCodeForAppWidgetId(int id) {
int requestCode = widgets.getInt("rc_" + id, -1);
if (requestCode == -1) {
requestCode = widgets.getInt("max_rc", 0) + 1;
widgets.edit()
.putInt("rc_" + id, requestCode)
.putInt("max_rc", requestCode)
.apply();
}
return requestCode;
}
static void removeAllNotIn(Set<Integer> appWidgetIdSet) {
List<String> keysToRemove = new LinkedList<>();
for (Map.Entry<String, ?> entry : widgets.getAll().entrySet()) {
if (entry.getKey().equals("max_rc")) {
continue;
}
Matcher matcher = ID_PATTERN.matcher(entry.getKey());
if (matcher.find()) {
int id = Integer.parseInt(matcher.group(1));
if (!appWidgetIdSet.contains(id)) {
keysToRemove.add(entry.getKey());
}
} else {
Log.w(LOG_TAG, "illegal key: " + entry.getKey());
keysToRemove.add(entry.getKey());
}
}
SharedPreferences.Editor editor = widgets.edit();
for (String key : keysToRemove) {
editor.remove(key);
Log.v(LOG_TAG, "remove key: " + key);
}
editor.apply();
}
}

View File

@@ -2,6 +2,8 @@ package com.stardust.scriptdroid.ui;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable; import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi; import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
@@ -26,7 +28,9 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public abstract class BaseActivity extends AppCompatActivity { public abstract class BaseActivity extends AppCompatActivity {
protected static final int PERMISSION_REQUEST_CODE = 11186; protected static final int PERMISSION_REQUEST_CODE = 11186;
private static boolean isRequestingPermissions = false;
private BackPressedHandler.Observer mBackPressObserver = new BackPressedHandler.Observer(); private BackPressedHandler.Observer mBackPressObserver = new BackPressedHandler.Observer();
@Override @Override
@@ -62,9 +66,14 @@ public abstract class BaseActivity extends AppCompatActivity {
protected void checkPermission(String... permissions) { protected void checkPermission(String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (isRequestingPermissions) {
return;
}
String[] requestPermissions = getRequestPermissions(permissions); String[] requestPermissions = getRequestPermissions(permissions);
if (requestPermissions.length > 0) if (requestPermissions.length > 0) {
isRequestingPermissions = true;
requestPermissions(requestPermissions, PERMISSION_REQUEST_CODE); requestPermissions(requestPermissions, PERMISSION_REQUEST_CODE);
}
} else { } else {
int[] grantResults = new int[permissions.length]; int[] grantResults = new int[permissions.length];
Arrays.fill(grantResults, PERMISSION_GRANTED); Arrays.fill(grantResults, PERMISSION_GRANTED);
@@ -72,6 +81,7 @@ public abstract class BaseActivity extends AppCompatActivity {
} }
} }
@RequiresApi(api = Build.VERSION_CODES.M) @RequiresApi(api = Build.VERSION_CODES.M)
private String[] getRequestPermissions(String[] permissions) { private String[] getRequestPermissions(String[] permissions) {
List<String> list = new ArrayList<>(); List<String> list = new ArrayList<>();
@@ -112,4 +122,11 @@ public abstract class BaseActivity extends AppCompatActivity {
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
} }
} }
@CallSuper
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
isRequestingPermissions = false;
}
} }

View File

@@ -36,10 +36,12 @@ import com.stardust.scriptdroid.Pref;
import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.autojs.AutoJs; import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.external.floatingwindow.HoverMenuManger; import com.stardust.scriptdroid.external.floatingwindow.HoverMenuManger;
import com.stardust.scriptdroid.external.open.ImportIntentActivity;
import com.stardust.scriptdroid.script.ScriptFile; import com.stardust.scriptdroid.script.ScriptFile;
import com.stardust.scriptdroid.script.StorageScriptProvider; import com.stardust.scriptdroid.script.StorageScriptProvider;
import com.stardust.scriptdroid.script.sample.Sample; import com.stardust.scriptdroid.script.sample.Sample;
import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment_; import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment_;
import com.stardust.util.IntentExtras;
import com.stardust.view.accessibility.AccessibilityService; import com.stardust.view.accessibility.AccessibilityService;
import com.stardust.scriptdroid.tool.AccessibilityServiceTool; import com.stardust.scriptdroid.tool.AccessibilityServiceTool;
import com.stardust.scriptdroid.tool.DrawableSaver; import com.stardust.scriptdroid.tool.DrawableSaver;
@@ -66,6 +68,7 @@ import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.Subscribe;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
@EActivity(R.layout.activity_main) @EActivity(R.layout.activity_main)
public class MainActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHost { public class MainActivity extends BaseActivity implements OnActivityResultDelegate.DelegateHost {
@@ -81,6 +84,7 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
private static final String ARGUMENT_PATH = "ARGUMENT_PATH"; 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 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 static final String ARGUMENT_SAMPLE = "Take a chance on me...ok...?";
private static final String ARGUMENT_INPUT_STREAM = "17.7.12, Hi...could we start all over again...";
@ViewById(R.id.drawer_layout) @ViewById(R.id.drawer_layout)
@@ -306,7 +310,10 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
return; return;
switch (action) { switch (action) {
case ACTION_ON_ACTION_RECORD_STOPPED: case ACTION_ON_ACTION_RECORD_STOPPED:
handleRecordedScript(intent.getStringExtra(ARGUMENT_SCRIPT)); IntentExtras extras = IntentExtras.fromIntent(intent);
String script = extras.get(ARGUMENT_SCRIPT);
extras.clear();
handleRecordedScript(script);
break; break;
case ACTION_IMPORT_SCRIPT: case ACTION_IMPORT_SCRIPT:
handleImportScriptFile(intent); handleImportScriptFile(intent);
@@ -323,10 +330,17 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
if (fragment == null) { if (fragment == null) {
mIntentToHandle = intent; mIntentToHandle = intent;
} else { } else {
fragment.importFile(intent.getStringExtra(ARGUMENT_PATH)); String path = intent.getStringExtra(ARGUMENT_PATH);
if (path != null) {
fragment.importFile(intent.getStringExtra(ARGUMENT_PATH));
return;
}
InputStream inputStream = IntentExtras.fromIntent(intent).getAndClear(ARGUMENT_INPUT_STREAM);
fragment.importFile("", inputStream);
} }
} }
private void handleImportSample(Intent intent) { private void handleImportSample(Intent intent) {
mViewPager.setCurrentItem(0, true); mViewPager.setCurrentItem(0, true);
MyScriptListFragment fragment = getMyScriptListFragment(); MyScriptListFragment fragment = getMyScriptListFragment();
@@ -388,6 +402,16 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
.putExtra(ARGUMENT_PATH, path)); .putExtra(ARGUMENT_PATH, path));
} }
public static void importScriptFileByInputStream(Context context, InputStream inputStream) {
Intent intent = new Intent(context, MainActivity_.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP)
.putExtra(EXTRA_ACTION, ACTION_IMPORT_SCRIPT);
IntentExtras.newExtras()
.put(ARGUMENT_INPUT_STREAM, inputStream)
.putInIntent(intent);
context.startActivity(intent);
}
public static void importSample(Context context, Sample sample) { public static void importSample(Context context, Sample sample) {
context.startActivity(new Intent(context, MainActivity_.class) context.startActivity(new Intent(context, MainActivity_.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP)
@@ -442,6 +466,7 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
StorageScriptProvider.getDefault().notifyStoragePermissionGranted(); StorageScriptProvider.getDefault().notifyStoragePermissionGranted();
} }
@@ -456,8 +481,10 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
public static void onRecordStop(Context context, String script) { public static void onRecordStop(Context context, String script) {
Intent intent = new Intent(context, MainActivity_.class) Intent intent = new Intent(context, MainActivity_.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
.putExtra(EXTRA_ACTION, ACTION_ON_ACTION_RECORD_STOPPED) .putExtra(EXTRA_ACTION, ACTION_ON_ACTION_RECORD_STOPPED);
.putExtra(ARGUMENT_SCRIPT, script); IntentExtras.newExtras()
.put(ARGUMENT_SCRIPT, script)
.putInIntent(intent);
context.startActivity(intent); context.startActivity(intent);
} }
@@ -466,4 +493,6 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega
public OnActivityResultDelegate.Mediator getOnActivityResultDelegateMediator() { public OnActivityResultDelegate.Mediator getOnActivityResultDelegateMediator() {
return mActivityResultMediator; return mActivityResultMediator;
} }
} }

View File

@@ -78,7 +78,6 @@ public class SplashActivity extends BaseActivity {
@Override @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults); super.onRequestPermissionsResult(requestCode, permissions, grantResults);
} }
@Override @Override

Binary file not shown.

After

Width:  |  Height:  |  Size: 901 B

View File

@@ -0,0 +1,33 @@
<?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:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clipToPadding="false"
android:theme="@style/AppTheme.AppBarOverlay">
<com.stardust.theme.widget.ThemeColorToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="@string/_app_name">
</com.stardust.theme.widget.ThemeColorToolbar>
</android.support.design.widget.AppBarLayout>
<com.stardust.scriptdroid.ui.main.script_list.ScriptListWithProgressBarView
android:id="@+id/script_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#fafafa"/>
</LinearLayout>

View File

@@ -148,6 +148,37 @@
</LinearLayout> </LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#c4c4c4"/>
<LinearLayout
android:id="@+id/discard_record"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:gravity="center_vertical"
android:paddingBottom="16dp"
android:paddingLeft="8dp"
android:paddingTop="16dp"
android:visibility="gone">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginRight="8dp"
android:src="@drawable/ic_close_white_24dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_discard_record"
android:textColor="@android:color/primary_text_dark"
android:textSize="16sp"/>
</LinearLayout>
<View <View
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="1dp" android:layout_height="1dp"

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/widget"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/icon"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:src="@drawable/ic_node_js_black"/>
<TextView
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:gravity="center"
android:maxLines="1"
android:textColor="@android:color/white"
android:textSize="12sp"/>
</LinearLayout>

View File

@@ -0,0 +1,19 @@
<?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_refresh"
android:icon="@drawable/ic_refresh_white_24dp"
android:orderInCategory="100"
android:title="@string/text_refresh"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_clear_file_selection"
android:orderInCategory="200"
android:title="@string/text_clear_file_selection"
app:showAsAction="never"/>
</menu>

View File

@@ -206,6 +206,7 @@
<string name="hint_loop_delay">延迟多少秒后开始循环</string> <string name="hint_loop_delay">延迟多少秒后开始循环</string>
<string name="text_number_format_error">格式错误</string> <string name="text_number_format_error">格式错误</string>
<string name="text_accessibility_settings">打开无障碍服务</string> <string name="text_accessibility_settings">打开无障碍服务</string>
<string name="text_discard_record">放弃录制</string>
<string-array name="record_control_keys"> <string-array name="record_control_keys">
<item></item> <item></item>
@@ -224,7 +225,7 @@
<string-array name="ad_showing_mode_keys"> <string-array name="ad_showing_mode_keys">
<item>默认</item> <item>默认</item>
<item>每天显示一次</item> <item>每天显示一次</item>
<item>两天显示一次</item> <item>关闭广告</item>
</string-array> </string-array>
<string-array name="ad_showing_mode_values"> <string-array name="ad_showing_mode_values">

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:configure="com.stardust.scriptdroid.external.widget.ScriptWidgetSettingsActivity_"
android:initialLayout="@layout/widget_script_shortcut"
android:minHeight="40dp"
android:minWidth="40dp"
android:previewImage="@drawable/ic_node_js_black"
android:resizeMode="none"/>

View File

@@ -6,6 +6,7 @@
<application <application
> >
<activity android:name=".execution.ScriptExecuteActivity"/> <activity android:name=".execution.ScriptExecuteActivity"/>
<service <service
android:name="com.stardust.view.accessibility.AccessibilityService" android:name="com.stardust.view.accessibility.AccessibilityService"
android:label="@string/_app_name" android:label="@string/_app_name"
@@ -18,6 +19,7 @@
android:resource="@xml/accessibility_service_config"/> android:resource="@xml/accessibility_service_config"/>
</service> </service>
</application> </application>
</manifest> </manifest>

View File

@@ -88,7 +88,7 @@ module.exports = function(__runtime__, scope){
}, arguments); }, arguments);
} }
automator.input = function(a, b){ automator.setText = function(a, b){
if(arguments.length == 1){ if(arguments.length == 1){
return __runtime__.automator.setText(__runtime__.automator.editable(-1), a); return __runtime__.automator.setText(__runtime__.automator.editable(-1), a);
}else{ }else{
@@ -96,8 +96,16 @@ module.exports = function(__runtime__, scope){
} }
} }
automator.input = function(a, b){
if(arguments.length == 1){
return __runtime__.automator.appendText(__runtime__.automator.editable(-1), a);
}else{
return __runtime__.automator.appendText(__runtime__.automator.editable(a), b);
}
}
scope.__asGlobal__(__runtime__.automator, ['back', 'home', 'powerDialog', 'notifications', 'quickSettings', 'recents', 'splitScreen']); scope.__asGlobal__(__runtime__.automator, ['back', 'home', 'powerDialog', 'notifications', 'quickSettings', 'recents', 'splitScreen']);
scope.__asGlobal__(automator, ['click', 'longClick', 'press', 'swipe', 'gesture', 'gestures', 'gestureAsync', 'gesturesAsync', 'scrollDown', 'scrollUp', 'input']); scope.__asGlobal__(automator, ['click', 'longClick', 'press', 'swipe', 'gesture', 'gestures', 'gestureAsync', 'gesturesAsync', 'scrollDown', 'scrollUp', 'input', 'setText']);
return automator; return automator;
} }

View File

@@ -41,7 +41,7 @@ module.exports = function(__runtime__, scope){
return __runtime__.info.getLatestActivity(); return __runtime__.info.getLatestActivity();
} }
scope.waitActivity = function(activity, delay){ scope.waitForActivity = function(activity, delay){
delay = delay || 200; delay = delay || 200;
while(scope.currentActivity() != activity){ while(scope.currentActivity() != activity){
sleep(delay); sleep(delay);

View File

@@ -1,18 +1,23 @@
module.exports = function(__runtime__, scope){ module.exports = function(__runtime__, scope){
var images = {}; var images = {};
if(android.os.Build.VERSION.SDK_INT < 19){
return images;
}
var colorFinder = __runtime__.images.colorFinder; var rtImages = __runtime__.getImages();
images.requestScreenCapture = __runtime__.images.requestScreenCapture.bind(__runtime__.images); var colorFinder = rtImages.colorFinder;
images.captureScreen = __runtime__.images.captureScreen.bind(__runtime__.images); images.requestScreenCapture = rtImages.requestScreenCapture.bind(rtImages);
images.saveImage = __runtime__.images.saveImage.bind(__runtime__.images); images.captureScreen = rtImages.captureScreen.bind(rtImages);
images.pixel = __runtime__.images.pixel; images.saveImage = rtImages.saveImage.bind(rtImages);
images.detectsColor = __runtime__.images.detectsColor.bind(__runtime__.images); images.pixel = rtImages.pixel;
images.detectsColor = rtImages.detectsColor.bind(rtImages);
images.findColor = function(img, color, options){ images.findColor = function(img, color, options){
if(typeof(color) == 'string'){ if(typeof(color) == 'string'){

View File

@@ -1,6 +1,7 @@
package com.stardust.autojs.runtime; package com.stardust.autojs.runtime;
import android.content.Context; import android.content.Context;
import android.os.Build;
import android.support.annotation.CallSuper; import android.support.annotation.CallSuper;
import com.stardust.autojs.engine.ScriptEngine; import com.stardust.autojs.engine.ScriptEngine;
@@ -40,12 +41,12 @@ public abstract class AbstractScriptRuntime {
@ScriptVariable @ScriptVariable
public UI ui; public UI ui;
@ScriptVariable
public Images images;
@ScriptVariable @ScriptVariable
public Dialogs dialogs; public Dialogs dialogs;
private Images images;
private static WeakReference<Context> applicationContext; private static WeakReference<Context> applicationContext;
public AbstractScriptRuntime(UiHandler uiHandler, Console console, AccessibilityBridge bridge, AppUtils appUtils, ScreenCaptureRequester screenCaptureRequester) { public AbstractScriptRuntime(UiHandler uiHandler, Console console, AccessibilityBridge bridge, AppUtils appUtils, ScreenCaptureRequester screenCaptureRequester) {
@@ -54,7 +55,9 @@ public abstract class AbstractScriptRuntime {
this.automator = new SimpleActionAutomator(bridge, this); this.automator = new SimpleActionAutomator(bridge, this);
this.info = bridge.getInfoProvider(); this.info = bridge.getInfoProvider();
this.ui = new UI(uiHandler.getContext()); this.ui = new UI(uiHandler.getContext());
images = new Images(uiHandler.getContext(), this, screenCaptureRequester); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
images = new Images(uiHandler.getContext(), this, screenCaptureRequester);
}
dialogs = new Dialogs(app, uiHandler); dialogs = new Dialogs(app, uiHandler);
} }
@@ -109,6 +112,12 @@ public abstract class AbstractScriptRuntime {
@CallSuper @CallSuper
public void onStop() { public void onStop() {
images.releaseScreenCapturer(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
images.releaseScreenCapturer();
}
}
public Object getImages() {
return images;
} }
} }

View File

@@ -3,6 +3,8 @@ package com.stardust.autojs.runtime.api.image;
import android.graphics.Point; import android.graphics.Point;
import android.graphics.Rect; import android.graphics.Rect;
import android.media.Image; import android.media.Image;
import android.os.Build;
import android.support.annotation.RequiresApi;
import com.stardust.autojs.runtime.ScriptInterruptedException; import com.stardust.autojs.runtime.ScriptInterruptedException;
import com.stardust.concurrent.VolatileBox; import com.stardust.concurrent.VolatileBox;
@@ -18,6 +20,7 @@ import java.util.concurrent.TimeUnit;
* Created by Stardust on 2017/5/18. * Created by Stardust on 2017/5/18.
*/ */
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public class ColorFinder { public class ColorFinder {
private static ThreadPoolExecutor sThreadPoolExecutor = new ThreadPoolExecutor(4, 16, 5, TimeUnit.MINUTES, new SynchronousQueue<Runnable>()); private static ThreadPoolExecutor sThreadPoolExecutor = new ThreadPoolExecutor(4, 16, 5, TimeUnit.MINUTES, new SynchronousQueue<Runnable>());

View File

@@ -10,6 +10,7 @@ import android.graphics.Matrix;
import android.media.Image; import android.media.Image;
import android.os.Build; import android.os.Build;
import android.support.annotation.RequiresApi; import android.support.annotation.RequiresApi;
import android.util.Log;
import com.stardust.autojs.runtime.AbstractScriptRuntime; import com.stardust.autojs.runtime.AbstractScriptRuntime;
import com.stardust.autojs.runtime.ScriptInterruptedException; import com.stardust.autojs.runtime.ScriptInterruptedException;
@@ -21,6 +22,7 @@ import com.stardust.util.ScreenMetrics;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Locale;
/** /**
* Created by Stardust on 2017/5/20. * Created by Stardust on 2017/5/20.
@@ -103,13 +105,20 @@ public class Images {
} }
public static int pixel(Image image, int x, int y) { public static int pixel(Image image, int x, int y) {
int originX = x;
int originY = y;
x = ScreenMetrics.rescaleX(x, image.getWidth());
y = ScreenMetrics.rescaleY(y, image.getHeight());
Image.Plane plane = image.getPlanes()[0]; Image.Plane plane = image.getPlanes()[0];
int offset = y * plane.getRowStride() + x * plane.getPixelStride(); int offset = y * plane.getRowStride() + x * plane.getPixelStride();
int c = plane.getBuffer().getInt(offset); int c = plane.getBuffer().getInt(offset);
Log.d("Images", String.format(Locale.getDefault(), "(%d, %d)→(%d, %d)", originX, originY, x, y));
return (c & 0xff000000) + ((c & 0xff) << 16) + (c & 0x00ff00) + ((c & 0xff0000) >> 16); return (c & 0xff000000) + ((c & 0xff) << 16) + (c & 0x00ff00) + ((c & 0xff0000) >> 16);
} }
public static int pixel(Bitmap bitmap, int x, int y) { public static int pixel(Bitmap bitmap, int x, int y) {
x = ScreenMetrics.rescaleX(x, bitmap.getWidth());
y = ScreenMetrics.rescaleY(y, bitmap.getHeight());
return bitmap.getPixel(x, y); return bitmap.getPixel(x, y);
} }

View File

@@ -10,6 +10,7 @@ import android.widget.TextView;
import com.stardust.enhancedfloaty.FloatyService; import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.enhancedfloaty.ResizableExpandableFloaty; import com.stardust.enhancedfloaty.ResizableExpandableFloaty;
import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow; import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow;
import com.stardust.util.ScreenMetrics;
import com.stardust.util.ViewUtil; import com.stardust.util.ViewUtil;
import com.stardust.autojs.R; import com.stardust.autojs.R;
@@ -30,6 +31,7 @@ public class ConsoleFloaty extends ResizableExpandableFloaty.AbstractResizableEx
setShouldRequestFocusWhenExpand(false); setShouldRequestFocusWhenExpand(false);
setInitialX(100); setInitialX(100);
setInitialY(1000); setInitialY(1000);
setCollapsedViewUnpressedAlpha(1.0f);
} }
@Override @Override
@@ -58,7 +60,7 @@ public class ConsoleFloaty extends ResizableExpandableFloaty.AbstractResizableEx
view.post(new Runnable() { view.post(new Runnable() {
@Override @Override
public void run() { public void run() {
ViewUtil.setViewMeasure(view, 800, 800); ViewUtil.setViewMeasure(view, ScreenMetrics.getDeviceScreenWidth() * 2 / 3, ScreenMetrics.getDeviceScreenHeight() / 3);
} }
}); });
} }

View File

@@ -124,6 +124,12 @@ public class StardustConsole extends AbstractConsole {
@Override @Override
public void show() { public void show() {
if (!SettingsCompat.canDrawOverlays(mUiHandler.getContext())) { if (!SettingsCompat.canDrawOverlays(mUiHandler.getContext())) {
mUiHandler.post(new Runnable() {
@Override
public void run() {
}
});
SettingsCompat.manageDrawOverlays(mUiHandler.getContext()); SettingsCompat.manageDrawOverlays(mUiHandler.getContext());
mUiHandler.toast(R.string.text_no_floating_window_permission); mUiHandler.toast(R.string.text_no_floating_window_permission);
} }

View File

@@ -109,12 +109,20 @@ public class SimpleActionAutomator {
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SELECT)); return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SELECT));
} }
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public boolean setText(ActionTarget target, String text) { public boolean setText(ActionTarget target, String text) {
mScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP); mScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP);
return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SET_TEXT, text)); return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SET_TEXT, text));
} }
@ScriptInterface
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public boolean appendText(ActionTarget target, String text) {
mScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP);
return performAction(target.createAction(UiObject.ACTION_APPEND_TEXT, text));
}
@ScriptInterface @ScriptInterface
public boolean back() { public boolean back() {
return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK); return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK);

View File

@@ -1,13 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="46dp" android:layout_width="wrap_content"
android:layout_height="46dp" android:layout_height="wrap_content"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:orientation="vertical"> android:orientation="vertical">
<ImageView <ImageView
android:layout_width="46dp" android:layout_width="46dp"
android:layout_height="46dp" android:layout_height="46dp"
android:padding="5dp"
android:src="@drawable/ic_debug_console"/> android:src="@drawable/ic_debug_console"/>
</LinearLayout> </LinearLayout>

View File

@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android" <accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeAllMask" android:accessibilityEventTypes="typeNotificationStateChanged|typeAnnouncement|typeAssistReadingContext|typeContextClicked|typeGestureDetectionEnd|typeGestureDetectionStart|typeTouchExplorationGestureEnd|typeTouchExplorationGestureStart|typeTouchInteractionEnd|typeTouchInteractionStart|typeViewAccessibilityFocusCleared|typeViewAccessibilityFocused|typeViewClicked|typeViewHoverEnter|typeViewHoverExit|typeViewFocused|typeViewLongClicked|typeViewScrolled|typeViewSelected|typeViewTextChanged|typeViewTextSelectionChanged|typeViewTextTraversedAtMovementGranularity|typeWindowContentChanged|typeWindowsChanged|typeWindowStateChanged"
android:accessibilityFeedbackType="feedbackGeneric" android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagRetrieveInteractiveWindows|flagIncludeNotImportantViews|flagReportViewIds|flagRequestEnhancedWebAccessibility" android:accessibilityFlags="flagIncludeNotImportantViews|flagReportViewIds|flagRetrieveInteractiveWindows|flagRequestEnhancedWebAccessibility"
android:canPerformGestures="true" android:canPerformGestures="true"
android:canRequestEnhancedWebAccessibility="true" android:canRequestEnhancedWebAccessibility="true"
android:canRetrieveWindowContent="true" android:canRetrieveWindowContent="true"
android:description="@string/text_accessibility_service_description" android:description="@string/text_accessibility_service_description"
android:notificationTimeout="0"/> android:notificationTimeout="100"/>

View File

@@ -36,6 +36,8 @@ import static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat.
public class UiObject extends AccessibilityNodeInfoCompat { public class UiObject extends AccessibilityNodeInfoCompat {
public static final int ACTION_APPEND_TEXT = 0x00200001;
private static final String TAG = "UiObject"; private static final String TAG = "UiObject";
private static final boolean DEBUG = false; private static final boolean DEBUG = false;
private static int notRecycledCount = 0; private static int notRecycledCount = 0;

View File

@@ -42,14 +42,18 @@ public class ActionFactory {
} }
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public static SimpleAction createActionWithEditableFilter(int action, int index, final String text) { public static SimpleAction createActionWithEditableFilter(final int action, int index, final String text) {
return new SearchTargetAction(action, new FilterAction.EditableFilter(index)) { return new SearchTargetAction(action, new FilterAction.EditableFilter(index)) {
@Override @Override
protected void performAction(UiObject node) { protected void performAction(UiObject node) {
Bundle args = new Bundle(); Bundle args = new Bundle();
args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, node.text() + text); if (action == AccessibilityNodeInfo.ACTION_SET_TEXT) {
node.performAction(getAction(), args); args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text);
} else {
args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, node.text() + text);
}
node.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, args);
} }
}; };
} }

View File

@@ -1,35 +0,0 @@
package com.stardust.uiautomator;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.InstrumentationInfo;
import android.widget.Toast;
import java.util.List;
/**
* Created by Stardust on 2017/5/9.
*/
public class Test {
private void runTests(Context context) {
final String packageName = context.getPackageName();
final List<InstrumentationInfo> list =
context.getPackageManager().queryInstrumentation(packageName, 0);
if (list.isEmpty()) {
Toast.makeText(context, "Cannot find instrumentation for " + packageName,
Toast.LENGTH_SHORT).show();
return;
}
final InstrumentationInfo instrumentationInfo = list.get(0);
final ComponentName componentName =
new ComponentName(instrumentationInfo.packageName,
instrumentationInfo.name);
if (!context.startInstrumentation(componentName, null, null)) {
Toast.makeText(context, "Cannot run instrumentation for " + packageName,
Toast.LENGTH_SHORT).show();
}
}
}

View File

@@ -59,13 +59,14 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi
@Override @Override
public void onAccessibilityEvent(final AccessibilityEvent event) { public void onAccessibilityEvent(final AccessibilityEvent event) {
Log.v(TAG, "onAccessibilityEvent: " + event); Log.v(TAG, "onAccessibilityEvent: " + event);
try { if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
|| event.getEventType() == AccessibilityEvent.TYPE_VIEW_HOVER_ENTER
|| event.getEventType() == AccessibilityEvent.TYPE_VIEW_HOVER_EXIT) {
AccessibilityNodeInfo root = super.getRootInActiveWindow(); AccessibilityNodeInfo root = super.getRootInActiveWindow();
Log.v(TAG, "getRootInActiveWindow: " + root); if (root != null) {
if (root != null)
mRootInActiveWindow = root; mRootInActiveWindow = root;
} catch (Exception ignored) { Log.d(TAG, "rootInActiveWindow: " + mRootInActiveWindow);
}
} }
if (!containsAllEventTypes && !eventTypes.contains(event.getEventType())) if (!containsAllEventTypes && !eventTypes.contains(event.getEventType()))
return; return;
@@ -81,6 +82,7 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi
} }
} }
@Override @Override
public void onInterrupt() { public void onInterrupt() {

View File

@@ -27,5 +27,5 @@ dependencies {
}) })
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
compile 'com.android.support:support-annotations:25.3.1' compile 'com.android.support:support-annotations:25.3.1'
compile 'com.github.czy1121:settingscompat:1.1.4' compile 'com.github.hyb1996:settingscompat:1.1.5'
} }

View File

@@ -0,0 +1,76 @@
package com.stardust.util;
import android.content.Intent;
import android.util.SparseArray;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Stardust on 2017/7/11.
*/
public class IntentExtras implements Serializable {
private static int mMaxId = -1;
private static final String EXTRA_ID = "com.stardust.util.IntentExtras.id";
private static SparseArray<Map<String, Object>> extraStore = new SparseArray<>();
public static IntentExtras newExtras() {
return new IntentExtras();
}
public static IntentExtras fromIntent(Intent intent) {
int id = intent.getIntExtra(EXTRA_ID, -1);
if (id < 0) {
throw new IllegalArgumentException("");
}
return new IntentExtras(id);
}
private Map<String, Object> mMap;
private int mId;
private IntentExtras() {
mMap = new HashMap<>();
mMaxId++;
mId = mMaxId;
extraStore.put(mId, mMap);
}
private IntentExtras(int id) {
mMap = extraStore.get(id);
mMaxId = id;
}
@SuppressWarnings("unchecked")
public <T> T get(String key) {
return (T) mMap.get(key);
}
@SuppressWarnings("unchecked")
public <T> T getAndClear(String key) {
T value = (T) mMap.get(key);
clear();
return value;
}
public IntentExtras put(String key, Object value) {
mMap.put(key, value);
return this;
}
public Intent putInIntent(Intent intent) {
intent.putExtra(EXTRA_ID, mMaxId);
return intent;
}
public void clear() {
extraStore.remove(mId);
mMap = null;
}
}

View File

@@ -49,6 +49,19 @@ public class ScreenMetrics {
return y * deviceScreenHeight / height; return y * deviceScreenHeight / height;
} }
public static int rescaleX(int x, int width) {
if (width == 0 || !initialized)
return x;
return x * width / deviceScreenWidth;
}
public static int rescaleY(int y, int height) {
if (height == 0 || !initialized)
return y;
return y * height / deviceScreenHeight;
}
private int mScreenWidth; private int mScreenWidth;
private int mScreenHeight; private int mScreenHeight;