I'm attempting to use Google's Activity Recognition Service. Several days ago everything worked like a charm, i.e. I could connect use the service to obtain activity information. But today I found that I couldn't receive any anymore. After looking at the log I found this error:
05-15 21:19:27.196: W/ActivityManager(765): Permission Denial: Accessing service
ComponentInfo{edu.umich.si.inteco.captureprobe/edu.umich.si.inteco.captureprobe.
contextmanager.ActivityRecognitionService} from pid=-1, uid=10220 that is not exported
from uid 10223
I rebooted the phone and then it worked again. However, after I reinstall the application, the same problem appeared again. Could anyone point out what the "real" problem would be? Is it something related to "pid=-1"? I do have the permission in the Manifest file
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION"/>
I looked for answers on Google, but most of the issues are that they didn't place permission in the manifest file. This seems to me just a different issue...Could anyone help me? Thanks!
UPDATE:
The issue can always be solved by rebooting the phone. However, it always reappears when I uninstall the app and reinstall it through Eclipse. A consistent yet weird pattern (at least to me). I'm wondering whether the phone remember the app and stop it to access Google Play service after I uninstall it (or for some reason Google Play service just doesn't allow my app to access it). Any ideas?
I figured out the solution. The reason is due to the combination of two things:
Reinstallation generates a new different uid of the same application (note, by reinstallation I meant uninstall the app from the phone and then use Eclipse to reinstall).
By default, in the service tag, the value of "exported" is false, as described here
Whether or not components of other applications can invoke the service or interact with it — "true" if they can, and "false" if not. When the value is "false", only components of the same application or applications with the same user ID can start the service or bind to it.
The default value depends on whether the service contains intent filters. The absence of any filters means that it can be invoked only by specifying its exact class name. This implies that the service is intended only for application-internal use (since others would not know the class name). So in this case, the default value is "false". On the other hand, the presence of at least one filter implies that the service is intended for external use, so the default value is "true".
So I solved my problem simply by setting the flag to "true." (the sample code of Google Activity Recognition use the value "false" instead of "true.")
<service
android:name="edu.umich.si.inteco.captureprobe.contextmanager.ActivityRecognitionService"
android:enabled="true"
android:exported="true"
>
</service>
The interesting thing is, the same code works on Android 4.3 or below. I tested my code on four different phones with different Android version, and the uninstallation/reinstallation problem only occurred on the phone of Android 4.4. So that's why the I've been puzzled by the problem. Why didn't it happen before? Anyway, if you run into the same problem (i.e. the same application cannot use a service after you reinstall it), check the "exported" flag.
This is not specific to Activity Recognition; it's apparently a security improvement in 4.4, PendingIntents are registered in the system and a better solution appears to be to cancel the current pending intent (using PendingIntent.FLAG_CANCEL_CURRENT).
https://code.google.com/p/android/issues/detail?id=61850