add: about page, settings, notification switch
5
.idea/misc.xml
generated
@@ -2,9 +2,10 @@
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
<list size="2">
|
||||
<list size="3">
|
||||
<item index="0" class="java.lang.String" itemvalue="com.stardust.view.ViewBind.Click" />
|
||||
<item index="1" class="java.lang.String" itemvalue="com.stardust.view.ViewBinding.Click" />
|
||||
<item index="1" class="java.lang.String" itemvalue="com.stardust.view.ViewBinding.Check" />
|
||||
<item index="2" class="java.lang.String" itemvalue="com.stardust.view.ViewBinding.Click" />
|
||||
</list>
|
||||
</component>
|
||||
<component name="NullableNotNullManager">
|
||||
|
||||
@@ -37,15 +37,14 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||
testCompile 'junit:junit:4.12'
|
||||
|
||||
compile 'com.android.support:appcompat-v7:25.0.0'
|
||||
compile 'com.android.support:design:25.0.0'
|
||||
testCompile 'junit:junit:4.12'
|
||||
|
||||
compile 'com.afollestad.material-dialogs:core:0.9.2.3'
|
||||
compile 'com.google.code.gson:gson:2.8.0'
|
||||
compile 'com.sothree.slidinguppanel:library:3.3.1'
|
||||
compile('de.psdev.licensesdialog:licensesdialog:1.8.1')
|
||||
compile 'com.squareup.duktape:duktape-android:1.1.0'
|
||||
compile 'com.furture.react:DuktapeJava:1.1.0'
|
||||
compile 'com.zzhoujay.markdown:markdown:1.0.2'
|
||||
|
||||
@@ -54,15 +53,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(name:'920-common-release', ext:'aar'){
|
||||
transitive = true
|
||||
}
|
||||
compile(name:'920-styles-debug', ext:'aar'){
|
||||
transitive = true
|
||||
}
|
||||
compile(name:'920-file_explorer-release', ext:'aar'){
|
||||
transitive = true
|
||||
}
|
||||
compile(name:'920-common-release', ext:'aar')
|
||||
compile(name:'920-styles-debug', ext:'aar')
|
||||
compile(name:'920-file_explorer-release', ext:'aar')
|
||||
compile(name:'920-app-debug', ext:'aar')
|
||||
|
||||
|
||||
|
||||
@@ -72,9 +72,90 @@
|
||||
</provider>
|
||||
|
||||
<activity android:name=".EditActivity"/>
|
||||
|
||||
<activity android:name=".DocumentActivity"/>
|
||||
<activity android:name=".AboutActivity"/>
|
||||
<activity android:name=".SettingsActivity"/>
|
||||
<activity android:name=".ErrorReportActivity"/>
|
||||
|
||||
<service android:name=".AssistModeSwitchService"/>
|
||||
|
||||
<activity
|
||||
android:name="com.stardust.EditAndRunIntentActivity"
|
||||
android:icon="@drawable/ic_edit_green_48dp"
|
||||
android:label="编辑与运行脚本">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<action android:name="android.intent.action.EDIT"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data android:scheme="file"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:mimeType="application/x-*"/>
|
||||
<data android:mimeType="application/postscript"/>
|
||||
<data android:mimeType="application/plain"/>
|
||||
<data android:mimeType="application/x-javascript"/>
|
||||
<data android:mimeType="text/*"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
|
||||
<data android:mimeType="text/*"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEARCH"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.googlecode.android_scripting.action.EDIT_SCRIPT"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".ImportIntentActivity"
|
||||
android:icon="@drawable/ic_folder_open_outline_green"
|
||||
android:label="导入脚本文件">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<action android:name="android.intent.action.EDIT"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
|
||||
<data android:scheme="file"/>
|
||||
<data android:scheme="content"/>
|
||||
<data android:mimeType="application/x-*"/>
|
||||
<data android:mimeType="application/postscript"/>
|
||||
<data android:mimeType="application/plain"/>
|
||||
<data android:mimeType="application/x-javascript"/>
|
||||
<data android:mimeType="text/*"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
|
||||
<data android:mimeType="text/*"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEARCH"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="com.googlecode.android_scripting.action.EDIT_SCRIPT"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
4
app/src/main/assets/sample_hello_big_sister.js
Normal file
@@ -0,0 +1,4 @@
|
||||
toast("大姐姐好")
|
||||
for(var i = 0; i < 10; i++){
|
||||
toast("大姐姐今年有" + i + "块钱~");
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
launchApp("微信");
|
||||
sleep(500);
|
||||
click("发现");
|
||||
sleep(500);
|
||||
click("朋友圈");
|
||||
while(!click("发现"));
|
||||
while(!click("朋友圈"));
|
||||
29
app/src/main/java/com/stardust/EditAndRunIntentActivity.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package com.stardust;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.stardust.scriptdroid.BaseActivity;
|
||||
import com.stardust.scriptdroid.EditActivity;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/2.
|
||||
*/
|
||||
|
||||
public class EditAndRunIntentActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
handleIntent();
|
||||
}
|
||||
|
||||
private void handleIntent() {
|
||||
Intent intent = getIntent();
|
||||
String path = intent.getData().getPath();
|
||||
if (!TextUtils.isEmpty(path))
|
||||
EditActivity.editFile(this, path);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.stardust;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
@@ -15,9 +16,9 @@ import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
|
||||
public class UIActionPerformActivity extends AppCompatActivity {
|
||||
|
||||
|
||||
private static volatile Runnable action;
|
||||
private static volatile UIAction action;
|
||||
|
||||
public static void performAction(Runnable action) {
|
||||
public static void performAction(UIAction action) {
|
||||
if (UIActionPerformActivity.action != null) {
|
||||
return;
|
||||
}
|
||||
@@ -30,10 +31,20 @@ public class UIActionPerformActivity extends AppCompatActivity {
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
DroidRuntime.setContext(this);
|
||||
action.run();
|
||||
action.setActivity(this).run();
|
||||
}
|
||||
|
||||
|
||||
public abstract static class UIAction implements Runnable {
|
||||
|
||||
protected Activity mActivity;
|
||||
|
||||
public UIAction setActivity(Activity activity) {
|
||||
mActivity = activity;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.stardust.scriptdroid;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.stardust.scriptdroid.tool.IntentTool;
|
||||
import com.stardust.view.ViewBinder;
|
||||
import com.stardust.view.ViewBinding;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/2.
|
||||
*/
|
||||
|
||||
public class AboutActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setUpUI();
|
||||
}
|
||||
|
||||
private void setUpUI() {
|
||||
setContentView(R.layout.activity_about);
|
||||
setUpToolbar();
|
||||
ViewBinder.bind(this);
|
||||
}
|
||||
|
||||
private void setUpToolbar() {
|
||||
Toolbar toolbar = $(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.github)
|
||||
private void openGitHub() {
|
||||
IntentTool.goToLink(this, getString(R.string.my_github));
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.qq)
|
||||
private void openQQToChatWithMe() {
|
||||
String qq = getString(R.string.qq);
|
||||
IntentTool.goToQQ(this, qq);
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.email)
|
||||
private void openEmailToSendMe() {
|
||||
String email = getString(R.string.email);
|
||||
IntentTool.goToMail(this, email);
|
||||
}
|
||||
|
||||
|
||||
@ViewBinding.Click(R.id.donate)
|
||||
private void showDonateMeDialog() {
|
||||
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.share)
|
||||
private void share() {
|
||||
IntentTool.shareText(this, getString(R.string.share_app));
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.icon)
|
||||
private void lol() {
|
||||
Toast.makeText(this, "略略略", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.developer)
|
||||
private void hhh() {
|
||||
Toast.makeText(this, "这是软件开发者(。・・)ノ", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private void setClipText(CharSequence label, CharSequence text) {
|
||||
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
|
||||
clipboardManager.setPrimaryClip(ClipData.newPlainText(label, text));
|
||||
Toast.makeText(this, label + getString(R.string.text_already_copy_to_clip), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package com.stardust.scriptdroid;
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import com.stardust.util.CrashHandler;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
@@ -16,6 +18,7 @@ public class App extends Application {
|
||||
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(ErrorReportActivity.class));
|
||||
instance = this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.stardust.scriptdroid;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.stardust.scriptdroid.droid.runtime.action.ActionPerformService;
|
||||
import com.stardust.scriptdroid.ui.AssistModeSwitchNotification;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/2.
|
||||
*/
|
||||
public class AssistModeSwitchService extends Service {
|
||||
|
||||
public static PendingIntent getStartIntent() {
|
||||
Intent intent = new Intent(App.getApp(), AssistModeSwitchService.class)
|
||||
.putExtra("intentValid", true)
|
||||
.putExtra("switch", "assistMode");
|
||||
return PendingIntent.getService(App.getApp(), 0, intent, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
boolean intentValid = intent.getBooleanExtra("intentValid", false);
|
||||
if (intentValid) {
|
||||
String action = intent.getStringExtra("action");
|
||||
if (action != null) {
|
||||
if (action.equals("assistMode")) {
|
||||
ActionPerformService.setAssistModeEnable(!ActionPerformService.isAssistModeEnable());
|
||||
} else {
|
||||
AssistModeSwitchNotification.setEnable(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
stopSelf();
|
||||
return super.onStartCommand(intent, flags, startId);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PendingIntent getDeletePendingIntent() {
|
||||
Intent deleteIntent = new Intent(App.getApp(), AssistModeSwitchService.class)
|
||||
.putExtra("intentValid", true)
|
||||
.putExtra("switch", "assistModeNotification");
|
||||
return PendingIntent.getService(App.getApp(), 0, deleteIntent, 0);
|
||||
}
|
||||
}
|
||||
@@ -6,10 +6,11 @@ import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.View;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static android.content.pm.PackageManager.PERMISSION_DENIED;
|
||||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/23.
|
||||
@@ -30,6 +31,10 @@ public class BaseActivity extends AppCompatActivity {
|
||||
String[] requestPermissions = getRequestPermissions(permissions);
|
||||
if (requestPermissions.length > 0)
|
||||
requestPermissions(requestPermissions, PERMISSION_REQUEST_CODE);
|
||||
} else {
|
||||
int[] grantResults = new int[permissions.length];
|
||||
Arrays.fill(grantResults, PERMISSION_GRANTED);
|
||||
onRequestPermissionsResult(PERMISSION_REQUEST_CODE, permissions, grantResults);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.stardust.scriptdroid;
|
||||
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/2.
|
||||
*/
|
||||
|
||||
public class ErrorReportActivity extends BaseActivity {
|
||||
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
try {
|
||||
super.onCreate(savedInstanceState);
|
||||
setUpUI();
|
||||
handleIntent();
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleIntent() {
|
||||
String message = getIntent().getStringExtra("message");
|
||||
final String errorDetail = getIntent().getStringExtra("error");
|
||||
new MaterialDialog.Builder(this)
|
||||
.content(message)
|
||||
.positiveText("退出")
|
||||
.negativeText("复制调试信息")
|
||||
.onPositive(new MaterialDialog.SingleButtonCallback() {
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
|
||||
exit();
|
||||
}
|
||||
})
|
||||
.onNegative(new MaterialDialog.SingleButtonCallback() {
|
||||
@Override
|
||||
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
|
||||
copyToClip(getDeviceMessage() + errorDetail);
|
||||
exitAfter(1000);
|
||||
}
|
||||
})
|
||||
.cancelable(false)
|
||||
.show();
|
||||
}
|
||||
|
||||
private String getDeviceMessage() {
|
||||
return "Android: " + Build.VERSION.SDK_INT + "\n";
|
||||
}
|
||||
|
||||
private void exitAfter(long millis) {
|
||||
new Timer().schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
exit();
|
||||
}
|
||||
}, millis);
|
||||
}
|
||||
|
||||
private void copyToClip(String text) {
|
||||
((ClipboardManager) getSystemService(CLIPBOARD_SERVICE))
|
||||
.setPrimaryClip(ClipData.newPlainText("Debug", text));
|
||||
Toast.makeText(ErrorReportActivity.this, R.string.text_already_copy_to_clip, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private void setUpUI() {
|
||||
setContentView(R.layout.activity_error_report);
|
||||
setUpToolbar();
|
||||
}
|
||||
|
||||
private void setUpToolbar() {
|
||||
Toolbar toolbar = $(R.id.toolbar);
|
||||
toolbar.setTitle(getString(R.string.text_error_report));
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setHomeButtonEnabled(false);
|
||||
}
|
||||
|
||||
private void exit() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
finishAffinity();
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.stardust.scriptdroid;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
|
||||
import com.stardust.scriptdroid.droid.script.file.SharedPrefScriptFileList;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/2.
|
||||
*/
|
||||
|
||||
public class ImportIntentActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
handleIntent();
|
||||
}
|
||||
|
||||
private void handleIntent() {
|
||||
Intent intent = getIntent();
|
||||
final String path = intent.getData().getPath();
|
||||
if (!TextUtils.isEmpty(path)) {
|
||||
new MaterialDialog.Builder(this)
|
||||
.title(R.string.text_please_input_name)
|
||||
.input(getString(R.string.text_name), new File(path).getName(), new MaterialDialog.InputCallback() {
|
||||
@Override
|
||||
public void onInput(@NonNull MaterialDialog dialog, CharSequence input) {
|
||||
SharedPrefScriptFileList.getInstance().add(new ScriptFile(input.toString(), path));
|
||||
startMainActivity();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
}
|
||||
|
||||
private void startMainActivity() {
|
||||
startActivity(new Intent(this, MainActivity.class)
|
||||
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP));
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.stardust.scriptdroid;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Bundle;
|
||||
@@ -12,17 +11,17 @@ import android.support.v7.app.ActionBarDrawerToggle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.InputType;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.DialogAction;
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.afollestad.materialdialogs.folderselector.FileChooserDialog;
|
||||
import com.stardust.app.NotRemindAgainDialog;
|
||||
import com.stardust.scriptdroid.droid.runtime.action.ActionPerformService;
|
||||
import com.stardust.scriptdroid.droid.script.file.ScriptFile;
|
||||
import com.stardust.scriptdroid.droid.script.file.ScriptFileList;
|
||||
import com.stardust.scriptdroid.droid.script.file.SharedPrefScriptFileList;
|
||||
import com.stardust.scriptdroid.file.FileChooser;
|
||||
import com.stardust.scriptdroid.file.FileUtils;
|
||||
import com.stardust.scriptdroid.tool.BackPressedHandler;
|
||||
import com.stardust.scriptdroid.ui.ScriptFileOperation;
|
||||
import com.stardust.scriptdroid.ui.ScriptListRecyclerView;
|
||||
import com.stardust.scriptdroid.ui.SlideMenuFragment;
|
||||
@@ -32,22 +31,19 @@ import com.stardust.view.ViewBinding;
|
||||
import com.stardust.view.accessibility.AccessibilityServiceUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
|
||||
public class MainActivity extends BaseActivity {
|
||||
public class MainActivity extends BaseActivity implements FileChooserDialog.FileCallback {
|
||||
|
||||
private SlidingUpPanel mAddFilePanel;
|
||||
private ScriptListRecyclerView mScriptListRecyclerView;
|
||||
private ScriptFileList mScriptFileList;
|
||||
private FileChooser mFileChooser;
|
||||
private DrawerLayout mDrawerLayout;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setUpUI();
|
||||
setUpFileChooser();
|
||||
checkPermissions();
|
||||
}
|
||||
|
||||
@@ -72,19 +68,6 @@ public class MainActivity extends BaseActivity {
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpFileChooser() {
|
||||
mFileChooser = new FileChooser(this);
|
||||
mFileChooser.setOnFileChoseListener(new FileChooser.OnFileChoseListener() {
|
||||
@Override
|
||||
public void onFileChose(InputStream inputStream) {
|
||||
String path = FileUtils.getPath(inputStream);
|
||||
if (path != null) {
|
||||
MainActivity.this.addScriptFile(path);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addScriptFile(final String path) {
|
||||
new MaterialDialog.Builder(this).title(R.string.text_name)
|
||||
.inputType(InputType.TYPE_CLASS_TEXT)
|
||||
@@ -159,19 +142,14 @@ public class MainActivity extends BaseActivity {
|
||||
|
||||
@ViewBinding.Click(R.id.import_from_file)
|
||||
private void showFileChooser() {
|
||||
mFileChooser.startFileManagerToChoose("*/*", new FileChooser.FileManagerNotFoundHandler() {
|
||||
@Override
|
||||
public void handle(ActivityNotFoundException exception, String mimeType) {
|
||||
exception.printStackTrace();
|
||||
Snackbar.make(mDrawerLayout, R.string.text_file_manager_not_found, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
new FileChooserDialog.Builder(this)
|
||||
.extensionsFilter(".js", ".txt")
|
||||
.show();
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.setting)
|
||||
private void startSettingActivity() {
|
||||
//TODO create Setting Activity
|
||||
Toast.makeText(this, "暂无", Toast.LENGTH_LONG).show();
|
||||
startActivity(new Intent(this, SettingsActivity.class));
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.exit)
|
||||
@@ -179,10 +157,6 @@ public class MainActivity extends BaseActivity {
|
||||
super.finish();
|
||||
}
|
||||
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
mFileChooser.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode,
|
||||
@NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
@@ -191,4 +165,16 @@ public class MainActivity extends BaseActivity {
|
||||
mScriptListRecyclerView.getAdapter().notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFileSelection(@NonNull FileChooserDialog dialog, @NonNull File file) {
|
||||
addScriptFile(file.getPath());
|
||||
}
|
||||
|
||||
|
||||
private BackPressedHandler mBackPressedHandler = new BackPressedHandler.DoublePressExit(this);
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
mBackPressedHandler.onBackPressed();
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ public class NonUiInitializer {
|
||||
private static final Map<String, Integer> SAMPLES = new MapEntries<String, Integer>()
|
||||
.entry("sample_open_wechat_moment.js", R.string.text_sample_open_what_moment)
|
||||
.entry("sample_open_running_services.js", R.string.text_sample_open_running_services)
|
||||
.entry("sample_simple_calculator.js", R.string.text_sample_simple_calculator)
|
||||
.entry("sample_hello_big_sister.js", R.string.text_sample_hello_big_sister)
|
||||
.map();
|
||||
|
||||
private static NonUiInitializer instance = new NonUiInitializer();
|
||||
@@ -35,7 +35,7 @@ public class NonUiInitializer {
|
||||
|
||||
}
|
||||
|
||||
public void copySampleScriptFileIfNeeded(){
|
||||
public void copySampleScriptFileIfNeeded() {
|
||||
if (!Pref.def().getBoolean(Pref.SAMPLE_SCRIPTS_COPIED, false)) {
|
||||
copySampleScriptFile();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.stardust.scriptdroid;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.View;
|
||||
|
||||
import com.stardust.util.MapEntries;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import de.psdev.licensesdialog.LicensesDialog;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/2.
|
||||
*/
|
||||
|
||||
public class SettingsActivity extends BaseActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setUpUI();
|
||||
}
|
||||
|
||||
private void setUpUI() {
|
||||
setContentView(R.layout.activity_settings);
|
||||
setUpToolbar();
|
||||
getFragmentManager().beginTransaction().replace(R.id.fragment_setting, new PreferenceFragment()).commit();
|
||||
}
|
||||
|
||||
private void setUpToolbar() {
|
||||
Toolbar toolbar = $(R.id.toolbar);
|
||||
toolbar.setTitle(R.string.text_setting);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public static class PreferenceFragment extends android.preference.PreferenceFragment {
|
||||
|
||||
private Map<String, Runnable> ACTION_MAP;
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(R.xml.preferences);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
ACTION_MAP = new MapEntries<String, Runnable>()
|
||||
.entry(getString(R.string.text_about), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
startActivity(new Intent(getActivity(), AboutActivity.class));
|
||||
}
|
||||
})
|
||||
.entry(getString(R.string.text_licenses), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
showLicenseDialog();
|
||||
}
|
||||
})
|
||||
.map();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
|
||||
Runnable action = ACTION_MAP.get(preference.getTitle().toString());
|
||||
if (action != null) {
|
||||
action.run();
|
||||
return true;
|
||||
} else {
|
||||
return super.onPreferenceTreeClick(preferenceScreen, preference);
|
||||
}
|
||||
}
|
||||
|
||||
private void showLicenseDialog() {
|
||||
new LicensesDialog.Builder(getActivity())
|
||||
.setNotices(R.raw.licenses)
|
||||
.setIncludeOwnLicense(true)
|
||||
.build()
|
||||
.showAppCompat();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.stardust.scriptdroid.droid;
|
||||
|
||||
import com.stardust.scriptdroid.droid.runtime.DroidRuntime;
|
||||
import com.stardust.scriptdroid.droid.script.GBJDuktapeJavaScriptEngine;
|
||||
import com.stardust.scriptdroid.droid.script.DuktapeJavaScriptEngine;
|
||||
import com.stardust.scriptdroid.droid.script.JavaScriptEngine;
|
||||
import com.stardust.scriptdroid.file.FileUtils;
|
||||
|
||||
@@ -19,7 +19,7 @@ public class Droid {
|
||||
}
|
||||
|
||||
private static final DroidRuntime RUNTIME = DroidRuntime.getRuntime();
|
||||
private static final JavaScriptEngine JAVA_SCRIPT_ENGINE = new GBJDuktapeJavaScriptEngine(RUNTIME);
|
||||
private static final JavaScriptEngine JAVA_SCRIPT_ENGINE = new DuktapeJavaScriptEngine(RUNTIME);
|
||||
private static final OnRunFinishedListener DEFAULT_LISTENER = new OnRunFinishedListener() {
|
||||
@Override
|
||||
public void onRunFinished(Object result, Exception e) {
|
||||
|
||||
@@ -10,7 +10,6 @@ import android.view.accessibility.AccessibilityNodeInfo;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.afollestad.materialdialogs.MaterialDialog;
|
||||
import com.stardust.UIActionPerformActivity;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.droid.runtime.action.Action;
|
||||
@@ -194,12 +193,7 @@ public class DroidRuntime implements IDroidRuntime {
|
||||
}
|
||||
|
||||
public MaterialDialog show(final MaterialDialog.Builder dialog) {
|
||||
UIActionPerformActivity.performAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
dialog.show();
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.stardust.scriptdroid.droid.runtime.action;
|
||||
import android.accessibilityservice.AccessibilityService;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.preference.PreferenceManager;
|
||||
@@ -27,6 +28,10 @@ import java.util.List;
|
||||
|
||||
public class ActionPerformService extends AccessibilityService {
|
||||
|
||||
|
||||
public static final String ACTION_CHANGE_ASSIST_MODE = App.getApp().getPackageName() + ".ACTION_CHANGE_ASSIST_MODE";
|
||||
|
||||
|
||||
private static final String TAG = "ActionPerformService";
|
||||
private static final String KEY_ASSIST_MODE_ENABLE = "ASSIST_MODE_ENABLE";
|
||||
private static ActionPerformService instance;
|
||||
@@ -65,6 +70,7 @@ public class ActionPerformService extends AccessibilityService {
|
||||
public static void setAssistModeEnable(boolean assistModeEnable) {
|
||||
ActionPerformService.assistModeEnable = assistModeEnable;
|
||||
PreferenceManager.getDefaultSharedPreferences(App.getApp()).edit().putBoolean(KEY_ASSIST_MODE_ENABLE, assistModeEnable).apply();
|
||||
App.getApp().sendBroadcast(new Intent(ACTION_CHANGE_ASSIST_MODE).putExtra("enable", assistModeEnable));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
package com.stardust.scriptdroid.droid.script;
|
||||
|
||||
import android.util.Log;
|
||||
import android.util.Pair;
|
||||
|
||||
import com.squareup.duktape.Duktape;
|
||||
import com.efurture.script.JSTransformer;
|
||||
import com.furture.react.DuktapeEngine;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.droid.runtime.api.IDroidRuntime;
|
||||
|
||||
import static com.stardust.scriptdroid.droid.script.JavaScriptEngine.Init.readInitScript;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
@@ -14,54 +21,100 @@ import static com.stardust.scriptdroid.droid.script.JavaScriptEngine.Init.readIn
|
||||
|
||||
public class DuktapeJavaScriptEngine implements JavaScriptEngine {
|
||||
|
||||
private static final String TAG = "DuktapeJavaScriptEngine";
|
||||
|
||||
private Duktape mDuktape = Duktape.create();
|
||||
private boolean mRecycled = false;
|
||||
private final List<Pair<DuktapeEngine, Thread>> mDuktapeEngineList = new ArrayList<>();
|
||||
private static final String INIT_SCRIPT;
|
||||
private Map<String, Object> mVariableMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
try {
|
||||
INIT_SCRIPT = JSTransformer.parse(new StringReader(Init.INIT_SCRIPT));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public DuktapeJavaScriptEngine(IDroidRuntime runtime) {
|
||||
setRuntime(runtime);
|
||||
execute(readInitScript());
|
||||
|
||||
}
|
||||
|
||||
public void setRuntime(IDroidRuntime runtime) {
|
||||
private void setRuntime(IDroidRuntime runtime) {
|
||||
set("droid", IDroidRuntime.class, runtime);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object execute(String script) {
|
||||
return mDuktape.evaluate(script);
|
||||
public Object execute(String script) throws IOException {
|
||||
DuktapeEngine duktapeEngine = new DuktapeEngine();
|
||||
init(duktapeEngine);
|
||||
add(duktapeEngine, Thread.currentThread());
|
||||
Object result;
|
||||
try {
|
||||
result = duktapeEngine.execute(JSTransformer.parse(new StringReader(script)));
|
||||
} catch (IOException e) {
|
||||
remove(duktapeEngine);
|
||||
throw e;
|
||||
}
|
||||
remove(duktapeEngine);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void init(DuktapeEngine duktapeEngine) {
|
||||
duktapeEngine.put("context", App.getApp());
|
||||
duktapeEngine.execute(INIT_SCRIPT);
|
||||
for (Map.Entry<String, Object> variable : mVariableMap.entrySet()) {
|
||||
duktapeEngine.put(variable.getKey(), variable.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void remove(DuktapeEngine duktapeEngine) {
|
||||
duktapeEngine.destory();
|
||||
synchronized (mDuktapeEngineList) {
|
||||
Iterator<Pair<DuktapeEngine, Thread>> iterator = mDuktapeEngineList.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Pair<DuktapeEngine, Thread> pair = iterator.next();
|
||||
if (pair.first == duktapeEngine) {
|
||||
stop(pair.first, pair.second);
|
||||
}
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void stop(DuktapeEngine engine, Thread thread) {
|
||||
try {
|
||||
thread.interrupt();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
engine.destory();
|
||||
}
|
||||
|
||||
private void add(DuktapeEngine duktapeEngine, Thread thread) {
|
||||
synchronized (mDuktapeEngineList) {
|
||||
mDuktapeEngineList.add(0, new Pair<>(duktapeEngine, thread));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void set(String varName, Class<T> c, T value) {
|
||||
mDuktape.set(varName, c, value);
|
||||
mVariableMap.put(varName, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopAll() {
|
||||
mDuktape.close();
|
||||
return 1;
|
||||
}
|
||||
|
||||
public void recycle() {
|
||||
if (!mRecycled) {
|
||||
mDuktape.close();
|
||||
mRecycled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finalize() throws Throwable {
|
||||
try {
|
||||
if (!mRecycled) {
|
||||
Log.w(TAG, "Not recycled before finalize");
|
||||
recycle();
|
||||
int n;
|
||||
synchronized (mDuktapeEngineList) {
|
||||
for (Pair<DuktapeEngine, Thread> pair : mDuktapeEngineList) {
|
||||
stop(pair.first, pair.second);
|
||||
}
|
||||
} catch (Throwable throwable) {
|
||||
throwable.printStackTrace();
|
||||
n = mDuktapeEngineList.size();
|
||||
mDuktapeEngineList.clear();
|
||||
}
|
||||
super.finalize();
|
||||
return n;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
package com.stardust.scriptdroid.droid.script;
|
||||
|
||||
import android.util.Pair;
|
||||
|
||||
import com.efurture.script.JSTransformer;
|
||||
import com.furture.react.DuktapeEngine;
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.droid.runtime.api.IDroidRuntime;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/27.
|
||||
*/
|
||||
|
||||
public class GBJDuktapeJavaScriptEngine implements JavaScriptEngine {
|
||||
|
||||
|
||||
private final List<Pair<DuktapeEngine, Thread>> mDuktapeEngineList = new ArrayList<>();
|
||||
private static final String INIT_SCRIPT;
|
||||
private Map<String, Object> mVariableMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
try {
|
||||
INIT_SCRIPT = JSTransformer.parse(new StringReader(Init.INIT_SCRIPT));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public GBJDuktapeJavaScriptEngine(IDroidRuntime runtime) {
|
||||
setRuntime(runtime);
|
||||
|
||||
}
|
||||
|
||||
private void setRuntime(IDroidRuntime runtime) {
|
||||
set("droid", IDroidRuntime.class, runtime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object execute(String script) throws IOException {
|
||||
DuktapeEngine duktapeEngine = new DuktapeEngine();
|
||||
init(duktapeEngine);
|
||||
add(duktapeEngine, Thread.currentThread());
|
||||
Object result;
|
||||
try {
|
||||
result = duktapeEngine.execute(JSTransformer.parse(new StringReader(script)));
|
||||
} catch (IOException e) {
|
||||
remove(duktapeEngine);
|
||||
throw e;
|
||||
}
|
||||
remove(duktapeEngine);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void init(DuktapeEngine duktapeEngine) {
|
||||
duktapeEngine.put("context", App.getApp());
|
||||
duktapeEngine.execute(INIT_SCRIPT);
|
||||
for (Map.Entry<String, Object> variable : mVariableMap.entrySet()) {
|
||||
duktapeEngine.put(variable.getKey(), variable.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void remove(DuktapeEngine duktapeEngine) {
|
||||
duktapeEngine.destory();
|
||||
synchronized (mDuktapeEngineList) {
|
||||
Iterator<Pair<DuktapeEngine, Thread>> iterator = mDuktapeEngineList.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Pair<DuktapeEngine, Thread> pair = iterator.next();
|
||||
if (pair.first == duktapeEngine) {
|
||||
stop(pair.first, pair.second);
|
||||
}
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void stop(DuktapeEngine engine, Thread thread) {
|
||||
try {
|
||||
thread.interrupt();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
engine.destory();
|
||||
}
|
||||
|
||||
private void add(DuktapeEngine duktapeEngine, Thread thread) {
|
||||
synchronized (mDuktapeEngineList) {
|
||||
mDuktapeEngineList.add(0, new Pair<>(duktapeEngine, thread));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void set(String varName, Class<T> c, T value) {
|
||||
mVariableMap.put(varName, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int stopAll() {
|
||||
int n;
|
||||
synchronized (mDuktapeEngineList) {
|
||||
for (Pair<DuktapeEngine, Thread> pair : mDuktapeEngineList) {
|
||||
stop(pair.first, pair.second);
|
||||
}
|
||||
n = mDuktapeEngineList.size();
|
||||
mDuktapeEngineList.clear();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.stardust.scriptdroid.tool;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.stardust.scriptdroid.R;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/3.
|
||||
*/
|
||||
public interface BackPressedHandler {
|
||||
|
||||
void onBackPressed();
|
||||
|
||||
class DoublePressExit implements BackPressedHandler {
|
||||
|
||||
private final Activity mActivity;
|
||||
private long mLastPressedMillis;
|
||||
private long mDoublePressInterval = 1000;
|
||||
|
||||
public DoublePressExit(Activity activity) {
|
||||
mActivity = activity;
|
||||
}
|
||||
|
||||
public DoublePressExit setDoublePressInterval(long doublePressInterval) {
|
||||
mDoublePressInterval = doublePressInterval;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (System.currentTimeMillis() - mLastPressedMillis < mDoublePressInterval) {
|
||||
mActivity.finish();
|
||||
} else {
|
||||
mLastPressedMillis = System.currentTimeMillis();
|
||||
Toast.makeText(mActivity, R.string.text_press_again_to_exit, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.stardust.scriptdroid.tool;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Intent工具,用于Activity之间的跳转,调起其他应用程序等
|
||||
*/
|
||||
public class IntentTool {
|
||||
|
||||
public static void 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)));
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void goToMail(Context context, String sendTo, @Nullable String title, @Nullable String content) {
|
||||
Uri uri = Uri.parse("mailto:" + sendTo);
|
||||
String[] email = {sendTo};
|
||||
Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
|
||||
intent.putExtra(Intent.EXTRA_CC, email);
|
||||
if (title != null)
|
||||
intent.putExtra(Intent.EXTRA_SUBJECT, title);
|
||||
if (content != null)
|
||||
intent.putExtra(Intent.EXTRA_TEXT, content);
|
||||
context.startActivity(Intent.createChooser(intent, "请选择邮件应用"));
|
||||
}
|
||||
|
||||
public static void goToMail(Context context, String sendTo) {
|
||||
goToMail(context, sendTo, null, null);
|
||||
}
|
||||
|
||||
public static void goToLink(Context context, String link) {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(link));
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
public static void shareText(Context context, String text) {
|
||||
context.startActivity(new Intent(Intent.ACTION_SEND)
|
||||
.putExtra(Intent.EXTRA_TEXT, text)
|
||||
.setType("text/plain"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.stardust.scriptdroid.ui;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
|
||||
import com.stardust.scriptdroid.App;
|
||||
import com.stardust.scriptdroid.AssistModeSwitchService;
|
||||
import com.stardust.scriptdroid.R;
|
||||
import com.stardust.scriptdroid.droid.runtime.action.ActionPerformService;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/2.
|
||||
*/
|
||||
|
||||
public class AssistModeSwitchNotification {
|
||||
|
||||
private static final int NOTIFY_ID = 11126;
|
||||
private static final String KEY_ASSIST_MODE_NOTIFICATION = "KEY_ASSIST_MODE_NOTIFICATION";
|
||||
|
||||
private static boolean enable = false;
|
||||
private static Notification notification;
|
||||
|
||||
static {
|
||||
readPreference();
|
||||
}
|
||||
|
||||
public static boolean isEnable() {
|
||||
return enable;
|
||||
}
|
||||
|
||||
public static void setEnable(boolean enable) {
|
||||
if (AssistModeSwitchNotification.enable == enable)
|
||||
return;
|
||||
AssistModeSwitchNotification.enable = enable;
|
||||
PreferenceManager.getDefaultSharedPreferences(App.getApp()).edit().putBoolean(KEY_ASSIST_MODE_NOTIFICATION, enable).apply();
|
||||
if (enable) {
|
||||
showNotification();
|
||||
} else {
|
||||
hideNotification();
|
||||
}
|
||||
}
|
||||
|
||||
public static void notifyAssistModeChanged() {
|
||||
if (enable) {
|
||||
setEnable(false);
|
||||
setEnable(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void showNotification() {
|
||||
notification = new NotificationCompat.Builder(App.getApp())
|
||||
.setAutoCancel(false)
|
||||
.setSmallIcon(R.drawable.ic_robot_head)
|
||||
.setDeleteIntent(AssistModeSwitchService.getDeletePendingIntent())
|
||||
.setContentText(ActionPerformService.isAssistModeEnable() ?
|
||||
App.getApp().getString(R.string.text_assist_mode_enabled) :
|
||||
App.getApp().getString(R.string.text_assist_mode_disabled))
|
||||
.setContentIntent(AssistModeSwitchService.getStartIntent())
|
||||
.build();
|
||||
showNotification(notification);
|
||||
}
|
||||
|
||||
private static void showNotification(Notification notification) {
|
||||
NotificationManager notificationManager = (NotificationManager) App.getApp().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(NOTIFY_ID, notification);
|
||||
}
|
||||
|
||||
private static void hideNotification() {
|
||||
NotificationManager notificationManager = (NotificationManager) App.getApp().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.cancel(NOTIFY_ID);
|
||||
}
|
||||
|
||||
|
||||
private static void readPreference() {
|
||||
enable = PreferenceManager.getDefaultSharedPreferences(App.getApp()).getBoolean(KEY_ASSIST_MODE_NOTIFICATION, false);
|
||||
setEnable(enable);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.stardust.scriptdroid.ui;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.Snackbar;
|
||||
@@ -9,8 +12,6 @@ import android.support.v7.widget.SwitchCompat;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.stardust.app.Fragment;
|
||||
import com.stardust.scriptdroid.DocumentActivity;
|
||||
@@ -21,7 +22,7 @@ import com.stardust.view.ViewBinder;
|
||||
import com.stardust.view.ViewBinding;
|
||||
import com.stardust.view.accessibility.AccessibilityServiceUtils;
|
||||
|
||||
import de.psdev.licensesdialog.LicensesDialog;
|
||||
import static com.stardust.scriptdroid.droid.runtime.action.ActionPerformService.ACTION_CHANGE_ASSIST_MODE;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/1/30.
|
||||
@@ -35,7 +36,8 @@ public class SlideMenuFragment extends Fragment {
|
||||
activity.getSupportFragmentManager().beginTransaction().replace(viewId, fragment).commit();
|
||||
}
|
||||
|
||||
private SwitchCompat mAutoOperateServiceSwitch;
|
||||
private SwitchCompat mAutoOperateServiceSwitch, mAssistServiceSwitch, mAssistServiceNotificationSwitch;
|
||||
private Receiver mReceiver = new Receiver();
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -49,40 +51,68 @@ public class SlideMenuFragment extends Fragment {
|
||||
if (mAutoOperateServiceSwitch == null) {
|
||||
setUpSwitchCompat();
|
||||
ViewBinder.bind(this);
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(ACTION_CHANGE_ASSIST_MODE);
|
||||
getContext().registerReceiver(mReceiver, filter);
|
||||
}
|
||||
syncSwitchStatus();
|
||||
syncSwitchState();
|
||||
}
|
||||
|
||||
private void syncSwitchStatus() {
|
||||
private void syncSwitchState() {
|
||||
mAutoOperateServiceSwitch.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mAutoOperateServiceSwitch.setChecked(ActionPerformService.isEnable());
|
||||
}
|
||||
}, 450);
|
||||
mAssistServiceSwitch.setChecked(ActionPerformService.isAssistModeEnable());
|
||||
mAssistServiceNotificationSwitch.setChecked(AssistModeSwitchNotification.isEnable());
|
||||
}
|
||||
|
||||
private void setUpSwitchCompat() {
|
||||
mAutoOperateServiceSwitch = $(R.id.sw_auto_operate_service);
|
||||
mAutoOperateServiceSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
if (isChecked && !ActionPerformService.isEnable()) {
|
||||
AccessibilityServiceUtils.goToPermissionSetting(getContext());
|
||||
} else if (!isChecked && ActionPerformService.isEnable()) {
|
||||
ActionPerformService.disable();
|
||||
}
|
||||
}
|
||||
});
|
||||
mAssistServiceSwitch = $(R.id.sw_assist_service);
|
||||
mAssistServiceNotificationSwitch = $(R.id.sw_assist_service_notification);
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.licenses)
|
||||
private void showLicenseDialog() {
|
||||
new LicensesDialog.Builder(getActivity())
|
||||
.setNotices(R.raw.licenses)
|
||||
.setIncludeOwnLicense(true)
|
||||
.build()
|
||||
.showAppCompat();
|
||||
@ViewBinding.Click(R.id.syntax_and_api)
|
||||
private void startSyntaxHelpActivity() {
|
||||
startActivity(new Intent(getContext(), DocumentActivity.class));
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.auto_operate_service)
|
||||
private void clickAutoOperateServiceSwitch() {
|
||||
mAutoOperateServiceSwitch.toggle();
|
||||
}
|
||||
|
||||
@ViewBinding.Check(R.id.sw_auto_operate_service)
|
||||
private void setAutoOperateServiceEnable(boolean enable) {
|
||||
if (enable && !ActionPerformService.isEnable()) {
|
||||
AccessibilityServiceUtils.goToPermissionSetting(getContext());
|
||||
} else if (!enable && ActionPerformService.isEnable()) {
|
||||
ActionPerformService.disable();
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBinding.Check(R.id.sw_assist_service)
|
||||
private void setAssistServiceEnable(boolean enable) {
|
||||
ActionPerformService.setAssistModeEnable(enable);
|
||||
AssistModeSwitchNotification.notifyAssistModeChanged();
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.assist_service)
|
||||
private void toggleAssistServiceSwitch() {
|
||||
mAssistServiceSwitch.toggle();
|
||||
}
|
||||
|
||||
@ViewBinding.Check(R.id.sw_assist_service_notification)
|
||||
private void setAssistServiceNotificationEnable(boolean enable) {
|
||||
AssistModeSwitchNotification.setEnable(enable);
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.assist_service_notification)
|
||||
private void toggleAssistServiceNotificationSwitch() {
|
||||
mAssistServiceNotificationSwitch.toggle();
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.stop_all_running_scripts)
|
||||
@@ -94,19 +124,23 @@ public class SlideMenuFragment extends Fragment {
|
||||
Snackbar.make(getActivityContentView(), "没有正在运行的脚本", Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.syntax_and_api)
|
||||
private void startSyntaxHelpActivity() {
|
||||
startActivity(new Intent(getContext(), DocumentActivity.class));
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
getContext().unregisterReceiver(mReceiver);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.about_app)
|
||||
private void startAboutActivity() {
|
||||
// TODO: 2017/1/30 startAboutActivity
|
||||
Toast.makeText(getContext(), "暂无", Toast.LENGTH_LONG).show();
|
||||
private class Receiver extends BroadcastReceiver {
|
||||
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(ACTION_CHANGE_ASSIST_MODE)) {
|
||||
AssistModeSwitchNotification.notifyAssistModeChanged();
|
||||
mAssistServiceSwitch.setChecked(intent.getBooleanExtra("enable", false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBinding.Click(R.id.auto_operate_service)
|
||||
private void clickAutoOperateServiceSwitch() {
|
||||
mAutoOperateServiceSwitch.setChecked(!mAutoOperateServiceSwitch.isChecked());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
47
app/src/main/java/com/stardust/util/CrashHandler.java
Normal file
@@ -0,0 +1,47 @@
|
||||
package com.stardust.util;
|
||||
|
||||
/**
|
||||
* Created by Stardust on 2017/2/2.
|
||||
*/
|
||||
|
||||
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import com.stardust.scriptdroid.App;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
|
||||
public class CrashHandler implements UncaughtExceptionHandler {
|
||||
private static final String TAG = "CrashHandler";
|
||||
private final Class<?> mErrorReportClass;
|
||||
|
||||
public CrashHandler(Class<?> errorReportClass) {
|
||||
this.mErrorReportClass = errorReportClass;
|
||||
}
|
||||
|
||||
public void uncaughtException(Thread thread, Throwable ex) {
|
||||
try {
|
||||
Log.e("CrashHandler", "Uncaught Exception!!!");
|
||||
ex.printStackTrace();
|
||||
String t = "很抱歉,程序遇到未知错误,即将停止运行\n错误代码:" + ex.toString();
|
||||
Intent intent = new Intent(App.getApp(), this.mErrorReportClass);
|
||||
intent.putExtra("message", t);
|
||||
intent.putExtra("error", throwableToString(ex));
|
||||
App.getApp().startActivity(intent);
|
||||
System.exit(0);
|
||||
} catch (Throwable var6) {
|
||||
var6.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static String throwableToString(Throwable throwable) {
|
||||
StringWriter sw = new StringWriter();
|
||||
PrintWriter pw = new PrintWriter(sw);
|
||||
throwable.printStackTrace(pw);
|
||||
return sw.toString();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.stardust.view;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.CompoundButton;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -21,7 +22,31 @@ public class ViewBinder {
|
||||
}
|
||||
Method[] methods = o.getClass().getDeclaredMethods();
|
||||
for (Method method : methods) {
|
||||
method.setAccessible(true);
|
||||
bindClick(o, method, findViewById);
|
||||
bindCheck(o, method, findViewById);
|
||||
}
|
||||
}
|
||||
|
||||
private static void bindCheck(final Object o, final Method method, Method findViewById) {
|
||||
ViewBinding.Check annotation = method.getAnnotation(ViewBinding.Check.class);
|
||||
if (annotation == null || annotation.value() == 0)
|
||||
return;
|
||||
int id = annotation.value();
|
||||
try {
|
||||
CompoundButton button = (CompoundButton) findViewById.invoke(o, id);
|
||||
button.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
try {
|
||||
method.invoke(o, isChecked);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +70,6 @@ public class ViewBinder {
|
||||
|
||||
private static void invokeMethod(Object o, Method method) {
|
||||
try {
|
||||
method.setAccessible(true);
|
||||
method.invoke(o);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
||||
@@ -26,4 +26,10 @@ public @interface ViewBinding {
|
||||
@interface Click {
|
||||
int value();
|
||||
}
|
||||
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@interface Check {
|
||||
int value();
|
||||
}
|
||||
}
|
||||
|
||||
BIN
app/src/main/res/drawable/ic_developer_512.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
app/src/main/res/drawable/ic_email_black_48dp.png
Normal file
|
After Width: | Height: | Size: 425 B |
BIN
app/src/main/res/drawable/ic_github_mark.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
app/src/main/res/drawable/ic_money_black.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
app/src/main/res/drawable/ic_notifications_green_48dp.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
app/src/main/res/drawable/ic_qq.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
app/src/main/res/drawable/ic_qq_black.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/drawable/ic_robot_head_green.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 1.9 KiB |
BIN
app/src/main/res/drawable/ic_share_white_48dp.png
Normal file
|
After Width: | Height: | Size: 938 B |
94
app/src/main/res/layout/activity_about.xml
Normal file
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#f9f9f9"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"
|
||||
app:title="@string/text_about"/>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/icon_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="200dp"
|
||||
android:background="@android:color/white"
|
||||
android:clickable="true"
|
||||
android:foreground="?selectableItemBackgroundBorderless">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
android:layout_width="90dp"
|
||||
android:layout_height="90dp"
|
||||
android:layout_centerInParent="true"
|
||||
android:src="@drawable/script_droid"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/icon"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/version"
|
||||
android:textColor="#777777"
|
||||
android:textSize="14sp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include layout="@layout/activity_about_items"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:gravity="center"
|
||||
android:text="@string/copyright"
|
||||
android:textColor="#777777"
|
||||
android:textSize="14sp"/>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/share"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:clickable="true"
|
||||
android:src="@drawable/ic_share_white_48dp"
|
||||
app:layout_anchor="@id/icon_container"
|
||||
app:layout_anchorGravity="bottom|right|end"/>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
143
app/src/main/res/layout/activity_about_items.xml
Normal file
@@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:background="@android:color/white"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/developer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:src="@drawable/ic_developer_512"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/developer"
|
||||
android:textColor="@android:color/secondary_text_light"
|
||||
android:textSize="16sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/divider"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/github"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:clickable="true"
|
||||
android:foreground="?selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:src="@drawable/ic_github_mark"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/github"
|
||||
android:textColor="@android:color/secondary_text_light"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="16sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/divider"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/email"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:src="@drawable/ic_email_black_48dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/email"
|
||||
android:textColor="@android:color/secondary_text_light"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="16sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/divider"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/qq"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:src="@drawable/ic_qq_black"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/qq"
|
||||
android:textColor="@android:color/secondary_text_light"
|
||||
android:textIsSelectable="true"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/divider"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/donate"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:src="@drawable/ic_money_black"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/donate_developer"
|
||||
android:textColor="@android:color/secondary_text_light"
|
||||
android:textSize="16sp"/>
|
||||
</LinearLayout>
|
||||
|
||||
<include layout="@layout/divider"/>
|
||||
</LinearLayout>
|
||||
23
app/src/main/res/layout/activity_error_report.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay">
|
||||
|
||||
</android.support.v7.widget.Toolbar>
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
</LinearLayout>
|
||||
28
app/src/main/res/layout/activity_settings.xml
Normal file
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fragment_setting"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
</LinearLayout>
|
||||
7
app/src/main/res/layout/divider.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<View xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:background="#e4e4e4"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingStart="16dp"/>
|
||||
@@ -5,6 +5,28 @@
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/syntax_and_api"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_js"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/text_syntax_and_api"
|
||||
android:textColor="@android:color/primary_text_light"/>
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/auto_operate_service"
|
||||
android:layout_width="match_parent"
|
||||
@@ -39,27 +61,71 @@
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/syntax_and_api"
|
||||
<RelativeLayout
|
||||
android:id="@+id/assist_service"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon_assist_service"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_js"/>
|
||||
android:src="@drawable/ic_service_green"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toRightOf="@id/icon_assist_service"
|
||||
android:gravity="center"
|
||||
android:text="@string/text_syntax_and_api"
|
||||
android:text="@string/text_assist_service"
|
||||
android:textColor="@android:color/primary_text_light"/>
|
||||
</LinearLayout>
|
||||
|
||||
<android.support.v7.widget.SwitchCompat
|
||||
android:id="@+id/sw_assist_service"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="16dp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/assist_service_notification"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon_assist_service_notification"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_notifications_green_48dp"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_toRightOf="@id/icon_assist_service_notification"
|
||||
android:gravity="center"
|
||||
android:text="@string/text_assist_service_notification"
|
||||
android:textColor="@android:color/primary_text_light"/>
|
||||
|
||||
<android.support.v7.widget.SwitchCompat
|
||||
android:id="@+id/sw_assist_service_notification"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="16dp"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/stop_all_running_scripts"
|
||||
@@ -83,47 +149,4 @@
|
||||
android:textColor="@android:color/primary_text_light"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/about_app"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_about_us_green_100px"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/text_about"
|
||||
android:textColor="@android:color/primary_text_light"/>
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/licenses"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="52dp"
|
||||
android:background="?selectableItemBackground"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_margin="16dp"
|
||||
android:src="@drawable/ic_license_green"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:gravity="center"
|
||||
android:text="@string/text_licenses"
|
||||
android:textColor="@android:color/primary_text_light"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -12,4 +12,23 @@
|
||||
<copyright>Copyright 2008 Google Inc.</copyright>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>DuktapeJava</name>
|
||||
<url>https://github.com/gubaojian/DuktapeJava</url>
|
||||
<copyright/>
|
||||
<license>MIT License</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>920 Text Editor</name>
|
||||
<url>https://github.com/jecelyin/920-text-editor-v2</url>
|
||||
<copyright/>
|
||||
<license>Apache Software License 2.0</license>
|
||||
</notice>
|
||||
<notice>
|
||||
<name>MarkDown</name>
|
||||
<url>https://github.com/zzhoujay/Markdown</url>
|
||||
<copyright>Copyright (c) 2015 zzhoujay</copyright>
|
||||
<license>MIT License</license>
|
||||
</notice>
|
||||
|
||||
</notices>
|
||||
@@ -1,5 +1,6 @@
|
||||
<resources>
|
||||
<string name="app_name">免Root脚本机器人</string>
|
||||
<string name="version">Version 1.17.0202</string>
|
||||
<string name="action_settings">设置</string>
|
||||
<string name="action_disable_service">关闭服务</string>
|
||||
<string name="text_accessibility_service_description">使脚本自动操作(点击、长按、滑动等)所需,若关闭则只能执行不涉及自动操作的脚本。</string>
|
||||
@@ -32,7 +33,6 @@
|
||||
<string name="text_setting">设置</string>
|
||||
<string name="text_exit">退出</string>
|
||||
<string name="text_auto_operate_service">自动操作服务</string>
|
||||
<string name="version">Version 1.17.0130</string>
|
||||
<string name="text_syntax_and_api">语法与API</string>
|
||||
<string name="text_close_all_running_scripts">关闭所有正在运行的脚本</string>
|
||||
<string name="text_about">关于</string>
|
||||
@@ -41,4 +41,23 @@
|
||||
<string name="text_sample_open_what_moment">示例:打开朋友圈</string>
|
||||
<string name="text_sample_open_running_services">示例:打开正在运行的服务(安卓6.0+)</string>
|
||||
<string name="text_sample_simple_calculator">示例:简单计算器</string>
|
||||
<string name="copyright">Copyright©2016 All right reserves.</string>
|
||||
<string name="developer">星尘幻影</string>
|
||||
<string name="qq">946994919</string>
|
||||
<string name="email">hybbbb1996@gmail.com</string>
|
||||
<string name="github">软件源代码</string>
|
||||
<string name="text_already_copy_to_clip">已复制到剪贴板</string>
|
||||
<string name="donate_developer">打赏作者</string>
|
||||
<string name="text_email">邮箱</string>
|
||||
<string name="my_github">https://github.com/hyb1996/NoRootScriptDroid</string>
|
||||
<string name="share_app">[免Root脚本机器人]下载地址:https://github.com/hyb1996/NoRootScriptDroid/releases</string>
|
||||
<string name="text_assist_service">脚本辅助服务</string>
|
||||
<string name="text_assist_serivce_notification">通知栏显示脚本辅助开关</string>
|
||||
<string name="text_assist_service_notification">通知栏显示脚本辅助开关</string>
|
||||
<string name="text_others">其他</string>
|
||||
<string name="text_assist_mode_enabled">脚本辅助已开启(点击关闭)</string>
|
||||
<string name="text_assist_mode_disabled">脚本辅助已关闭(点击开启)</string>
|
||||
<string name="text_error_report">错误报告</string>
|
||||
<string name="text_sample_hello_big_sister">大姐姐好</string>
|
||||
<string name="text_press_again_to_exit">再按一次退出程序</string>
|
||||
</resources>
|
||||
|
||||
14
app/src/main/res/xml/preferences.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceCategory
|
||||
android:title="@string/text_about">
|
||||
|
||||
<Preference
|
||||
android:title="@string/text_about"/>
|
||||
|
||||
<Preference
|
||||
android:title="@string/text_licenses"/>
|
||||
</PreferenceCategory>
|
||||
|
||||
</PreferenceScreen>
|
||||