7

I'm working with Mark Murphy's excellent Commonsware books - but it's a lot to digest. I built the 'FakePlayer' app (pretends to be an mp3 player). It contains a service. As a learning experience I tried to write a trivial app (has only a button) whose click handler does:

Intent i = new Intent();
i.setAction("com.example.cwfakeplayer.MyPlayerService");
Context context = getApplicationContext();
context.startService(i);

It worked fine - the service start ok. I noticed Eclipse complaining about no permission on the service, so I updated the service's manifest by adding 2 lines, android:permissions and android:exported:

    <service 
        android:name="MyPlayerService"
        android:permission="com.example.fakeplayer.permission.MY_PLAYER_PERMISSION"
        android:exported="true"
       <intent-filter>
            <action android:name="com.example.fakeplayer.MyPlayerService"></action>
       </intent-filter>
      </service>

I reloaded the player app onto the device (I'm using a Galaxy S2) using 'debug' under eclipse. It seemed to work; the starter app caused a permission exception, which I expected.

I then added to the starter app's manifest (to give it the permission):

<manifest
  ...
  <uses-sdk ....
  ....
  <uses-permission android:name="com.example.fakeplayer.permission.MY_PLAYER_PERMISSION" />

I reloaded the starter app onto the device (using debug under Eclipse). Still get the permission error in the starter app.

I removed both apps from the device and reinstalled (using debug...), service app first, then starter. Still get perm error.

I am working my way through the 'how to use a remote service' section of Mr. Murphy's Advanced Android book, so I realized this is not the best way perhaps to work across apps.

I did a 'adb shell dumpsys package', located the starter app, and found it had 'permissionsFixed=false' and no 'grantedPermissions' section. I take this to mean the manifest change in the starter app did not manage to get the perm added to the app. But I have no idea why. As a learning experience, it's generated only confusion so far....

Any clues greatly appreciated! Thanks!

Art Swri
  • 2,799
  • 3
  • 25
  • 36

2 Answers2

4

I updated the service's manifest by adding 2 lines, android:permissions and android:exported

Technically, android:exported="true" is superfluous, as having the <intent-filter> automatically makes the <service> be exported.

I removed both apps from the device and reinstalled (using debug...), service app first, then starter. Still get perm error.

You do not show where you ever declare the custom permission with the <permission> element. In practice, if you control both apps, put the same <permission> element in both manifests, so the order of installation of your two apps no longer matters.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • It also helps to include the in the first place. Thanks for the answer and for the excellent books and example code. I did not see any example code in the Android book that uses so I overlooked it in mine. (I _did_ read the chapter - but I am very 'code focused'). – Art Swri Mar 18 '13 at 17:06
  • @ArtSwri: Well, the book you apparently are reading ("Advanced Android") was retired a year ago, with its contents folded into [my main book](http://commonsware.com). That book definitely covers the `` element for custom permissions, as I use them in a plugin example: https://github.com/commonsguy/cw-omnibus/tree/master/RemoteViews That being said, thanks for the kind words! – CommonsWare Mar 18 '13 at 17:12
  • Wow I'm further behind than I thought - my subscription ran out. Leaving now to renew... – Art Swri Mar 18 '13 at 17:17
  • @CommonsWare To the second half of your answer - isn't that what he did with the android:permission=... inside the tag? – David Doria Oct 01 '13 at 12:32
  • @DavidDoria: The `android:permission` attribute does not declare a custom permission. `` does. `android:permission` states that a component should be defended by a permission (custom or otherwise), but if that permission does not exist, it will not be used. – CommonsWare Oct 01 '13 at 12:34
  • 1
    after remove of "android:exported="true" error: As of Android 12, android:exported must be set; use true to make the activity available to other apps, and false otherwise – NickUnuchek Jan 20 '22 at 09:18
-2

Try replace this in your manifest

<service android:name="com.example.fakeplayer.MyPlayerService"></service>

instead of

<service 
    android:name="MyPlayerService"
    android:permission="com.example.fakeplayer.permission.MY_PLAYER_PERMISSION"
    android:exported="true"
   <intent-filter>
        <action android:name="com.example.fakeplayer.MyPlayerService"></action>
   </intent-filter>
  </service>

If this doesn't work, kindly post out your error.

IssacZH.
  • 1,457
  • 3
  • 24
  • 54
  • It's my understanding that removing the will cause exported to default to false, which means the service is not visible outside the app that contains it. So what I expected happened: the startService() in the starter app does nothing - there is nothing visible to it that will handle the Intent. (There is nothing in the log besides the Log.d I have in the button-clicked method. I do appreciate your effort, but don't think it's actually a solution. – Art Swri Mar 18 '13 at 03:59