sl4a icon indicating copy to clipboard operation
sl4a copied to clipboard

??? Direct access to Android API

Open kuri65536 opened this issue 9 years ago • 4 comments

from py4a: https://github.com/kuri65536/python-for-android/issues/87

Is it possible?

kuri65536 avatar Jun 17 '15 21:06 kuri65536

@Rpc(description = "Get Memory Statistics By Type")
public float getMemoryStat(@RpcParameter(name = "type") String type) throws InterruptedException {
        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
        ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
        activityManager.getMemoryInfo(mi);

        long availableMegs = mi.availMem / 1048576L;  // returns percentages

        long percentAvail = mi.availMem / mi.totalMem; // returns percentages

        if (type == "avail") {
            return mi.availMem;
        } else {
            return mi.totalMem;
        }
}

Untested, but something like this should work... Depends on how you want your returns.

michaelrinderle avatar Mar 07 '16 04:03 michaelrinderle

Thanks for your suggestion. This is work for the original question of this issue.

But I mean the title of this issue is more generally to call any API from SL4A, and I don't have any idea for it. I think it is not easy to realize "any API call in SL4A" and need to a lot work for us.

kuri65536 avatar Mar 08 '16 22:03 kuri65536

i get it now. i'll look into this. off the top of my head i am thinking custom class loading might be the answer. i am not too familiar with it but we can create a SL4A method that accepts the file path to the dex file (dalvik converts class files to dex), as well as any parameters, and returns the data. the only problem is not knowing what the method is going to return (int, string, etc) so it might be tricky creating the method without knowing this....

See this: http://developer.android.com/reference/dalvik/system/DexClassLoader.html

michaelrinderle avatar Mar 08 '16 23:03 michaelrinderle

this is rudimentary since it is only returning as strings right now and has virtually no error handling but I think this is probably the approach to take for this feature. in essence, you can write up a small java class to run any type of methods against the whole android api, compile to dex, store the jar/apk file on your phone and call its methods from this in sl4a.

you provide the file path, full class name, method you want, and any arguments... I am going to work on this in the upcoming weeks to tweak it out but hit me back if you have any other ideas on this...

// TODO (Michael) Add Class Loader To Run Custom Java Methods

  @Rpc(description = "Load Custom Class to access API.")
  public String classLoader(
          @RpcParameter(name = "path") String path,
          @RpcParameter(name = "classname") String classname, // full class name com.example.packagename.ClassToAdd
          @RpcParameter(name = "method") String method,
          @RpcParameter(name = "args") String args
  ) throws Exception{

    String dexFile = path;
    File f = new File(Environment.getExternalStorageDirectory().toString() + dexFile);
    final File optimizedDexOutputPath = getDir("outdex", 0);
    DexClassLoader classLoader = new DexClassLoader(f.getAbsolutePath(),
                                                    optimizedDexOutputPath.getAbsolutePath(),
                                                    null,
                                                    getClassLoader());


    try {
      Class<?> myClass = classLoader.loadClass(classname);
      Object obj = (Object)myClass.newInstance();
      Method m = myClass.getMethod(method, String.class);
      String returnMsg = m.invoke(obj, args).toString();
      return returnMsg;
    } catch (Exception e){
      return e.toString();
    }
  }

converting jar to dex: (dx is in android sdk)

./dx --dex --output = output.jar input.jar

michaelrinderle avatar Mar 09 '16 01:03 michaelrinderle