5

There are apps (such as https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher) that are free, but whose paid features can be enabled by buying another app (in this case, this one https://play.google.com/store/apps/details?id=com.teslacoilsw.launcher.prime)

How does this work?

My guess is that the free apps launches an explicit Intent and can detect if the app is present via a try/catch structure. The downside of this is that this could be easily circunvented by someone who creates an app with the same package name and specifies all possible Intent filters.

Is this how it works, or is it some other way?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
zundi
  • 2,361
  • 1
  • 28
  • 45

2 Answers2

2

There are various ways to do that. One way is to query a content provider which will be protected with a special permission.

I have released quite long ago on Github a library which helps doing this: Android Unlocker Library.

That's a good option if you are dealing with devices outside the Google ecosystem, however, from a developer experience, in-app purchases offer a much better user experience (and thus drive more sales) according to me.

Vincent Mimoun-Prat
  • 28,208
  • 16
  • 81
  • 124
0

The easiest way is to use startActivityForResult(...) from app A against an Activity of app B, that must be configured with an IntentFilter in order to be used from an outer app. Inside the B called activity you can also check who's calling with getCallingActivity(). You can find an example here.

Before starting the Activity, you can test that B is installed (using the PackageManager) or you can just start the activity and catch the Exception.

In the called Activity, you can check the signature of the calling package using the PackageManager.checkSignature(String,String) method. Pass the package name of A and B and if the signature matches, execute the logic.

Community
  • 1
  • 1
Mimmo Grottoli
  • 5,758
  • 2
  • 17
  • 27
  • Can this be circumvented if I create an app with the same package name and that answers the same intent? Not to publish, but just to install locally to enable the other app's features. – zundi Jan 22 '16 at 14:19
  • `PackageManager.checkSignature()` was what I was looking for. Will return `true` if both are signed by the same certificate, which means it's not easily circumvented, even if you have the other app's source code. Thanks – zundi Jan 25 '16 at 12:52