Added volume control

This commit is contained in:
hyb1996
2017-02-17 11:38:24 +08:00
parent 8993079151
commit 40d6285bed
30 changed files with 309 additions and 78 deletions

Binary file not shown.

View File

@@ -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.

View File

@@ -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"

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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());
}
}

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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;
}
}
}

View File

@@ -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()) {

View File

@@ -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);
}
}
}
}
}

View File

@@ -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};

View File

@@ -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) {

View File

@@ -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)

View File

@@ -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() {

View File

@@ -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)

View File

@@ -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() {

View File

@@ -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

View File

@@ -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>

View File

@@ -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>

View File

@@ -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">