I have written a service as part of an application. I try to call this service from a second application using the following code:
Intent intent = new Intent () ;
intent.setClassName("com.test" ,"com.test.DownloadService") ;
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(handler);
intent.putExtra("MESSENGER", messenger);
intent.setData(Uri.parse("http://www.vogella.com/index.html"));
intent.putExtra("urlpath", "http://www.vogella.com/index.html");
this.startService(intent);
It gives the following exception
07-10 09:27:28.819: ERROR/AndroidRuntime(4226): FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.inject/com.inject.MyActivity}: java.lang.SecurityException: Not allowed to start service Intent { dat=http://www.vogella.com/index.html cmp=com.test/.DownloadService (has extras) } without permission not exported from uid 10109
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1971)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1996)
at android.app.ActivityThread.access$700(ActivityThread.java:126)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1156)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4458)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.SecurityException: Not allowed to start service Intent { dat=http://www.vogella.com/index.html cmp=com.test/.DownloadService (has extras) } without permission not exported from uid 10109
at android.app.ContextImpl.startService(ContextImpl.java:1122)
at android.content.ContextWrapper.startService(ContextWrapper.java:359)
at com.inject.MyActivity.onCreate(MyActivity.java:28)
at android.app.Activity.performCreate(Activity.java:4465)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1935)
... 11 more
Why this permission issue occurs?
The following code works perfect when I call the service from the same app:
Intent intent = new Intent(this, DownloadService.class);
// Create a new Messenger for the communication back
Messenger messenger = new Messenger(handler);
intent.putExtra("MESSENGER", messenger);
intent.setData(Uri.parse("http://www.vogella.com/index.html"));
intent.putExtra("urlpath", "http://www.vogella.com/index.html");
startService(intent);
Can someone please let me know why I get this permission issue when I call the service from a different application, though I have given all the required permissions in App2's manifest.
EDIT
Manifest of App2
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.inject"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="14"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
<activity android:name="MyActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Manifest of App1 which contains the service
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="14"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<service android:name="DownloadService" >
</service>
</application>
</manifest>
Workflow for using permissions Some permissions, known as install-time permissions, are automatically granted when your app is installed. Other permissions, known as runtime permissions, require your app to go a step further and request the permission at runtime.
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> This permission is granted automatically when an application is installed and the app doesn't need to prompt users to grant the permission. This is displayed with other permissions that the app may request in Play store.
The service isn't available to other applications because you haven't made it explicitly available. Your service needs to be defined like this:
<service android:name="DownloadService"
android:exported="true">
</service>
You don't need any extra permissions (unless you want to use them)
Have your read the documentation? It is quite clear with this issue:
Global access to a service can be enforced when it is declared in its manifest's tag. By doing so, other applications will need to declare a corresponding element in their own manifest to be able to start, stop, or bind to the service.
As of GINGERBREAD, when using Context.startService(Intent), you can also set Intent.FLAG_GRANT_READ_URI_PERMISSION and/or Intent.FLAG_GRANT_WRITE_URI_PERMISSION on the Intent. This will grant the Service temporary access to the specific URIs in the Intent. Access will remain until the Service has called stopSelf(int) for that start command or a later one, or until the Service has been completely stopped. This works for granting access to the other apps that have not requested the permission protecting the Service, or even when the Service is not exported at all.
In addition, a service can protect individual IPC calls into it with permissions, by calling the checkCallingPermission(String) method before executing the implementation of that call.
See the Security and Permissions document for more information on permissions and security in general.
Show us your AndroidManifest.xml
if you still have permission problems after reading the documentation. Also see the exported
and the permission
attribute of the service in your manifest.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With