diff --git a/src/main/java/org/qpython/qsl4a/qsl4a/Process.java b/src/main/java/org/qpython/qsl4a/qsl4a/Process.java
index 68ab1076a7cec501f0bf4c103a01bd3723bd7618..67becf3a08590f89581f9801f8d6415045af66e2 100644
--- a/src/main/java/org/qpython/qsl4a/qsl4a/Process.java
+++ b/src/main/java/org/qpython/qsl4a/qsl4a/Process.java
@@ -16,8 +16,6 @@
package org.qpython.qsl4a.qsl4a;
-import android.content.Context;
-
import org.qpython.qsl4a.codec.StreamGobbler;
import org.qpython.qsl4a.qsl4a.interpreter.InterpreterConstants;
@@ -108,7 +106,7 @@ public class Process {
return mIn;
}
- public void start(Context context, final Runnable shutdownHook) {
+ public void start(final Runnable shutdownHook) {
if (isAlive()) {
throw new RuntimeException("Attempted to start process that is already running.");
}
@@ -119,19 +117,17 @@ public class Process {
int[] pid = new int[1];
String[] argumentsArray = mArguments.toArray(new String[mArguments.size()]);
-// mLog = new File(String.format("%s/%s.log", InterpreterConstants.SDCARD_SL4A_ROOT, getName()));
- mLog = new File(String.format("%s/%s.log", FileUtils.getRootPath(context.getApplicationContext()), getName()));
+ mLog = new File(String.format("%s/%s.log", InterpreterConstants.SDCARD_SL4A_ROOT, getName()));
mFd =
Exec.createSubprocess(binaryPath, argumentsArray, getEnvironmentArray(),
- getWorkingDirectory(context), pid);
+ getWorkingDirectory(), pid);
mPid.set(pid[0]);
mOut = new FileOutputStream(mFd);
mIn = new StreamGobbler(new FileInputStream(mFd), mLog, DEFAULT_BUFFER_SIZE);
mStartTime = System.currentTimeMillis();
new Thread(new Runnable() {
- @Override
public void run() {
int result = Exec.waitFor(mPid.get());
mEndTime = System.currentTimeMillis();
@@ -203,7 +199,7 @@ public class Process {
mName = name;
}
- public String getWorkingDirectory(Context context) {
+ public String getWorkingDirectory() {
return null;
}
-}
\ No newline at end of file
+}
diff --git a/src/main/java/org/qpython/qsl4a/qsl4a/ScriptLauncher.java b/src/main/java/org/qpython/qsl4a/qsl4a/ScriptLauncher.java
index 45dd43c84a34d8d0b87d32a6b84736a622543342..4bb294b27300fe1807fe0893b4720f0902b0f7b8 100644
--- a/src/main/java/org/qpython/qsl4a/qsl4a/ScriptLauncher.java
+++ b/src/main/java/org/qpython/qsl4a/qsl4a/ScriptLauncher.java
@@ -17,7 +17,6 @@
package org.qpython.qsl4a.qsl4a;
import android.app.Service;
-import android.content.Context;
import android.content.Intent;
@@ -60,7 +59,7 @@ public class ScriptLauncher {
return task;
}
- public static InterpreterProcess launchInterpreter(Context context, final AndroidProxy proxy, Intent intent,
+ public static InterpreterProcess launchInterpreter(final AndroidProxy proxy, Intent intent,
InterpreterConfiguration config, Runnable shutdownHook) {
Interpreter interpreter;
String interpreterName;
@@ -68,33 +67,33 @@ public class ScriptLauncher {
interpreter = config.getInterpreterByName(interpreterName);
InterpreterProcess process = new InterpreterProcess(interpreter, proxy);
if (shutdownHook == null) {
- process.start(context,new Runnable() {
+ process.start(new Runnable() {
@Override
public void run() {
proxy.shutdown();
}
});
} else {
- process.start(context,shutdownHook);
+ process.start(shutdownHook);
}
return process;
}
- public static ScriptProcess launchScript(Context context,File script, InterpreterConfiguration configuration,
+ public static ScriptProcess launchScript(File script, InterpreterConfiguration configuration,
final AndroidProxy proxy, Runnable shutdownHook) {
if (!script.exists()) {
throw new RuntimeException("No such script to launch.");
}
ScriptProcess process = new ScriptProcess(script, configuration, proxy);
if (shutdownHook == null) {
- process.start(context,new Runnable() {
+ process.start(new Runnable() {
@Override
public void run() {
proxy.shutdown();
}
});
} else {
- process.start(context,shutdownHook);
+ process.start(shutdownHook);
}
return process;
}
diff --git a/src/main/java/org/qpython/qsl4a/qsl4a/facade/AndroidFacade.java b/src/main/java/org/qpython/qsl4a/qsl4a/facade/AndroidFacade.java
index 62991ca7c7c8c51d52c52c767b96856c304f2e13..fb219a19fad3351d2bc2530d7fd47c7febabb98c 100644
--- a/src/main/java/org/qpython/qsl4a/qsl4a/facade/AndroidFacade.java
+++ b/src/main/java/org/qpython/qsl4a/qsl4a/facade/AndroidFacade.java
@@ -17,36 +17,32 @@
package org.qpython.qsl4a.qsl4a.facade;
import android.annotation.SuppressLint;
-import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
-import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
-import android.hardware.camera2.CameraCharacteristics;
-import android.hardware.camera2.CameraManager;
import android.net.Uri;
-import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
+import android.os.Message;
import android.os.StatFs;
import android.os.Vibrator;
-import android.support.annotation.RequiresApi;
import android.text.ClipboardManager;
-import android.text.InputType;
-import android.text.method.PasswordTransformationMethod;
-import android.widget.EditText;
import android.widget.Toast;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
import org.qpython.qsl4a.QSL4APP;
-import org.qpython.qsl4a.qsl4a.FileUtils;
+import org.qpython.qsl4a.qsl4a.util.FileUtils;
import org.qpython.qsl4a.qsl4a.FutureActivityTaskExecutor;
import org.qpython.qsl4a.qsl4a.LogUtil;
import org.qpython.qsl4a.qsl4a.NotificationIdFactory;
@@ -54,10 +50,10 @@ import org.qpython.qsl4a.qsl4a.future.FutureActivityTask;
import org.qpython.qsl4a.qsl4a.jsonrpc.RpcReceiver;
import org.qpython.qsl4a.qsl4a.rpc.Rpc;
import org.qpython.qsl4a.qsl4a.rpc.RpcDefault;
-import org.qpython.qsl4a.qsl4a.rpc.RpcDeprecated;
import org.qpython.qsl4a.qsl4a.rpc.RpcOptional;
import org.qpython.qsl4a.qsl4a.rpc.RpcParameter;
-
+import org.qpython.qsl4a.qsl4a.util.HtmlUtil;
+import org.qpython.qsl4a.qsl4a.util.SPFUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
@@ -66,11 +62,6 @@ import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.qpython.qsl4a.qsl4a.util.SPFUtils;
-
/**
* Some general purpose Android routines.
*
Intents
Intents are returned as a map, in the following form:
@@ -98,8 +89,8 @@ public class AndroidFacade extends RpcReceiver {
int getLogo48();
}
- private final Service mService;
- private final Handler mHandler;
+ public final Service mService;
+ public final Handler mHandler;
private final Intent mIntent;
private final FutureActivityTaskExecutor mTaskQueue;
@@ -108,11 +99,11 @@ public class AndroidFacade extends RpcReceiver {
private final Resources mResources;
private ClipboardManager mClipboard = null;
-
- //乘着船 修改
public final Context context;
public final String qpyProvider;
+ public static Handler handler;
+
private final int intentFlags = Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION ;
@Override
@@ -138,11 +129,10 @@ public class AndroidFacade extends RpcReceiver {
//乘着船 修改
context = mService.getApplicationContext();
qpyProvider = context.getPackageName() + ".provider";
-
}
ClipboardManager getClipboardManager() {
- Object clipboard = null;
+ Object clipboard;
if (mClipboard == null) {
try {
clipboard = mService.getSystemService(Context.CLIPBOARD_SERVICE);
@@ -203,6 +193,46 @@ public class AndroidFacade extends RpcReceiver {
}
}
+ Intent startActivityForResultCode(final Intent intent) {
+ FutureActivityTask task = new FutureActivityTask() {
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ try {
+ int requestCode;
+ if (intent!=null){
+ requestCode=intent.getIntExtra("REQUEST_CODE",1024);
+ } else {
+ requestCode=2048;
+ }
+ startActivityForResult(intent, requestCode);
+ } catch (Exception e) {
+ if(intent!=null) {
+ intent.putExtra("EXCEPTION", e.getMessage());
+ setResult(intent);
+ }
+ }
+ }
+
+ @Override
+ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (data==null)
+ data=new Intent();
+ data.putExtra("RESULT_CODE",resultCode);
+ setResult(data);
+ }
+ };
+ mTaskQueue.execute(task);
+
+ try {
+ return task.getResult();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ task.finish();
+ }
+ }
+
// TODO(damonkohler): Pull this out into proper argument deserialization and support
// complex/nested types being passed in.
public static void putExtrasFromJsonObject(JSONObject extras, Intent intent) throws JSONException {
@@ -210,9 +240,9 @@ public class AndroidFacade extends RpcReceiver {
for (int i = 0; i < names.length(); i++) {
String name = names.getString(i);
Object data = extras.get(name);
- if (data == null) {
- continue;
- }
+ //if (data == null) {
+ // continue;
+ //}
if (data instanceof Integer) {
intent.putExtra(name, (Integer) data);
}
@@ -374,12 +404,12 @@ public class AndroidFacade extends RpcReceiver {
}
}
- void startActivity(final Intent intent) {
+ void startActivity(final Intent intent) throws Exception {
try {
intent.setFlags(intent.getFlags() | intentFlags);
context.startActivity(intent);
} catch (Exception e) {
- LogUtil.e("Failed to launch intent.", e);
+ throw new Exception("Failed to launch intent : "+ e);
}
}
@@ -463,6 +493,44 @@ public class AndroidFacade extends RpcReceiver {
}
}
+ public void doStartActivity(final Intent intent, Boolean wait,int flags) throws Exception {
+ if (wait == null || !wait) {
+ startActivity(intent);
+ } else {
+ FutureActivityTask task = new FutureActivityTask() {
+ private boolean mSecondResume = false;
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ intent.setFlags(intent.getFlags() | intentFlags);
+ startActivity(intent);
+ }
+
+ @Override
+ public void onResume() {
+ if (mSecondResume) {
+ finish();
+ }
+ mSecondResume = true;
+ }
+
+ @Override
+ public void onDestroy() {
+ setResult(null);
+ }
+
+ };
+ mTaskQueue.execute(task,flags);
+
+ try {
+ task.getResult();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
/**
* packagename and classname, if provided, are used in a 'setComponent' call.
*/
@@ -537,16 +605,26 @@ public class AndroidFacade extends RpcReceiver {
mVibrator.vibrate(duration);
}
- @Rpc(description = "Displays a short-duration Toast notification.")
+ @Rpc(description = "Displays a Toast notification.")
public void makeToast(@RpcParameter(name = "message") final String message,
- @RpcParameter(name = "length") @RpcDefault("0") final Integer length) {
- mHandler.post(new Runnable() {
- public void run() {
- Toast.makeText(mService, message, length).show();
- }
+ @RpcParameter(name = "length") @RpcDefault("0") final Integer length,
+ @RpcParameter(name = "isHtml") @RpcDefault("false") final Boolean isHtml) {
+ mHandler.post(() -> {
+ if(isHtml)
+ Toast.makeText(mService, HtmlUtil.textToHtml(message), length).show();
+ else
+ Toast.makeText(mService, message, length).show();
});
}
+ public void makeToast(final String message,final Integer length) {
+ makeToast(message,length,false);
+ }
+
+ public void makeToast(final String message) {
+ makeToast(message,0,false);
+ }
+
/* 乘着船:过时删除
private String getInputFromAlertDialog(final String title, final String message,
final boolean password) {
@@ -610,29 +688,52 @@ public class AndroidFacade extends RpcReceiver {
private static int NOTIFICATION_ID = 0x20002;//通知栏消息id
+ @SuppressLint("UnspecifiedImmutableFlag")
@Rpc(description = "Displays a notification that will be canceled when the user clicks on it.")
public void notify(
@RpcParameter(name = "title", description = "title") final String title,
@RpcParameter(name = "message") final String message,
- @RpcParameter(name = "attachmentUri") @RpcOptional final String attachmentUri) {
+ @RpcParameter(name = "uri") @RpcOptional final String uri,
+ @RpcParameter(name = "arg") @RpcOptional final String arg) {
// This contentIntent is a noop.
Intent intent;
-
- if (attachmentUri!=null) {
- android.util.Log.d("AndroidFacade", "attachmentUri:"+attachmentUri);
- if (attachmentUri.startsWith("http:") || attachmentUri.startsWith("https:")) {
- intent = SPFUtils.getLinkAsIntent(context, attachmentUri);
+ PendingIntent contentIntent = null;
+ if (uri!=null) {
+ //android.util.Log.d("AndroidFacade", "attachmentUri:"+attachmentUri);
+ if (uri.startsWith("http:") || uri.startsWith("https:")) {
+ intent = SPFUtils.getLinkAsIntent(context, uri);
} else {
+ if (uri.endsWith(".py")) {
+ try{
+ intent = new Intent (context,NotificationClickReceiver.class);
+ intent.putExtra("path",uri);
+ intent.putExtra("arg",arg);
+ contentIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ } catch (Exception e) {
+ intent = new Intent();
+ intent.setClassName(mService.getPackageName(), "org.qpython.qpylib.MPyApi");
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setAction("org.qpython.qpylib.action.MPyApi");
+ Bundle mBundle = new Bundle();
+ mBundle.putString("app", SPFUtils.getCode(mService.getApplicationContext()));
+ mBundle.putString("act", "onPyApi");
+ mBundle.putString("flag", "api");
+ mBundle.putString("param", "fileapi");
+ mBundle.putString("pyfile", uri);
+ mBundle.putString("pyarg", arg);
+ intent.putExtras(mBundle);
+ }
+ } else {
intent = new Intent();
- intent.setClassName(context.getPackageName(), attachmentUri);
-
- }
+ intent.setClassName(context.getPackageName(), uri);
+ }}
} else {
intent = new Intent();
}
- PendingIntent contentIntent = PendingIntent.getActivity(mService, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
+ if(contentIntent == null)
+ contentIntent = PendingIntent.getActivity(mService, NOTIFICATION_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = SPFUtils.getNotification(context, title, message, contentIntent,
- SPFUtils.getDrawableId(mService, "img_home_logo"), null, Notification.FLAG_AUTO_CANCEL);
+ SPFUtils.getDrawableId(mService, "img_home_logo"), null);
// Get a unique notification id from the application.
mNotificationManager.notify(NotificationIdFactory.create(), notification);
@@ -654,7 +755,7 @@ public class AndroidFacade extends RpcReceiver {
@RpcParameter(name = "to", description = "A comma separated list of recipients.") final String to,
@RpcParameter(name = "subject") final String subject,
@RpcParameter(name = "body") final String body,
- @RpcParameter(name = "attachmentUri") @RpcOptional final String attachmentUri) {
+ @RpcParameter(name = "attachmentUri") @RpcOptional final String attachmentUri) throws Exception {
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("plain/text");
intent.putExtra(android.content.Intent.EXTRA_EMAIL, to.split(","));
@@ -742,7 +843,7 @@ public class AndroidFacade extends RpcReceiver {
zone.put("offset", tz.getOffset((new Date()).getTime()));
result.put("TZ", zone);
result.put("SDK", android.os.Build.VERSION.SDK);
- result.put("download", FileUtils.getExternalDownload(context).getAbsolutePath());
+ result.put("download", FileUtils.getExternalDownload().getAbsolutePath());
result.put("appcache", mService.getCacheDir().getAbsolutePath());
try {
StatFs fs = new StatFs("/sdcard");
@@ -783,4 +884,17 @@ public class AndroidFacade extends RpcReceiver {
return result;
}
+ public static class NotificationClickReceiver extends BroadcastReceiver {
+ public NotificationClickReceiver(){}
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ Message msg = new Message();
+ msg.obj = new String[]{
+ intent.getStringExtra("path"),
+ intent.getStringExtra("arg")
+ };
+ handler.sendMessage(msg);
+ }
+ }
}
diff --git a/src/main/java/org/qpython/qsl4a/qsl4a/facade/ApplicationManagerFacade.java b/src/main/java/org/qpython/qsl4a/qsl4a/facade/ApplicationManagerFacade.java
index 57518fc0459fc4ca067d22963ad78dec9add6a12..eefcf3626e647b8d3437275f1fd9ee5534721567 100644
--- a/src/main/java/org/qpython/qsl4a/qsl4a/facade/ApplicationManagerFacade.java
+++ b/src/main/java/org/qpython/qsl4a/qsl4a/facade/ApplicationManagerFacade.java
@@ -4,12 +4,16 @@ import android.app.ActivityManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import org.qpython.qsl4a.qsl4a.jsonrpc.RpcReceiver;
import org.qpython.qsl4a.qsl4a.rpc.Rpc;
+import org.qpython.qsl4a.qsl4a.rpc.RpcDefault;
+import org.qpython.qsl4a.qsl4a.rpc.RpcOptional;
import org.qpython.qsl4a.qsl4a.rpc.RpcParameter;
import java.util.ArrayList;
@@ -29,6 +33,7 @@ public class ApplicationManagerFacade extends RpcReceiver {
private final AndroidFacade mAndroidFacade;
private final ActivityManager mActivityManager;
private final PackageManager mPackageManager;
+ private final Context context;
public ApplicationManagerFacade(FacadeManager manager) {
super(manager);
@@ -36,31 +41,83 @@ public class ApplicationManagerFacade extends RpcReceiver {
mAndroidFacade = manager.getReceiver(AndroidFacade.class);
mActivityManager = (ActivityManager) service.getSystemService(Context.ACTIVITY_SERVICE);
mPackageManager = service.getPackageManager();
+ context = mAndroidFacade.context;
}
- @Rpc(description = "Returns a list of all launchable application class names.")
- public Map getLaunchableApplications() {
+ @Rpc(description = "Returns a list of all launchable packages with class name and application name .")
+ public Map getLaunchablePackages(
+ @RpcParameter(name = "need class name") @RpcDefault("false") Boolean needClassName) {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List resolveInfos = mPackageManager.queryIntentActivities(intent, 0);
Map applications = new HashMap();
+ if (needClassName){
+ for (ResolveInfo info : resolveInfos) {
+ applications.put(info.activityInfo.packageName, info.activityInfo.name+"|"+info.loadLabel(mPackageManager).toString());
+ }}
+ else {
for (ResolveInfo info : resolveInfos) {
- applications.put(info.loadLabel(mPackageManager).toString(), info.activityInfo.name);
- }
+ applications.put(info.activityInfo.packageName, info.loadLabel(mPackageManager).toString());
+ }}
return applications;
}
- @Rpc(description = "Start activity with the given class name.")
- public void launch(@RpcParameter(name = "className") String className) {
- Intent intent = new Intent(Intent.ACTION_MAIN);
- String packageName = className.substring(0, className.lastIndexOf("."));
- intent.setClassName(packageName, className);
- mAndroidFacade.startActivity(intent);
+ /*@Rpc(description = "get all packages")
+ public Map getAllPackages() {
+ Map packages = new HashMap<>();
+ List packageInfos = context.getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES |
+ PackageManager.GET_SERVICES);
+ for (PackageInfo info : packageInfos) {
+ packages.put(info.packageName, info.applicationInfo.loadLabel(mPackageManager).toString());
+ }
+ return packages;
+ }
+
+ @Rpc(description = "get system packages")
+ public Map getSystemPackages() {
+ Map packages = new HashMap<>();
+ List packageInfos = context.getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES |
+ PackageManager.GET_SERVICES);
+ for (PackageInfo info : packageInfos) {
+ if(((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) || ((info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1))
+ packages.put(info.packageName, info.applicationInfo.loadLabel(mPackageManager).toString());
+ }
+ return packages;
+ }
+
+ @Rpc(description = "get user packages")
+ public Map getUserPackages() {
+ Map packages = new HashMap<>();
+ List packageInfos = context.getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES |
+ PackageManager.GET_SERVICES);
+ for (PackageInfo info : packageInfos) {
+ if(((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 1) && ((info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 1))
+ packages.put(info.packageName, info.applicationInfo.loadLabel(mPackageManager).toString());
+ }
+ return packages;
+ }*/
+
+ @Rpc(description = "Start activity with the given classname and/or packagename .")
+ public void launch(@RpcParameter(name = "classname") @RpcOptional final String classname,
+ @RpcParameter(name = "packagename") @RpcOptional String packagename,
+ @RpcParameter(name = "wait") @RpcDefault("true") final Boolean wait)
+ throws Exception {
+ Intent intent;
+ if (classname == null) {
+ intent=context.getPackageManager().getLaunchIntentForPackage(packagename);
+ } else {
+ intent = new Intent(Intent.ACTION_MAIN);
+ if (packagename == null) {
+ packagename = classname.substring(0, classname.lastIndexOf("."));
+ }
+ intent.setClassName(packagename, classname);
+ }
+ mAndroidFacade.doStartActivity(intent,wait);
}
@Rpc(description = "Returns a list of packages running activities or services.", returns = "List of packages running activities.")
- public List getRunningPackages() {
- Set runningPackages = new HashSet();
+ public Set getRunningPackages() {
+ Set runningPackages = new HashSet<>();
List appProcesses =
mActivityManager.getRunningAppProcesses();
for (ActivityManager.RunningAppProcessInfo info : appProcesses) {
@@ -71,13 +128,46 @@ public class ApplicationManagerFacade extends RpcReceiver {
for (ActivityManager.RunningServiceInfo info : serviceProcesses) {
runningPackages.add(info.service.getPackageName());
}
- return new ArrayList(runningPackages);
+ return runningPackages;
+ }
+
+ @Rpc(description = "get installed packages")
+ public Map getInstalledPackages(
+ @RpcParameter(name = "flag") @RpcDefault("4") final Integer flag
+ ) {
+ Map packages = new HashMap<>();
+ List packageInfos = context.getPackageManager().getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES);
+ boolean allow;
+ for (PackageInfo info : packageInfos) {
+ switch (flag) {
+ case 5://所有应用
+ allow = true;
+ break;
+ case 4://用户应用
+ allow = ( info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM ) == 0;
+ break;
+ case 3://系统应用
+ allow = ( info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM ) != 0;
+ break;
+ case 2://系统已更新应用
+ allow = ( info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP ) != 0;
+ break;
+ case 1://系统未更新应用
+ allow = ( info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM ) != 0 && ( info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP ) == 0;
+ break;
+ default:
+ allow = false;
+ }
+ if(allow)
+ packages.put(info.packageName, info.applicationInfo.loadLabel(mPackageManager).toString());
+ }
+ return packages;
}
@SuppressWarnings("deprecation")
@Rpc(description = "Force stops a package.")
public void forceStopPackage(
- @RpcParameter(name = "packageName", description = "name of package") String packageName) {
+ @RpcParameter(name = "packageName", description = "name of package") final String packageName) {
mActivityManager.restartPackage(packageName);
}
diff --git a/src/main/java/org/qpython/qsl4a/qsl4a/facade/CameraFacade.java b/src/main/java/org/qpython/qsl4a/qsl4a/facade/CameraFacade.java
index 189015288107af56a78efc9f221b0f70f126f7ad..806cdab8e98246cfa4ea8b57e4f00e52e0ea47d4 100644
--- a/src/main/java/org/qpython/qsl4a/qsl4a/facade/CameraFacade.java
+++ b/src/main/java/org/qpython/qsl4a/qsl4a/facade/CameraFacade.java
@@ -16,7 +16,6 @@
package org.qpython.qsl4a.qsl4a.facade;
-import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
@@ -38,7 +37,7 @@ import android.view.WindowManager;
import android.view.SurfaceHolder.Callback;
import org.qpython.qsl4a.QSL4APP;
-import org.qpython.qsl4a.qsl4a.FileUtils;
+import org.qpython.qsl4a.qsl4a.util.FileUtils;
import org.qpython.qsl4a.qsl4a.FutureActivityTaskExecutor;
import org.qpython.qsl4a.qsl4a.LogUtil;
diff --git a/src/main/java/org/qpython/qsl4a/qsl4a/facade/CipherFacade.java b/src/main/java/org/qpython/qsl4a/qsl4a/facade/CipherFacade.java
index 1dcf35b3de567666dc21414d1b13812a3453a4d5..9446abe6bc39a26cd509529e66ecfc97182403d2 100644
--- a/src/main/java/org/qpython/qsl4a/qsl4a/facade/CipherFacade.java
+++ b/src/main/java/org/qpython/qsl4a/qsl4a/facade/CipherFacade.java
@@ -11,7 +11,9 @@ import org.qpython.qsl4a.qsl4a.rpc.RpcParameter;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
+import java.nio.ByteBuffer;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
@@ -35,27 +37,22 @@ public class CipherFacade extends RpcReceiver {
mPackageManager = mService.getPackageManager();
}
- private static byte[] readFromFile(String filePath) {
- try {
- File file = new File(filePath);
- FileInputStream fis = new FileInputStream(file);
- int length = fis.available();
- byte[] data = new byte[length];
- fis.read(data);
- fis.close();
- return data;
- } catch (Exception e) {
- e.printStackTrace();
- return new byte[0];
- }}
-
- private static void writeToFile(String filePath, byte[] data) {
- try {
- FileOutputStream fos = new FileOutputStream(filePath);
- fos.write(data);
- fos.flush();
- fos.close();
- } catch (Exception e) {e.printStackTrace();}}
+ private static byte[] readFromFile(String filePath) throws Exception {
+ File file = new File(filePath);
+ FileInputStream fis = new FileInputStream(file);
+ int length = fis.available();
+ byte[] data = new byte[length];
+ fis.read(data);
+ fis.close();
+ return data;
+ }
+
+ private static void writeToFile(String filePath, byte[] data) throws Exception {
+ FileOutputStream fos = new FileOutputStream(filePath);
+ fos.write(data);
+ fos.flush();
+ fos.close();
+ }
/**
* @function cipherInit 加密解密引擎设置
@@ -91,11 +88,12 @@ public class CipherFacade extends RpcReceiver {
} else {
InitialVector = initialVector.getBytes(encodingFormat);
}
- /*if (InitialVector.length > 16){
- byte[] IV = {};
- System.arraycopy(InitialVector,0,IV,0,16);
- InitialVector = IV;
- }*/
+ }
+ if (InitialVector.length > 16){
+ //InitialVector长度大于16时自动截取
+ byte[] IV = new byte[16];
+ System.arraycopy(InitialVector,0,IV,0,16);
+ InitialVector = IV;
}
//Algorithm 加密算法如AES
String Algorithm;
diff --git a/src/main/java/org/qpython/qsl4a/qsl4a/facade/CommonIntentsFacade.java b/src/main/java/org/qpython/qsl4a/qsl4a/facade/CommonIntentsFacade.java
index f0baf0d40df396ac3783da8975c3d79e1687f5a3..7cf9a36cb3c8c68528856fa40c1e40bb6ab86777 100644
--- a/src/main/java/org/qpython/qsl4a/qsl4a/facade/CommonIntentsFacade.java
+++ b/src/main/java/org/qpython/qsl4a/qsl4a/facade/CommonIntentsFacade.java
@@ -69,7 +69,7 @@ public class CommonIntentsFacade extends RpcReceiver {
}
}
- private void view(Uri uri, String type) {
+ private void view(Uri uri, String type) throws Exception {
Intent intent = new Intent();
intent.setClassName(this.mAndroidFacade.getmService().getApplicationContext(),"org.qpython.qpy.main.QWebViewActivity");
@@ -96,7 +96,7 @@ public class CommonIntentsFacade extends RpcReceiver {
}
@Rpc(description = "Opens the list of contacts.")
- public void viewContacts() throws JSONException {
+ public void viewContacts() throws Exception {
view(People.CONTENT_URI, null);
}
@@ -123,7 +123,7 @@ public class CommonIntentsFacade extends RpcReceiver {
}
@Rpc(description = "Starts a search for the given query.")
- public void search(@RpcParameter(name = "query") String query) {
+ public void search(@RpcParameter(name = "query") String query) throws Exception {
Intent intent = new Intent(Intent.ACTION_SEARCH);
intent.putExtra(SearchManager.QUERY, query);
mAndroidFacade.startActivity(intent);
diff --git a/src/main/java/org/qpython/qsl4a/qsl4a/facade/FloatViewFacade.java b/src/main/java/org/qpython/qsl4a/qsl4a/facade/FloatViewFacade.java
index 936a1b6632dda19b015cbe8288a3400e4767309b..925606fef099380f9ebb26877e39a9a490b807db 100644
--- a/src/main/java/org/qpython/qsl4a/qsl4a/facade/FloatViewFacade.java
+++ b/src/main/java/org/qpython/qsl4a/qsl4a/facade/FloatViewFacade.java
@@ -28,12 +28,22 @@ public class FloatViewFacade extends RpcReceiver {
private final String protectActivity = "org.qpython.qpy.main.auxActivity.ProtectActivity";
private final Context context;
+ private final String[] argName = new String[] {
+ "x","y","width","height","textSize", //Integer型(可以设为上次)
+ "index", //Integer型(索引,不可设为上次)
+ "text","html", //字符型(二选一)
+ "backColor","textColor", //字符型(二选一)
+ "clickRemove", //布尔型
+ "flag", //Integer型(索引,不可设为上次)
+ "script","arg" //字符型(无前则无后)
+ };
+
//按钮数组
public static final ArrayList