I need to access com.android.internal.telephony.gsm.GsmSmsDispatcher's sendRawPdu method.
I've done a little research and found that GSMPhone class contains GsmSmsDispatcher instance. I hoped to obtain GSMPhone instance from PhoneFactory but it seems to be uninitialized (it's static variables are null).
Android API version >= 8.
You can't access Android's internal classes using reflection. Each application in Android runs in its own process with its own instance of the Dalvik VM. Classes loaded in one process are not visible to another process. So when you try to access static variables from PhoneFactory, you end up loading the PhoneFactory class with unintialized variables.
Your best will be to do whatever you want to get done using the Android APIs. There are a few ways to get access to some private Android services, but it won't get you too far. The only relevant one for SMS is the isms service. You can look through the methods available in it in the ISms.aidl file present in the com.android.internal.telephony package.
Related
I started exploring BeanShell for SL4A because I read that it could access the entire Android API. This would facilitate experimenting with API features and programming ideas without the need for a computer or compilation.
However, much of the API is accessed through a Context, and I don't know how to obtain this. Although both SL4A and BeanShell are well-documented, the combination of the two seems to be very poorly documented.
For example, to access android.net.ConnectivityManager, the developer reference states that I need to call Context.getSystemService(Context.CONNECTIVITY_SERVICE) to get an instance. But without a context, I don't think I'm able to access the methods of the ConnectivityManager.
So how do I obtain the Context?
Dahrrr…
While researching and formulating the question, I found out that this is an unresolved issue:
Notes for Java interpreters
Beanshell and Rhino can both directly access the android api. However, many Android api calls required a context, which, due to the way they are run, these interpreters don't have. A solution is being sought... suggestions appreciated.
I don't know sl4a or beanshell but i know Rhino. So i suppose that you can create scriptable objects too. If this is correct you can do something like this (in java):
// first create a simple scope called -> scope
// inject context.
Object injectObject = Context.javaToJS(android_context, scope); // ('Context' of rhino library)
ScriptableObject.putProperty(scope, "android_context_name", injectObject);
// so then execute your script with the injected object
execute(javascript_context, host, scope, scriptId, source, settings);
When you finish injected the the context you can access him via: "android_context_name". (inside your script).
When you run your bean shell script, it will be thru an android app ?
There are such available
e.g : BeanShell Executor, that will allow you to run a script.
So I assume the context will be passed from the app to the script being executed.
Consider
PackageInfo info1 = pm.getPackageArchiveInfo(apkPath,PackageManager.GET_PERMISSIONS);
In this statement, by using GET_PERMISSIONS I can get the set of all permissions used in the application.
In the same way can i get the API calls?
Thank you. I am new to this android programming if it is a simple question please forgive
No, you cannot get the API calls by any easy method, and arguably not even by a hard method.
If you had access to the application's installed .apk (and at least on older Android versions you did), you could read through it for obvious invocations of platform functions. (This is a form of "Static Analysis")
However, Java (and hence Dalvik) supports a mechanism called "reflection" which allows looking up and calling functions by name - a name that could be constructed at runtime by circuitous means, or user or network input.
Much of the actual functionality used for calling functionality in the system process is also ultimately performed by name, making another place where functionality not present in the static file could be added at runtime.
Finally, the native underlayers of Android (and likely the DVM as well) permit a determined programmer to dynamically designate arbitrary "data" to be "code" and then execute it.
I'm trying to bind a service from an activity and get possibility to call method of it.
These are in different applications (apk) but uses the same sharedUserId and process.
Since they use the same process, Am I obliged to use AIDL or can I use classic IBinder like for Local Service (described on Android Developer sample) ?
I tried both. AIDL works fine and method for Local Service doesn't works, I have an ClassCastException :
E/AndroidRuntime(17511): java.lang.ClassCastException: com.example.app.MyService$LocalBinder cannot be cast to com.example.app.MyService$LocalBinder
Is it possible to use this method for calling service with two apps in a common "shared" process? Or Is that the use of this shared process still requires an IPC method like AIDL?
If I want to use classic IBinder, it's for keeping my application as simple as possible.
Hope you can help me and sorry for my bad english ;-)
I guess the problem is the following. Even if you use sharedUserId and your applications run in the same process you cannot call methods of your service locally, because your service and application are in different packages. Thus, you can use only AIDL that will create a proxy in your client application.
Your problem is that each app has its own APK containing its own CLASSES.DEX, and classes and interfaces are not shared between them. App1.apk/com.example.Class1 is considered a different type than App2.apk/com.example.Class1. Whether or not they're identical doesn't matter.
There's a few ways you can address this:
1) As you've noticed, you can use AIDL. This is the least efficient mechanism, and obviously limits you to only AIDL-compatible types.
2) You can use Java reflection API's. This is better than AIDL in terms of efficiency, but of course the syntax isn't that great.
3) You can attempt to use custom class loading to somehow finagle it so that both apps have access to the same type. For what you're trying to do, this is going to be more trouble than it's worth.
It annoys me when I need to pass the context reference around all over my code. So I am thinking to create a static method to return a reference to the application instance. I am not sure if it is safe to assume there is only one instance of the Application in one application. Apparently, the Application class in Android SDK doesn't provide such method to return the instance reference. So I suspect there must be a reason?
It's probably safe, assuming that your android app lives within a single os process (most do, but this isn't a guarantee on android), but I advise against it.
If you need access to the context/application outside of the places where it's already available (activities, services, broadcast receivers, applications, views, etc), you're probably letting details related to the android environment creep into code that shouldn't know so much about it.
The big exception is static utility methods (e.g. to display a canned dialog that you reuse in your app or similar), in which case passing your context is kind of a convention in the android world (for example, ProgressDialog.show takes a Context as its first argument).
While you can do this, my feeling is that it's probably a band-aid to work around the fact that you have too many components in your code that are unnecessarily tightly coupled to the android environment.
I am developing an Android app and I am using a library I wrote. This library has a class that contains some static fields. One of them is a API key. This key is used by other classes in my library to make calls on a remote service.
I initialize the API key on my main Activity once when it is created and the savedInstanceState is null.
My problem lies in other activities as they sometimes use the correct API key when making calls with my library and sometimes they do not. It seems as if the API key has not been set.
In particular there is one activity that i call from my preferences activity that always fails as the API key is not set.
Are not static fields maintained across Activities as they are on normal Java applications? I thought that for a specific jvm instance, all static fields are retained. Is the Android platform using new jvm instances for new Activities?
Please read:
http://developer.android.com/guide/topics/fundamentals.html#procthread
Your app is running in a process. The process may need to be killed while it is in the background. Your app must correctly save whatever state is appropriate as it goes in the background (via for ex Activity.onSaveInstanceState()) and/or reconstruct its state when later restarting in a new process.
Are you accessing the static field in a direct or indirect way?Are other activities mess with the Api key?If so you should synchronized before accessing it