0

In my app I have some objects with gps positions. At the moment the only thing I do with them is showing them on a map but I plan to implement other features which need to know the users location. I don't want to add the location permission to my app because some users may not want to use these features.

My idea was to have a separate apk (a kind of plugin) which only supplies the main app with location information so that only the plugin needs to request the location permission.

Is it possible to let the plugin share a system service (the LocationManager) directly without creating a custom service with an incompatible interface so that the main app can use the LocationManager of the plugin. This would make it possible to use existing classes like MyLocationOverlay or others. The main app could pass a ContextWrapper to these classes like this:

public static class LocationContext extends ContextWrapper {

    public LocationContext(Context base) {
        super(base);
    }

    @Override
    public Object getSystemService(String name) {
        if (name.equals(LOCATION_SERVICE)) {
            // Return the LocationManager service of the plugin here...
        }
        return super.getSystemService(name);
    }

}
Tom
  • 5,068
  • 5
  • 29
  • 41

3 Answers3

2

Not sure if I quite understand your question, but it is possible for one application to load classes from another app and thus avoid crossing process boundaries. The key is having the same android:process and android:sharedUserId attributes in your manifests for both aps. Then the apps will run in the same Linux process on the device. You can then use reflection APIs to programmatically load App A's classes from App B and vice versa. If App A is already on the Market, you would probably need to release a new version that adds the process and sharedUserId attributes, and then release App B with these same attributes.

michaelg
  • 2,692
  • 1
  • 17
  • 16
  • That sounds interesting. Assuming that both APKs have the same process and sharedUserId, can you give an example how the main app can get the LocationManager? – Tom Jun 15 '11 at 05:50
  • I tested it and it was easier than assumed: I just created an empty project, set the android:sharedUserId and the android:process to the package name of my main app and added a uses-permission tag to the plugins AndroidManifest.xml. Now the main app got all the permissions defined in the plugin and was able to get the users location. So this approach doesn't require a single line of code in the plugin. – Tom Jun 15 '11 at 10:54
  • Google does not recommend this: http://stackoverflow.com/questions/6354035/two-android-applications-with-same-user-id/6354073#6354073 Also you re-release Application A recommendations has been demonstrated to be flawed, as the new Application A will no longer have access to any files that it saved under its original user ID -- Android, at least through the 2.x series, did not automatically change the user ID of files when the user ID of the app changed. – CommonsWare Jun 15 '11 at 12:20
  • @CommonsWare That is a good point about releasing a new version with a different user ID and thus potentially losing access to legacy data saved with the old user ID. – michaelg Jun 15 '11 at 22:49
1

Yes this is possible, however I would strongly advice the Android OS engineers to disable this ability and also any other way of 2 friendly (same uuid, same signature) applications ) using each other functionality since this leads to serious security "holes" in the Permission system and serious issues in the Android security...

Just imagine 3 friendly applications. The first one has permission to connect to internet and nothing more, the second one can send SMS messages but nothing more and the third can access your location ....each app on its own is relatively harmless ...but image what can you do with them all together, since they are allowed to communicate.

Marek Szanyi
  • 2,348
  • 2
  • 22
  • 28
0

Is it possible to let the plugin share a system service (the LocationManager) directly without creating a custom service with an incompatible interface so that the main app can use the LocationManager of the plugin.

That will not be possible. LocationManager is not Parcelable, so you cannot pass it between processes.

This would make it possible to use existing classes like MyLocationOverlay or others.

Um, no. You did not write MyLocationOverlay. You cannot force it to use some faux LocationManager of your own design.

The main app could pass a ContextWrapper to these classes like this

ContextWrapper is not Parcelable, so you cannot pass it between processes.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • It's not absolutely correct that I can't force MyLocationOverlay to use another service. I didn't mean that the ContextWrapper is part of the plugin. It is created in the main app and is passed to any class that obtains a system service using Context.getSystemService(). The only job of the ContextWrapper then would be to obtain the LocationManager of the plugin. I already tried to subclass LocationManager to create a Proxy but LocationManager has a private constructor so it's not possible. – Tom Jun 15 '11 at 05:39
  • @Tom: I misunderstood your use of `ContextWrapper`, and that is certainly a curious approach to the problem. Still, you can't get `LocationManager` between processes, nor some of the parameters it uses (`GpsStatus`, `Looper`, etc.). Since you did not write `MyLocationOverlay`, you have no idea how it might change in future versions of Android, so your app could start crashing if you, say, create a subclass of `LocationManager` with a partial API implementation to try to support it across process boundaries. – CommonsWare Jun 15 '11 at 10:43
  • @Tom: Your APK plugin approach itself is sound, so long as you are doing something with respect to security to prevent arbitrary other apps from getting location data out of your plugin. However, I suspect that you're going to need to implement your own API (e.g., AIDL) and consume that same API. – CommonsWare Jun 15 '11 at 10:45
  • The solution of michaelg worked. Setting the same android:sharedUserId and android:process and signing the plugin apk with the same certificate as the apk of the main app enhances the permissions of the main app when the plugin is installed. – Tom Jun 15 '11 at 10:56
  • @Tom: Google does not recommend this: http://stackoverflow.com/questions/6354035/two-android-applications-with-same-user-id/6354073#6354073 – CommonsWare Jun 15 '11 at 12:20