Added volume control
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -7,8 +7,8 @@ android {
|
||||
applicationId "com.stardust.scriptdroid"
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 23
|
||||
versionCode 28
|
||||
versionName "1.17.0216"
|
||||
versionCode 29
|
||||
versionName "1.17.0216(1)"
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
@@ -68,8 +68,9 @@ dependencies {
|
||||
compile 'com.afollestad.material-dialogs:commons:0.9.2.3'
|
||||
compile 'com.makeramen:roundedimageview:2.2.1'
|
||||
compile 'com.rengwuxian.materialedittext:library:2.0.3'
|
||||
compile 'org.msgpack:msgpack-core:0.8.11'
|
||||
compile(name: '920-common-release', ext: 'aar')
|
||||
compile(name: '920-styles-debug', ext: 'aar')
|
||||
compile(name: '920-styles-release', ext: 'aar')
|
||||
compile(name: '920-file_explorer-release', ext: 'aar')
|
||||
compile(name: '920-app-debug', ext: 'aar')
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -86,7 +86,8 @@
|
||||
<activity android:name=".droid.script.ScriptExecuteActivity"/>
|
||||
|
||||
<service android:name=".external.notification.bounds_assist.BoundsAssistSwitchNotificationHandleService"/>
|
||||
<service android:name=".external.notification.record.ActionRecordNotificationHandleService"/>
|
||||
<service android:name=".external.notification.record.ActionRecordSwitchHandleService"/>
|
||||
<service android:name=".service.VolumeChangeListenService"/>
|
||||
|
||||
<activity
|
||||
android:name=".ui.edit.EditAndRunIntentActivity"
|
||||
|
||||
@@ -38,13 +38,11 @@ public class App extends Application {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
if (LeakCanary.isInAnalyzerProcess(this)) {
|
||||
// This process is dedicated to LeakCanary for heap analysis.
|
||||
// You should not init your app in this process.
|
||||
return;
|
||||
}
|
||||
LeakCanary.install(this);
|
||||
if (!BuildConfig.DEBUG)
|
||||
Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(ErrorReportActivity.class));
|
||||
// if (!BuildConfig.DEBUG)
|
||||
Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(ErrorReportActivity.class));
|
||||
instance = new WeakReference<>(this);
|
||||
stateObserver = new StateObserver(PreferenceManager.getDefaultSharedPreferences(this));
|
||||
registerActivityLifecycleCallback();
|
||||
|
||||
@@ -32,7 +32,15 @@ public class Pref {
|
||||
return getDisposableBoolean("isFirstGoToAccessibilitySetting", true);
|
||||
}
|
||||
|
||||
public static int oldVersion(){
|
||||
public static int oldVersion() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static boolean isRecordVolumeControlEnable() {
|
||||
return def().getBoolean(getString(R.string.key_use_volume_control_record), false);
|
||||
}
|
||||
|
||||
private static String getString(int id) {
|
||||
return App.getApp().getString(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,11 +96,13 @@ public abstract class FilterAction extends Action {
|
||||
List<AccessibilityNodeInfo> editableList = findEditable(root);
|
||||
if (mIndex == -1)
|
||||
return editableList;
|
||||
if (mIndex >= editableList.size())
|
||||
return Collections.EMPTY_LIST;
|
||||
return Collections.singletonList(editableList.get(mIndex));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private List<AccessibilityNodeInfo> findEditable(AccessibilityNodeInfo root) {
|
||||
public static List<AccessibilityNodeInfo> findEditable(AccessibilityNodeInfo root) {
|
||||
if (root == null) {
|
||||
return Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.stardust.scriptdroid.external.notification.record;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
@@ -11,6 +12,7 @@ import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.record.AccessibilityRecorderDelegate;
|
||||
import com.stardust.scriptdroid.service.AccessibilityWatchDogService;
|
||||
import com.stardust.scriptdroid.service.VolumeChangeListenService;
|
||||
import com.stardust.scriptdroid.ui.main.MainActivity;
|
||||
|
||||
import static com.stardust.scriptdroid.external.notification.record.ActionRecordSwitchView.PAUSED;
|
||||
@@ -21,10 +23,10 @@ import static com.stardust.scriptdroid.external.notification.record.ActionRecord
|
||||
* Created by Stardust on 2017/2/15.
|
||||
*/
|
||||
|
||||
public class ActionRecordNotificationHandleService extends Service {
|
||||
public class ActionRecordSwitchHandleService extends Service {
|
||||
|
||||
|
||||
private static final String EXTRA_INTENT_VALID = "ActionRecordNotificationHandleService.intentValid";
|
||||
private static final String EXTRA_INTENT_VALID = "ActionRecordSwitchHandleService.intentValid";
|
||||
private static final String EXTRA_ACTION = "action";
|
||||
private static final int ACTION_STOP = 17771;
|
||||
private static final int ACTION_START_OR_PAUSE = 17772;
|
||||
@@ -32,21 +34,21 @@ public class ActionRecordNotificationHandleService extends Service {
|
||||
private static final int ACTION_REDO = 17774;
|
||||
|
||||
public static PendingIntent getStartOrPauseIntent() {
|
||||
Intent intent = new Intent(App.getApp(), ActionRecordNotificationHandleService.class)
|
||||
Intent intent = new Intent(App.getApp(), ActionRecordSwitchHandleService.class)
|
||||
.putExtra(EXTRA_INTENT_VALID, true)
|
||||
.putExtra(EXTRA_ACTION, ACTION_START_OR_PAUSE);
|
||||
return PendingIntent.getService(App.getApp(), ACTION_START_OR_PAUSE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
}
|
||||
|
||||
public static PendingIntent getStopIntent() {
|
||||
Intent intent = new Intent(App.getApp(), ActionRecordNotificationHandleService.class)
|
||||
Intent intent = new Intent(App.getApp(), ActionRecordSwitchHandleService.class)
|
||||
.putExtra(EXTRA_INTENT_VALID, true)
|
||||
.putExtra(EXTRA_ACTION, ACTION_STOP);
|
||||
return PendingIntent.getService(App.getApp(), ACTION_STOP, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
}
|
||||
|
||||
public static PendingIntent getDeleteIntent() {
|
||||
Intent intent = new Intent(App.getApp(), ActionRecordNotificationHandleService.class)
|
||||
Intent intent = new Intent(App.getApp(), ActionRecordSwitchHandleService.class)
|
||||
.putExtra(EXTRA_INTENT_VALID, true)
|
||||
.putExtra(EXTRA_ACTION, ACTION_DELETE);
|
||||
return PendingIntent.getService(App.getApp(), ACTION_DELETE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
@@ -54,7 +56,7 @@ public class ActionRecordNotificationHandleService extends Service {
|
||||
|
||||
|
||||
public static PendingIntent getRedoIntent() {
|
||||
Intent intent = new Intent(App.getApp(), ActionRecordNotificationHandleService.class)
|
||||
Intent intent = new Intent(App.getApp(), ActionRecordSwitchHandleService.class)
|
||||
.putExtra(EXTRA_INTENT_VALID, true)
|
||||
.putExtra(EXTRA_ACTION, ACTION_REDO);
|
||||
return PendingIntent.getService(App.getApp(), ACTION_REDO, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
@@ -74,19 +76,20 @@ public class ActionRecordNotificationHandleService extends Service {
|
||||
private void performAction(int action) {
|
||||
switch (action) {
|
||||
case ACTION_STOP:
|
||||
stopRecord();
|
||||
stopRecord(this);
|
||||
collapseNotificationBar();
|
||||
break;
|
||||
case ACTION_START_OR_PAUSE:
|
||||
startOrPauseRecord();
|
||||
startOrPauseRecord(this);
|
||||
collapseNotificationBar();
|
||||
break;
|
||||
case ACTION_DELETE:
|
||||
ActionRecordSwitchNotification.cancelNotification();
|
||||
stopRecordIfNeeded();
|
||||
VolumeChangeListenService.stopServiceIfNeeded();
|
||||
break;
|
||||
case ACTION_REDO:
|
||||
redoRecord();
|
||||
redoRecord(this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -98,41 +101,53 @@ public class ActionRecordNotificationHandleService extends Service {
|
||||
|
||||
private void stopRecordIfNeeded() {
|
||||
if (AccessibilityRecorderDelegate.getInstance().getState() != STOPPED) {
|
||||
stopRecord();
|
||||
stopRecord(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void startOrPauseRecord() {
|
||||
private static void startOrPauseRecord(Context context) {
|
||||
int state = AccessibilityRecorderDelegate.getInstance().getState();
|
||||
if (state == PAUSED) {
|
||||
AccessibilityRecorderDelegate.getInstance().resumeRecord();
|
||||
ActionRecordSwitchView.getInstance().setState(RECORDING);
|
||||
resumeRecord(context);
|
||||
} else if (state == RECORDING) {
|
||||
AccessibilityRecorderDelegate.getInstance().pauseRecord();
|
||||
ActionRecordSwitchView.getInstance().setState(PAUSED);
|
||||
pauseRecord(context);
|
||||
} else {
|
||||
//state == STOPPED
|
||||
if (AccessibilityWatchDogService.getInstance() == null) {
|
||||
Toast.makeText(this, R.string.text_need_enable_accessibility_service, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
AccessibilityRecorderDelegate.getInstance().startRecord();
|
||||
ActionRecordSwitchView.getInstance().setState(RECORDING);
|
||||
Toast.makeText(this, R.string.text_start_record, Toast.LENGTH_SHORT).show();
|
||||
startRecord(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopRecord() {
|
||||
public static void startRecord(Context context) {
|
||||
if (AccessibilityWatchDogService.getInstance() == null) {
|
||||
Toast.makeText(context, R.string.text_need_enable_accessibility_service, Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
AccessibilityRecorderDelegate.getInstance().startRecord();
|
||||
ActionRecordSwitchView.getInstance().setState(RECORDING);
|
||||
Toast.makeText(context, R.string.text_start_record, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private static void pauseRecord(Context context) {
|
||||
AccessibilityRecorderDelegate.getInstance().pauseRecord();
|
||||
ActionRecordSwitchView.getInstance().setState(PAUSED);
|
||||
}
|
||||
|
||||
private static void resumeRecord(Context context) {
|
||||
AccessibilityRecorderDelegate.getInstance().resumeRecord();
|
||||
ActionRecordSwitchView.getInstance().setState(RECORDING);
|
||||
}
|
||||
|
||||
public static void stopRecord(Context context) {
|
||||
if (AccessibilityRecorderDelegate.getInstance().getState() != STOPPED) {
|
||||
String script = AccessibilityRecorderDelegate.getInstance().stopRecord();
|
||||
ActionRecordSwitchView.getInstance().setState(STOPPED);
|
||||
MainActivity.onActionRecordStopped(this, script);
|
||||
MainActivity.onActionRecordStopped(context, script);
|
||||
} else {
|
||||
Toast.makeText(App.getApp(), R.string.text_not_recording, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void redoRecord() {
|
||||
private static void redoRecord(Context context) {
|
||||
if (AccessibilityRecorderDelegate.getInstance().getState() != STOPPED) {
|
||||
AccessibilityRecorderDelegate.getInstance().stopRecord();
|
||||
ActionRecordSwitchView.getInstance().setState(STOPPED);
|
||||
@@ -7,6 +7,7 @@ import android.support.v4.app.NotificationCompat;
|
||||
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.service.VolumeChangeListenService;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/14.
|
||||
@@ -23,10 +24,11 @@ public class ActionRecordSwitchNotification {
|
||||
builder = new NotificationCompat.Builder(App.getApp())
|
||||
.setAutoCancel(false)
|
||||
.setSmallIcon(R.drawable.ic_robot_head)
|
||||
.setDeleteIntent(ActionRecordNotificationHandleService.getDeleteIntent())
|
||||
.setDeleteIntent(ActionRecordSwitchHandleService.getDeleteIntent())
|
||||
.setCustomContentView(ActionRecordSwitchView.getInstance());
|
||||
}
|
||||
showNotification(builder.build());
|
||||
VolumeChangeListenService.startServiceIfNeeded(App.getApp());
|
||||
}
|
||||
|
||||
private static void showNotification(Notification notification) {
|
||||
|
||||
@@ -48,9 +48,9 @@ public class ActionRecordSwitchView extends RemoteViews {
|
||||
}
|
||||
|
||||
private void setUpOnClick() {
|
||||
setOnClickPendingIntent(R.id.stop, ActionRecordNotificationHandleService.getStopIntent());
|
||||
setOnClickPendingIntent(R.id.start_or_pause, ActionRecordNotificationHandleService.getStartOrPauseIntent());
|
||||
setOnClickPendingIntent(R.id.close, ActionRecordNotificationHandleService.getDeleteIntent());
|
||||
setOnClickPendingIntent(R.id.redo, ActionRecordNotificationHandleService.getRedoIntent());
|
||||
setOnClickPendingIntent(R.id.stop, ActionRecordSwitchHandleService.getStopIntent());
|
||||
setOnClickPendingIntent(R.id.start_or_pause, ActionRecordSwitchHandleService.getStartOrPauseIntent());
|
||||
setOnClickPendingIntent(R.id.close, ActionRecordSwitchHandleService.getDeleteIntent());
|
||||
setOnClickPendingIntent(R.id.redo, ActionRecordSwitchHandleService.getRedoIntent());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,8 +97,11 @@ public class ShortcutActivity extends Activity {
|
||||
}
|
||||
|
||||
private boolean hasStorageReadPermission() {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
|
||||
checkSelfPermission(READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED;
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
return Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
|
||||
checkSelfPermission(READ_EXTERNAL_STORAGE) == PERMISSION_GRANTED;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
interface Tile {
|
||||
|
||||
@@ -80,7 +80,7 @@ public class AccessibilityRecorderDelegate implements AccessibilityDelegate {
|
||||
@Override
|
||||
public boolean onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event) {
|
||||
if (mState == RECORDING) {
|
||||
mRecorder.record(event);
|
||||
mRecorder.record(service, event);
|
||||
checkTimeOut();
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
package com.stardust.scriptdroid.record;
|
||||
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.os.Build;
|
||||
import android.util.SparseArray;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
import android.view.accessibility.AccessibilityNodeInfo;
|
||||
|
||||
import com.stardust.scriptdroid.droid.runtime.action.FilterAction;
|
||||
import com.stardust.util.SparseArrayEntries;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.stardust.scriptdroid.bounds_assist.BoundsAssistant.boundsToString;
|
||||
import static com.stardust.scriptdroid.bounds_assist.BoundsAssistant.getBoundsInScreen;
|
||||
|
||||
@@ -21,6 +25,7 @@ public class ActionRecorder {
|
||||
.entry(AccessibilityEvent.TYPE_VIEW_CLICKED, new DoUtilSucceedConverter("click"))
|
||||
.entry(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED, new DoUtilSucceedConverter("longClick"))
|
||||
.entry(AccessibilityEvent.TYPE_VIEW_SCROLLED, new DoOnceConverter("//scroll???"))
|
||||
.entry(AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED, new SetTextEventConverter())
|
||||
.sparseArray();
|
||||
|
||||
static {
|
||||
@@ -32,14 +37,14 @@ public class ActionRecorder {
|
||||
private StringBuilder mScript = new StringBuilder();
|
||||
private boolean mFirstAction = true;
|
||||
|
||||
public void record(AccessibilityEvent event) {
|
||||
public void record(AccessibilityService service, AccessibilityEvent event) {
|
||||
EventToScriptConverter converter = CONVERTER_MAP.get(event.getEventType());
|
||||
if (converter != null) {
|
||||
if (mFirstAction) {
|
||||
mFirstAction = false;
|
||||
return;
|
||||
}
|
||||
converter.onAccessibilityEvent(event, mScript);
|
||||
converter.onAccessibilityEvent(service, event, mScript);
|
||||
mScript.append("\n");
|
||||
}
|
||||
}
|
||||
@@ -54,13 +59,13 @@ public class ActionRecorder {
|
||||
|
||||
interface EventToScriptConverter {
|
||||
|
||||
void onAccessibilityEvent(AccessibilityEvent event, StringBuilder sb);
|
||||
void onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event, StringBuilder sb);
|
||||
}
|
||||
|
||||
private static abstract class BoundsEventConverter implements EventToScriptConverter {
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityEvent event, StringBuilder sb) {
|
||||
public void onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event, StringBuilder sb) {
|
||||
AccessibilityNodeInfo source = event.getSource();
|
||||
if (source == null)
|
||||
return;
|
||||
@@ -101,4 +106,37 @@ public class ActionRecorder {
|
||||
}
|
||||
}
|
||||
|
||||
private static class SetTextEventConverter implements EventToScriptConverter {
|
||||
|
||||
@Override
|
||||
public void onAccessibilityEvent(AccessibilityService service, AccessibilityEvent event, StringBuilder sb) {
|
||||
AccessibilityNodeInfo source = event.getSource();
|
||||
if (source == null)
|
||||
return;
|
||||
List<AccessibilityNodeInfo> editableList = FilterAction.EditableFilter.findEditable(service.getRootInActiveWindow());
|
||||
int i = findInEditableList(editableList, source);
|
||||
recycle(editableList);
|
||||
sb.append("while(!input(").append(i).append(", \"").append(source.getText()).append("\"));");
|
||||
source.recycle();
|
||||
}
|
||||
|
||||
private void recycle(List<AccessibilityNodeInfo> list) {
|
||||
for (AccessibilityNodeInfo nodeInfo : list) {
|
||||
nodeInfo.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static int findInEditableList(List<AccessibilityNodeInfo> editableList, AccessibilityNodeInfo editable) {
|
||||
int i = 0;
|
||||
for (AccessibilityNodeInfo nodeInfo : editableList) {
|
||||
if (getBoundsInScreen(nodeInfo).equals(getBoundsInScreen(editable))) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ public class AccessibilityWatchDogService extends AccessibilityService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
public void onAccessibilityEvent(AccessibilityEvent event) {
|
||||
Log.v(TAG, "onAccessibilityEvent: " + event);
|
||||
synchronized (mDelegates) {
|
||||
for (Map.Entry<Integer, AccessibilityDelegate> entry : mDelegates.entrySet()) {
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.stardust.scriptdroid.service;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.stardust.scriptdroid.Pref;
|
||||
import com.stardust.scriptdroid.external.notification.record.ActionRecordSwitchHandleService;
|
||||
import com.stardust.scriptdroid.record.AccessibilityRecorderDelegate;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import static com.stardust.scriptdroid.external.notification.record.ActionRecordSwitchView.STOPPED;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/16.
|
||||
*/
|
||||
|
||||
public class VolumeChangeListenService extends Service {
|
||||
|
||||
private static final String ACTION_VOLUME_CHANGE = "android.media.VOLUME_CHANGED_ACTION";
|
||||
|
||||
private VolumeChangeReceiver mVolumeChangeReceiver;
|
||||
private static WeakReference<VolumeChangeListenService> instance;
|
||||
|
||||
public static void stopServiceIfNeeded() {
|
||||
if (instance != null || instance.get() != null) {
|
||||
instance.get().stopSelf();
|
||||
}
|
||||
}
|
||||
|
||||
public static void startServiceIfNeeded(Context context) {
|
||||
if (Pref.isRecordVolumeControlEnable() && (instance == null || instance.get() == null)) {
|
||||
context.startService(new Intent(context, VolumeChangeListenService.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
if (instance != null && instance.get() != null) {
|
||||
instance.get().stopSelf();
|
||||
}
|
||||
instance = new WeakReference<>(this);
|
||||
mVolumeChangeReceiver = new VolumeChangeReceiver();
|
||||
registerReceiver(mVolumeChangeReceiver, new IntentFilter(ACTION_VOLUME_CHANGE));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
unregisterReceiver(mVolumeChangeReceiver);
|
||||
}
|
||||
|
||||
private class VolumeChangeReceiver extends BroadcastReceiver {
|
||||
|
||||
private long mLastChangeMillis;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(ACTION_VOLUME_CHANGE)) {
|
||||
if (System.currentTimeMillis() - mLastChangeMillis < 400) {
|
||||
return;
|
||||
}
|
||||
mLastChangeMillis = System.currentTimeMillis();
|
||||
if (AccessibilityRecorderDelegate.getInstance().getState() == STOPPED) {
|
||||
ActionRecordSwitchHandleService.startRecord(VolumeChangeListenService.this);
|
||||
} else {
|
||||
ActionRecordSwitchHandleService.stopRecord(VolumeChangeListenService.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -12,15 +12,37 @@ import com.stardust.scriptdroid.R;
|
||||
*/
|
||||
public class IntentTool {
|
||||
|
||||
public static void goToQQ(Context context, String qq) {
|
||||
public static boolean goToQQ(Context context, String qq) {
|
||||
try {
|
||||
String url = "mqqwpa://im/chat?chat_type=wpa&uin=" + qq;
|
||||
context.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
|
||||
return true;
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/****************
|
||||
* 发起添加群流程。群号:免Root脚本精灵交流群(556928653) 的 key 为: vjHXzZlpGcXNe-YEWzQ85mm_z8y-curC
|
||||
* 调用 joinQQGroup(vjHXzZlpGcXNe-YEWzQ85mm_z8y-curC) 即可发起手Q客户端申请加群 免Root脚本精灵交流群(556928653)
|
||||
*
|
||||
* @param key 由官网生成的key
|
||||
* @return 返回true表示呼起手Q成功,返回false表示呼起失败
|
||||
******************/
|
||||
public static boolean joinQQGroup(Context context, String key) {
|
||||
Intent intent = new Intent();
|
||||
intent.setData(Uri.parse("mqqopensdkapi://bizAgent/qm/qr?url=http%3A%2F%2Fqm.qq.com%2Fcgi-bin%2Fqm%2Fqr%3Ffrom%3Dapp%26p%3Dandroid%26k%3D" + key));
|
||||
// 此Flag可根据具体产品需要自定义,如设置,则在加群界面按返回,返回手Q主界面,不设置,按返回会返回到呼起产品界面 //intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void goToMail(Context context, String sendTo, @Nullable String title, @Nullable String content) {
|
||||
Uri uri = Uri.parse("mailto:" + sendTo);
|
||||
String[] email = {sendTo};
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package com.stardust.scriptdroid.ui.edit.editor920;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.afollestad.materialdialogs.folderselector.FolderChooserDialog;
|
||||
import com.jecelyin.editor.v2.Pref;
|
||||
import com.jecelyin.editor.v2.common.Command;
|
||||
import com.jecelyin.editor.v2.ui.IActivity;
|
||||
import com.jecelyin.editor.v2.ui.TabManager;
|
||||
@@ -13,6 +16,13 @@ import java.io.File;
|
||||
* Created by Stardust on 2017/1/30.
|
||||
*/
|
||||
public class Editor920Activity extends IActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Pref.getInstance(this).setReadOnly(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startPickPathActivity(String s, String s1) {
|
||||
|
||||
@@ -28,15 +38,11 @@ public class Editor920Activity extends IActivity {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDocumentChanged(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doCommand(Command command) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openFile(String s, String s1, int i) {
|
||||
|
||||
@@ -59,6 +65,16 @@ public class Editor920Activity extends IActivity {
|
||||
doCommand(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentLang() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDocumentChanged(int i) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFolderSelection(@NonNull FolderChooserDialog dialog, @NonNull File folder) {
|
||||
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.afollestad.materialdialogs.folderselector.FileChooserDialog;
|
||||
import com.stardust.app.NotRemindAgainDialog;
|
||||
import com.stardust.scriptdroid.BuildConfig;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.droid.runtime.action.ActionPerformAccessibilityDelegate;
|
||||
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
|
||||
import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
|
||||
import com.stardust.scriptdroid.droid.script.file.SharedPrefScriptFileList;
|
||||
@@ -80,7 +79,7 @@ public class MainActivity extends BaseActivity implements FileChooserDialog.File
|
||||
}
|
||||
|
||||
private void goToAccessibilityPermissionSettingIfDisabled() {
|
||||
if (!AccessibilityServiceUtils.isAccessibilityServiceEnabled(this, ActionPerformAccessibilityDelegate.class)) {
|
||||
if (!AccessibilityServiceUtils.isAccessibilityServiceEnabled(this, AccessibilityWatchDogService.class)) {
|
||||
new NotRemindAgainDialog.Builder(this, "goToAccessibilityPermissionSettingIfDisabled")
|
||||
.title(R.string.text_alert)
|
||||
.content(R.string.explain_accessibility_permission)
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package com.stardust.scriptdroid.ui.main.operation;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.widget.PopupWindowCompat;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
@@ -54,7 +58,27 @@ public class ScriptFileOperationPopupMenu extends PopupWindow {
|
||||
}
|
||||
|
||||
public void show(View anchor) {
|
||||
super.showAsDropDown(anchor, 0, -anchor.getWidth());
|
||||
int y = (int) (getScreenHeight() - anchor.getHeight() - getYInScreen(anchor) - getContentHeight());
|
||||
y = Math.min(y, -anchor.getHeight());
|
||||
PopupWindowCompat.showAsDropDown(this, anchor, 0, y, Gravity.LEFT | Gravity.BOTTOM);
|
||||
}
|
||||
|
||||
private int getContentHeight() {
|
||||
getContentView().measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
return getContentView().getMeasuredHeight();
|
||||
}
|
||||
|
||||
private int getYInScreen(View anchor) {
|
||||
int[] location = new int[2];
|
||||
anchor.getLocationInWindow(location);
|
||||
return location[1];
|
||||
}
|
||||
|
||||
|
||||
private float getScreenHeight() {
|
||||
DisplayMetrics displaymetrics = new DisplayMetrics();
|
||||
((Activity) mContext).getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
|
||||
return displaymetrics.heightPixels;
|
||||
}
|
||||
|
||||
private void init() {
|
||||
|
||||
@@ -68,9 +68,10 @@ public class AboutActivity extends BaseActivity {
|
||||
|
||||
@ViewBinding.Click(R.id.qq)
|
||||
private void openQQToChatWithMe() {
|
||||
Toast.makeText(this, R.string.text_qq_group_id_copied, Toast.LENGTH_SHORT).show();
|
||||
String qq = getString(R.string.qq);
|
||||
IntentTool.goToQQ(this, qq);
|
||||
if (!IntentTool.goToQQ(this, qq)) {
|
||||
Toast.makeText(this, R.string.text_mobile_qq_not_installed, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.email)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.stardust.scriptdroid.ui.settings;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
@@ -13,6 +11,7 @@ import android.widget.Toast;
|
||||
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.file.SampleFileManager;
|
||||
import com.stardust.scriptdroid.tool.IntentTool;
|
||||
import com.stardust.scriptdroid.ui.BaseActivity;
|
||||
import com.stardust.scriptdroid.ui.error.IssueReportActivity;
|
||||
import com.stardust.scriptdroid.ui.main.MainActivity;
|
||||
@@ -89,8 +88,9 @@ public class SettingsActivity extends BaseActivity {
|
||||
.entry(getString(R.string.text_join_qq_group), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
((ClipboardManager) getActivity().getSystemService(CLIPBOARD_SERVICE)).setPrimaryClip(ClipData.newPlainText("qq", "556928653"));
|
||||
Toast.makeText(getActivity(), R.string.text_qq_group_id_copied, Toast.LENGTH_SHORT).show();
|
||||
if (!IntentTool.joinQQGroup(getActivity(), "vjHXzZlpGcXNe-YEWzQ85mm_z8y-curC")) {
|
||||
Toast.makeText(getActivity(), R.string.text_mobile_qq_not_installed, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
})
|
||||
.entry(getString(R.string.text_about), new Runnable() {
|
||||
|
||||
@@ -14,13 +14,12 @@
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_developer_512"/>
|
||||
|
||||
<TextView
|
||||
@@ -40,13 +39,12 @@
|
||||
android:clickable="true"
|
||||
android:foreground="?selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_github_mark"/>
|
||||
|
||||
<TextView
|
||||
@@ -67,13 +65,12 @@
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_email_black_48dp"/>
|
||||
|
||||
<TextView
|
||||
@@ -94,13 +91,12 @@
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_qq_black"/>
|
||||
|
||||
<TextView
|
||||
@@ -122,13 +118,12 @@
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_money_black"/>
|
||||
|
||||
<TextView
|
||||
|
||||
@@ -48,4 +48,10 @@
|
||||
<url>https://github.com/HeinrichReimer/android-issue-reporter</url>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>LeakCanary</name>
|
||||
<copyright>Copyright 2015 Square, Inc.</copyright>
|
||||
<url>https://github.com/square/leakcanary</url>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
</notices>
|
||||
@@ -117,4 +117,8 @@
|
||||
<string name="text_qq_group_id_copied">已复制群号到剪贴板</string>
|
||||
<string name="text_close">关闭</string>
|
||||
<string name="text_re_record">重新录制</string>
|
||||
<string name="text_use_volume_control_record">使用音量键控制</string>
|
||||
<string name="summary_use_volume_control_record">开启后每次音量变化会开始或停止脚本录制</string>
|
||||
<string name="key_use_volume_control_record">key_use_volume_control_record</string>
|
||||
<string name="text_mobile_qq_not_installed">未安装手机QQ</string>
|
||||
</resources>
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/text_script_record">
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_use_volume_control_record"
|
||||
android:summary="@string/summary_use_volume_control_record"
|
||||
android:title="@string/text_use_volume_control_record"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/text_others">
|
||||
|
||||
|
||||
Reference in New Issue
Block a user