diff --git a/app/build.gradle b/app/build.gradle index 869eabfb..84b91f85 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -9,8 +9,8 @@ android { applicationId "com.stardust.scriptdroid" minSdkVersion 17 targetSdkVersion 23 - versionCode 145 - versionName "2.0.13 Beta3" + versionCode 146 + versionName "2.0.14 Beta" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true ndk { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c5eb4e22..291f9110 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -80,6 +80,11 @@ + + + + + + + + + + + + 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; +} \ No newline at end of file diff --git a/app/src/main/assets/sample/QQ与微信/QQ名片点赞脚本.js b/app/src/main/assets/sample/QQ与微信/QQ名片点赞脚本.js index 94694c59..e5c8538b 100644 --- a/app/src/main/assets/sample/QQ与微信/QQ名片点赞脚本.js +++ b/app/src/main/assets/sample/QQ与微信/QQ名片点赞脚本.js @@ -5,21 +5,29 @@ function 下滑(){ } function 赞(){ - className("ImageView").desc("赞").click(); + var like = className("ImageView").desc("赞").find(); + if(like){ + like.click(); + return true; + } + return false; } function 显示更多(){ for(let i = 0; i < 2;i++){ click("显示更多"); - } + } } toast("请打开自己的资料页,点击点赞图标"); sleep(100); +waitForActivity("com.tencent.mobileqq.activity.VisitorsActivity"); while(notStopped()){ - for(let i = 0; i < 10; i++){ - 赞(); + var i = 0; + while(i < 10){ + i += 赞() ? 1 : 0; + click("取消"); } 显示更多(); 下滑(); diff --git a/app/src/main/assets/sample/QQ与微信/QQ空间点赞(没卵用).js b/app/src/main/assets/sample/QQ与微信/QQ空间点赞(没卵用).js deleted file mode 100644 index 41483d0e..00000000 --- a/app/src/main/assets/sample/QQ与微信/QQ空间点赞(没卵用).js +++ /dev/null @@ -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){ - 点赞(); - 下滑(); -} \ No newline at end of file diff --git a/app/src/main/assets/sample/QQ与微信/QQ空间点赞.js b/app/src/main/assets/sample/QQ与微信/QQ空间点赞.js new file mode 100644 index 00000000..3b6a4209 --- /dev/null +++ b/app/src/main/assets/sample/QQ与微信/QQ空间点赞.js @@ -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(); +} \ No newline at end of file diff --git a/app/src/main/assets/sample/QQ与微信/好友列表名片点赞(不完美).js b/app/src/main/assets/sample/QQ与微信/好友列表名片点赞(不完美).js index 8fc980d1..c948b2ac 100644 --- a/app/src/main/assets/sample/QQ与微信/好友列表名片点赞(不完美).js +++ b/app/src/main/assets/sample/QQ与微信/好友列表名片点赞(不完美).js @@ -1,5 +1,6 @@ "auto"; + //漏赞过多请稍微调大延迟 var 延迟 = 200; diff --git a/app/src/main/assets/sample/QQ与微信/循环发送消息.js b/app/src/main/assets/sample/QQ与微信/循环发送消息.js index 703dc4ad..a83816da 100644 --- a/app/src/main/assets/sample/QQ与微信/循环发送消息.js +++ b/app/src/main/assets/sample/QQ与微信/循环发送消息.js @@ -1,10 +1,11 @@ "auto"; + toast("请打开一个聊天窗口"); sleep(500); while(true){ - input("我喜欢你"); + setText("我喜欢你"); click("发送"); sleep(200); } \ No newline at end of file diff --git a/app/src/main/assets/sample/其他应用/网易云音乐批量点赞.js b/app/src/main/assets/sample/其他应用/网易云音乐批量点赞.js index 2b6209d3..990fd415 100644 --- a/app/src/main/assets/sample/其他应用/网易云音乐批量点赞.js +++ b/app/src/main/assets/sample/其他应用/网易云音乐批量点赞.js @@ -3,8 +3,8 @@ launchApp("网易云音乐"); toast("打开一个歌曲的评论页面"); -//循环直至当前为评论页面 -waitActivity("com.netease.cloudmusic.activity.ResourceCommentActivity"); +//等待当前为评论页面 +waitForActivity("com.netease.cloudmusic.activity.ResourceCommentActivity"); while(true){ diff --git a/app/src/main/assets/sample/图片与图色处理/颜色获取和检测.js b/app/src/main/assets/sample/图片与图色处理/颜色获取和检测.js new file mode 100644 index 00000000..bbaaaa40 --- /dev/null +++ b/app/src/main/assets/sample/图片与图色处理/颜色获取和检测.js @@ -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)) \ No newline at end of file diff --git a/app/src/main/java/com/stardust/scriptdroid/App.java b/app/src/main/java/com/stardust/scriptdroid/App.java index 363ad426..5e44b536 100644 --- a/app/src/main/java/com/stardust/scriptdroid/App.java +++ b/app/src/main/java/com/stardust/scriptdroid/App.java @@ -83,10 +83,6 @@ public class App extends MultiDexApplication { } - public static String getResString(int id) { - return getApp().getString(id); - } - public VolumeChangeObserver getVolumeChangeObserver() { return mVolumeChangeObserver; } diff --git a/app/src/main/java/com/stardust/scriptdroid/Pref.java b/app/src/main/java/com/stardust/scriptdroid/Pref.java index 07f848d8..be9fc2d3 100644 --- a/app/src/main/java/com/stardust/scriptdroid/Pref.java +++ b/app/src/main/java/com/stardust/scriptdroid/Pref.java @@ -8,15 +8,13 @@ import com.stardust.autojs.runtime.api.AutomatorConfig; import com.stardust.automator.AccessibilityEventCommandHost; 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; /** * Created by Stardust on 2017/1/31. */ 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 String KEY_SERVER_ADDRESS = "Still love you...17.5.14"; @@ -99,7 +97,7 @@ public class Pref { } private static String getString(int id) { - return App.getResString(id); + return App.getApp().getString(id); } public static int getMaxTextLengthForCodeCompletion() { @@ -147,6 +145,9 @@ public class Pref { def().edit().putLong(KEY_LAST_SHOW_AD_MILLIS, System.currentTimeMillis()).apply(); return true; case "Off": + if (enableRemoveAdOption) { + return false; + } lastShowMillis = def().getLong(KEY_LAST_SHOW_AD_MILLIS, 0); if (System.currentTimeMillis() - lastShowMillis < TimeUnit.DAYS.toMillis(2)) { return false; diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java index 60fc5e3a..5f67a444 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/content/RecordNavigatorContent.java @@ -51,15 +51,17 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat @BindView(R.id.text_start_or_pause) TextView mStartOrPauseRecordText; - @BindView(R.id.stop_record) View mStopRecord; + @BindView(R.id.discard_record) + View mDiscardRecord; + + private Recorder mRecorder; private Context mContext; - + private boolean mDiscard = false; private KeyObserver mKeyObserver; - private VolumeChangeObserver.OnVolumeChangeListener mOnVolumeChangeListener = new VolumeChangeObserver.OnVolumeChangeListener() { @Override 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() { mRecorder.resume(); setState(Recorder.STATE_RECORDING); @@ -135,6 +143,7 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat } private void startRecord() { + mDiscard = false; mRecorder = mRecordedByRootSwitch.isChecked() ? new TouchRecorder(mContext) : AutoJs.getInstance().getAccessibilityActionRecorder(); mRecorder.setOnStateChangedListener(this); mRecorder.start(); @@ -144,6 +153,7 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat private void setState(int state) { 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); //我知道这样写代码会被打 但我懒... mStartOrPauseRecordText.setText(state == Recorder.STATE_RECORDING ? R.string.text_pause_record : @@ -191,7 +201,9 @@ public class RecordNavigatorContent implements NavigatorContent, Recorder.OnStat @Override public void onStop() { - MainActivity.onRecordStop(mContext, mRecorder.getCode()); + if (!mDiscard) { + MainActivity.onRecordStop(mContext, mRecorder.getCode()); + } mRecorder = null; } diff --git a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/LayoutInspector.java b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/LayoutInspector.java index dbf4ab2f..e2a30562 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/LayoutInspector.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/floatingwindow/menu/layout_inspector/LayoutInspector.java @@ -27,8 +27,8 @@ public class LayoutInspector { mCapture = null; } else { final AccessibilityNodeInfo root = service.getRootInActiveWindow(); - Log.d(LOG_TAG, "captureCurrentWindow: root = null"); if (root == null) { + Log.d(LOG_TAG, "captureCurrentWindow: root = null"); mCapture = null; } else { mExecutor.execute(new Runnable() { diff --git a/app/src/main/java/com/stardust/scriptdroid/external/open/ImportIntentActivity.java b/app/src/main/java/com/stardust/scriptdroid/external/open/ImportIntentActivity.java index b6ff3d5c..50670127 100644 --- a/app/src/main/java/com/stardust/scriptdroid/external/open/ImportIntentActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/external/open/ImportIntentActivity.java @@ -1,6 +1,7 @@ package com.stardust.scriptdroid.external.open; import android.content.Intent; +import android.net.Uri; import android.os.Bundle; import android.support.annotation.Nullable; 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.R; +import java.io.FileNotFoundException; + /** * Created by Stardust on 2017/2/2. */ @@ -30,13 +33,25 @@ public class ImportIntentActivity extends BaseActivity { @Override 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) { - final String path = intent.getData().getPath(); - if (!TextUtils.isEmpty(path)) - MainActivity.importScriptFile(this, path); + private void handleIntent(Intent intent) throws FileNotFoundException { + Uri uri = intent.getData(); + if (uri != null && "content".equals(uri.getScheme())) { + MainActivity.importScriptFileByInputStream(this, getContentResolver().openInputStream(uri)); + } else { + final String path = intent.getData().getPath(); + if (!TextUtils.isEmpty(path)) { + MainActivity.importScriptFile(this, path); + } + } finish(); } diff --git a/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidget.java b/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidget.java new file mode 100644 index 00000000..03281557 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidget.java @@ -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 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; + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidgetSettingsActivity.java b/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidgetSettingsActivity.java new file mode 100644 index 00000000..70e35f42 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidgetSettingsActivity.java @@ -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(); + } + + +} diff --git a/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidgets.java b/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidgets.java new file mode 100644 index 00000000..b80f0d05 --- /dev/null +++ b/app/src/main/java/com/stardust/scriptdroid/external/widget/ScriptWidgets.java @@ -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 appWidgetIdSet) { + List keysToRemove = new LinkedList<>(); + for (Map.Entry 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(); + } +} diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/BaseActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/BaseActivity.java index 25e61e96..5ad9d5c6 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/BaseActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/BaseActivity.java @@ -2,6 +2,8 @@ package com.stardust.scriptdroid.ui; import android.os.Build; import android.os.Bundle; +import android.support.annotation.CallSuper; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.RequiresApi; import android.support.v7.app.AppCompatActivity; @@ -26,7 +28,9 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED; public abstract class BaseActivity extends AppCompatActivity { + protected static final int PERMISSION_REQUEST_CODE = 11186; + private static boolean isRequestingPermissions = false; private BackPressedHandler.Observer mBackPressObserver = new BackPressedHandler.Observer(); @Override @@ -62,9 +66,14 @@ public abstract class BaseActivity extends AppCompatActivity { protected void checkPermission(String... permissions) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (isRequestingPermissions) { + return; + } String[] requestPermissions = getRequestPermissions(permissions); - if (requestPermissions.length > 0) + if (requestPermissions.length > 0) { + isRequestingPermissions = true; requestPermissions(requestPermissions, PERMISSION_REQUEST_CODE); + } } else { int[] grantResults = new int[permissions.length]; Arrays.fill(grantResults, PERMISSION_GRANTED); @@ -72,6 +81,7 @@ public abstract class BaseActivity extends AppCompatActivity { } } + @RequiresApi(api = Build.VERSION_CODES.M) private String[] getRequestPermissions(String[] permissions) { List list = new ArrayList<>(); @@ -112,4 +122,11 @@ public abstract class BaseActivity extends AppCompatActivity { activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true); } } + + @CallSuper + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + isRequestingPermissions = false; + } } diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java index 3973202c..3c263cca 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/main/MainActivity.java @@ -36,10 +36,12 @@ import com.stardust.scriptdroid.Pref; import com.stardust.scriptdroid.R; import com.stardust.scriptdroid.autojs.AutoJs; 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.StorageScriptProvider; import com.stardust.scriptdroid.script.sample.Sample; import com.stardust.scriptdroid.ui.main.task.TaskManagerFragment_; +import com.stardust.util.IntentExtras; import com.stardust.view.accessibility.AccessibilityService; import com.stardust.scriptdroid.tool.AccessibilityServiceTool; import com.stardust.scriptdroid.tool.DrawableSaver; @@ -66,6 +68,7 @@ import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import java.io.IOException; +import java.io.InputStream; @EActivity(R.layout.activity_main) 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 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_INPUT_STREAM = "17.7.12, Hi...could we start all over again..."; @ViewById(R.id.drawer_layout) @@ -306,7 +310,10 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega return; switch (action) { 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; case ACTION_IMPORT_SCRIPT: handleImportScriptFile(intent); @@ -323,10 +330,17 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega if (fragment == null) { mIntentToHandle = intent; } 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) { mViewPager.setCurrentItem(0, true); MyScriptListFragment fragment = getMyScriptListFragment(); @@ -388,6 +402,16 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega .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) { context.startActivity(new Intent(context, MainActivity_.class) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP) @@ -442,6 +466,7 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); StorageScriptProvider.getDefault().notifyStoragePermissionGranted(); } @@ -456,8 +481,10 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega public static void onRecordStop(Context context, String script) { Intent intent = new Intent(context, MainActivity_.class) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - .putExtra(EXTRA_ACTION, ACTION_ON_ACTION_RECORD_STOPPED) - .putExtra(ARGUMENT_SCRIPT, script); + .putExtra(EXTRA_ACTION, ACTION_ON_ACTION_RECORD_STOPPED); + IntentExtras.newExtras() + .put(ARGUMENT_SCRIPT, script) + .putInIntent(intent); context.startActivity(intent); } @@ -466,4 +493,6 @@ public class MainActivity extends BaseActivity implements OnActivityResultDelega public OnActivityResultDelegate.Mediator getOnActivityResultDelegateMediator() { return mActivityResultMediator; } + + } \ No newline at end of file diff --git a/app/src/main/java/com/stardust/scriptdroid/ui/splash/SplashActivity.java b/app/src/main/java/com/stardust/scriptdroid/ui/splash/SplashActivity.java index 2ebb6a1b..8d2d81cb 100644 --- a/app/src/main/java/com/stardust/scriptdroid/ui/splash/SplashActivity.java +++ b/app/src/main/java/com/stardust/scriptdroid/ui/splash/SplashActivity.java @@ -78,7 +78,6 @@ public class SplashActivity extends BaseActivity { @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); - } @Override diff --git a/app/src/main/res/drawable/discard.png b/app/src/main/res/drawable/discard.png new file mode 100644 index 00000000..cdc318b0 Binary files /dev/null and b/app/src/main/res/drawable/discard.png differ diff --git a/app/src/main/res/layout/activity_script_widget_settings.xml b/app/src/main/res/layout/activity_script_widget_settings.xml new file mode 100644 index 00000000..0112221c --- /dev/null +++ b/app/src/main/res/layout/activity_script_widget_settings.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/floating_window_record.xml b/app/src/main/res/layout/floating_window_record.xml index 957bcba4..08243531 100644 --- a/app/src/main/res/layout/floating_window_record.xml +++ b/app/src/main/res/layout/floating_window_record.xml @@ -148,6 +148,37 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/script_widget_settings_menu.xml b/app/src/main/res/menu/script_widget_settings_menu.xml new file mode 100644 index 00000000..0409910d --- /dev/null +++ b/app/src/main/res/menu/script_widget_settings_menu.xml @@ -0,0 +1,19 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0847fbc5..9f1a0e13 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -206,6 +206,7 @@ 延迟多少秒后开始循环 格式错误 打开无障碍服务 + 放弃录制 @@ -224,7 +225,7 @@ 默认 每天显示一次 - 两天显示一次 + 关闭广告 diff --git a/app/src/main/res/xml/script_widget_config.xml b/app/src/main/res/xml/script_widget_config.xml new file mode 100644 index 00000000..4c7bec47 --- /dev/null +++ b/app/src/main/res/xml/script_widget_config.xml @@ -0,0 +1,8 @@ + + \ No newline at end of file diff --git a/autojs/src/main/AndroidManifest.xml b/autojs/src/main/AndroidManifest.xml index fd33788b..ed63e9a6 100644 --- a/autojs/src/main/AndroidManifest.xml +++ b/autojs/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ + + diff --git a/autojs/src/main/assets/modules/__automator__.js b/autojs/src/main/assets/modules/__automator__.js index 3163e61c..37351dd8 100644 --- a/autojs/src/main/assets/modules/__automator__.js +++ b/autojs/src/main/assets/modules/__automator__.js @@ -88,7 +88,7 @@ module.exports = function(__runtime__, scope){ }, arguments); } - automator.input = function(a, b){ + automator.setText = function(a, b){ if(arguments.length == 1){ return __runtime__.automator.setText(__runtime__.automator.editable(-1), a); }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__(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; } diff --git a/autojs/src/main/assets/modules/__general__.js b/autojs/src/main/assets/modules/__general__.js index f06e0ba1..8b652d48 100644 --- a/autojs/src/main/assets/modules/__general__.js +++ b/autojs/src/main/assets/modules/__general__.js @@ -41,7 +41,7 @@ module.exports = function(__runtime__, scope){ return __runtime__.info.getLatestActivity(); } - scope.waitActivity = function(activity, delay){ + scope.waitForActivity = function(activity, delay){ delay = delay || 200; while(scope.currentActivity() != activity){ sleep(delay); diff --git a/autojs/src/main/assets/modules/__images__.js b/autojs/src/main/assets/modules/__images__.js index e46d4566..e21ab0f1 100644 --- a/autojs/src/main/assets/modules/__images__.js +++ b/autojs/src/main/assets/modules/__images__.js @@ -1,18 +1,23 @@ module.exports = function(__runtime__, scope){ 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){ if(typeof(color) == 'string'){ diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java b/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java index c0872272..0ac908a8 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/AbstractScriptRuntime.java @@ -1,6 +1,7 @@ package com.stardust.autojs.runtime; import android.content.Context; +import android.os.Build; import android.support.annotation.CallSuper; import com.stardust.autojs.engine.ScriptEngine; @@ -40,12 +41,12 @@ public abstract class AbstractScriptRuntime { @ScriptVariable public UI ui; - @ScriptVariable - public Images images; @ScriptVariable public Dialogs dialogs; + private Images images; + private static WeakReference applicationContext; 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.info = bridge.getInfoProvider(); 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); } @@ -109,6 +112,12 @@ public abstract class AbstractScriptRuntime { @CallSuper public void onStop() { - images.releaseScreenCapturer(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + images.releaseScreenCapturer(); + } + } + + public Object getImages() { + return images; } } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorFinder.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorFinder.java index e9b46b51..d54fb3b9 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorFinder.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/image/ColorFinder.java @@ -3,6 +3,8 @@ package com.stardust.autojs.runtime.api.image; import android.graphics.Point; import android.graphics.Rect; import android.media.Image; +import android.os.Build; +import android.support.annotation.RequiresApi; import com.stardust.autojs.runtime.ScriptInterruptedException; import com.stardust.concurrent.VolatileBox; @@ -18,6 +20,7 @@ import java.util.concurrent.TimeUnit; * Created by Stardust on 2017/5/18. */ +@RequiresApi(api = Build.VERSION_CODES.KITKAT) public class ColorFinder { private static ThreadPoolExecutor sThreadPoolExecutor = new ThreadPoolExecutor(4, 16, 5, TimeUnit.MINUTES, new SynchronousQueue()); diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/api/image/Images.java b/autojs/src/main/java/com/stardust/autojs/runtime/api/image/Images.java index 9c51d107..ed716af9 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/api/image/Images.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/api/image/Images.java @@ -10,6 +10,7 @@ import android.graphics.Matrix; import android.media.Image; import android.os.Build; import android.support.annotation.RequiresApi; +import android.util.Log; import com.stardust.autojs.runtime.AbstractScriptRuntime; import com.stardust.autojs.runtime.ScriptInterruptedException; @@ -21,6 +22,7 @@ import com.stardust.util.ScreenMetrics; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.nio.ByteBuffer; +import java.util.Locale; /** * Created by Stardust on 2017/5/20. @@ -103,13 +105,20 @@ public class Images { } 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]; int offset = y * plane.getRowStride() + x * plane.getPixelStride(); 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); } 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); } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/console/ConsoleFloaty.java b/autojs/src/main/java/com/stardust/autojs/runtime/console/ConsoleFloaty.java index 2cf47dd2..b64a17a2 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/console/ConsoleFloaty.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/console/ConsoleFloaty.java @@ -10,6 +10,7 @@ import android.widget.TextView; import com.stardust.enhancedfloaty.FloatyService; import com.stardust.enhancedfloaty.ResizableExpandableFloaty; import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow; +import com.stardust.util.ScreenMetrics; import com.stardust.util.ViewUtil; import com.stardust.autojs.R; @@ -30,6 +31,7 @@ public class ConsoleFloaty extends ResizableExpandableFloaty.AbstractResizableEx setShouldRequestFocusWhenExpand(false); setInitialX(100); setInitialY(1000); + setCollapsedViewUnpressedAlpha(1.0f); } @Override @@ -58,7 +60,7 @@ public class ConsoleFloaty extends ResizableExpandableFloaty.AbstractResizableEx view.post(new Runnable() { @Override public void run() { - ViewUtil.setViewMeasure(view, 800, 800); + ViewUtil.setViewMeasure(view, ScreenMetrics.getDeviceScreenWidth() * 2 / 3, ScreenMetrics.getDeviceScreenHeight() / 3); } }); } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/console/StardustConsole.java b/autojs/src/main/java/com/stardust/autojs/runtime/console/StardustConsole.java index 4ddc063d..29c35c5e 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/console/StardustConsole.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/console/StardustConsole.java @@ -124,6 +124,12 @@ public class StardustConsole extends AbstractConsole { @Override public void show() { if (!SettingsCompat.canDrawOverlays(mUiHandler.getContext())) { + mUiHandler.post(new Runnable() { + @Override + public void run() { + + } + }); SettingsCompat.manageDrawOverlays(mUiHandler.getContext()); mUiHandler.toast(R.string.text_no_floating_window_permission); } diff --git a/autojs/src/main/java/com/stardust/autojs/runtime/simpleaction/SimpleActionAutomator.java b/autojs/src/main/java/com/stardust/autojs/runtime/simpleaction/SimpleActionAutomator.java index dc9c49ba..f9c698ca 100644 --- a/autojs/src/main/java/com/stardust/autojs/runtime/simpleaction/SimpleActionAutomator.java +++ b/autojs/src/main/java/com/stardust/autojs/runtime/simpleaction/SimpleActionAutomator.java @@ -109,12 +109,20 @@ public class SimpleActionAutomator { return performAction(target.createAction(AccessibilityNodeInfo.ACTION_SELECT)); } + @ScriptInterface @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) public boolean setText(ActionTarget target, String text) { mScriptRuntime.requiresApi(Build.VERSION_CODES.LOLLIPOP); 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 public boolean back() { return performGlobalAction(AccessibilityService.GLOBAL_ACTION_BACK); diff --git a/autojs/src/main/res/layout/floating_window_collapse.xml b/autojs/src/main/res/layout/floating_window_collapse.xml index 94250936..3fc26ba5 100644 --- a/autojs/src/main/res/layout/floating_window_collapse.xml +++ b/autojs/src/main/res/layout/floating_window_collapse.xml @@ -1,13 +1,12 @@ \ No newline at end of file diff --git a/autojs/src/main/res/xml/accessibility_service_config.xml b/autojs/src/main/res/xml/accessibility_service_config.xml index 28a7fdb7..9c541b8b 100644 --- a/autojs/src/main/res/xml/accessibility_service_config.xml +++ b/autojs/src/main/res/xml/accessibility_service_config.xml @@ -1,10 +1,10 @@ \ No newline at end of file + android:notificationTimeout="100"/> \ No newline at end of file diff --git a/automator/src/main/java/com/stardust/automator/UiObject.java b/automator/src/main/java/com/stardust/automator/UiObject.java index cf2f74f4..c7a95563 100644 --- a/automator/src/main/java/com/stardust/automator/UiObject.java +++ b/automator/src/main/java/com/stardust/automator/UiObject.java @@ -36,6 +36,8 @@ import static android.support.v4.view.accessibility.AccessibilityNodeInfoCompat. public class UiObject extends AccessibilityNodeInfoCompat { + public static final int ACTION_APPEND_TEXT = 0x00200001; + private static final String TAG = "UiObject"; private static final boolean DEBUG = false; private static int notRecycledCount = 0; diff --git a/automator/src/main/java/com/stardust/automator/simple_action/ActionFactory.java b/automator/src/main/java/com/stardust/automator/simple_action/ActionFactory.java index 1d444b05..9946cc72 100644 --- a/automator/src/main/java/com/stardust/automator/simple_action/ActionFactory.java +++ b/automator/src/main/java/com/stardust/automator/simple_action/ActionFactory.java @@ -42,14 +42,18 @@ public class ActionFactory { } @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)) { @Override protected void performAction(UiObject node) { Bundle args = new Bundle(); - args.putCharSequence(AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, node.text() + text); - node.performAction(getAction(), args); + if (action == AccessibilityNodeInfo.ACTION_SET_TEXT) { + 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); } }; } diff --git a/automator/src/main/java/com/stardust/uiautomator/Test.java b/automator/src/main/java/com/stardust/uiautomator/Test.java deleted file mode 100644 index bb1b74c0..00000000 --- a/automator/src/main/java/com/stardust/uiautomator/Test.java +++ /dev/null @@ -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 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(); - } - } -} diff --git a/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java b/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java index d93834ef..34e4f027 100644 --- a/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java +++ b/automator/src/main/java/com/stardust/view/accessibility/AccessibilityService.java @@ -59,13 +59,14 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi @Override public void onAccessibilityEvent(final AccessibilityEvent 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(); - Log.v(TAG, "getRootInActiveWindow: " + root); - if (root != null) + if (root != null) { mRootInActiveWindow = root; - } catch (Exception ignored) { - + Log.d(TAG, "rootInActiveWindow: " + mRootInActiveWindow); + } } if (!containsAllEventTypes && !eventTypes.contains(event.getEventType())) return; @@ -81,6 +82,7 @@ public class AccessibilityService extends android.accessibilityservice.Accessibi } } + @Override public void onInterrupt() { diff --git a/common/build.gradle b/common/build.gradle index a88e3f9a..363d1962 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -27,5 +27,5 @@ dependencies { }) testCompile 'junit:junit:4.12' 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' } diff --git a/common/src/main/java/com/stardust/util/IntentExtras.java b/common/src/main/java/com/stardust/util/IntentExtras.java new file mode 100644 index 00000000..cf70fff4 --- /dev/null +++ b/common/src/main/java/com/stardust/util/IntentExtras.java @@ -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> 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 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 get(String key) { + return (T) mMap.get(key); + } + + @SuppressWarnings("unchecked") + public 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; + } +} diff --git a/common/src/main/java/com/stardust/util/ScreenMetrics.java b/common/src/main/java/com/stardust/util/ScreenMetrics.java index 0f12791a..f3b7af83 100644 --- a/common/src/main/java/com/stardust/util/ScreenMetrics.java +++ b/common/src/main/java/com/stardust/util/ScreenMetrics.java @@ -49,6 +49,19 @@ public class ScreenMetrics { 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 mScreenHeight;