permission denied when I try to startService
Asked Answered
L

4

5

I am trying to access an InputMethodService from an Activity, and I am running into issues with the permissions. This is for a custom keyboard app.

What I am trying to achieve is to bind the text, which is created in the Activity back into the InputMethodService. The Activity is opened from the InputMethodService, then from the Activity, I try to start the Service(which may be the issue. Here is how I open the Activity from the InputMethodService:

    @Override public void onStartInputView(EditorInfo attribute, boolean restarting) {
    super.onStartInputView(attribute, restarting);

    Intent intent = new Intent(this, MyKeyboard.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    context.startActivity(intent);

}

Here is where I try to communicate with the InputMethodService from the Activity:

    @Override
public void onCreate(Bundle bundle){
    super.onCreate(bundle);
    setContentView(R.xml.keyboard);

    startService(new Intent(this, MyService.class));
}

Here is my Manifest File:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.my.package">
<application android:label="@string/ime_name">
    <service android:name="MyService"
            android:permission="android.permission.BIND_INPUT_METHOD">
        <intent-filter>
            <action android:name="android.view.InputMethod" />
        </intent-filter>
        <meta-data android:name="android.view.im" android:resource="@xml/method" />
    </service>
    <activity android:name=".MyKeyboard" android:theme="@style/Theme.Transparent">
    </activity>
</application>

and here is my stack trace:

11-18 15:58:34.732: E/AndroidRuntime(5458): Uncaught handler: thread main exiting due to uncaught exception
11-18 15:58:34.752: E/AndroidRuntime(5458): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mypackage/com.mypackage.MyActivity}: java.lang.SecurityException: Not allowed to start service Intent { cmp=com.mypackage/.MyService} without permission android.permission.BIND_INPUT_METHOD
11-18 15:58:34.752: E/AndroidRuntime(5458):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at android.app.ActivityThread.access$2200(ActivityThread.java:119)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at android.os.Looper.loop(Looper.java:123)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at android.app.ActivityThread.main(ActivityThread.java:4363)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at  java.lang.reflect.Method.invokeNative(Native Method)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at java.lang.reflect.Method.invoke(Method.java:521)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at dalvik.system.NativeStart.main(Native Method)
11-18 15:58:34.752: E/AndroidRuntime(5458): Caused by: java.lang.SecurityException: Not allowed to start service Intent { cmp=com.mypackage/.MyService } without permission android.permission.BIND_INPUT_METHOD
11-18 15:58:34.752: E/AndroidRuntime(5458):     at android.app.ApplicationContext.startService(ApplicationContext.java:765)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at android.content.ContextWrapper.startService(ContextWrapper.java:326)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at com.mypackage.MyActivity.onCreate(MyActivity.java:94)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
11-18 15:58:34.752: E/AndroidRuntime(5458):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
11-18 15:58:34.752: E/AndroidRuntime(5458):     ... 11 more

Any ideas?

Longueur answered 18/11, 2011 at 21:26 Comment(1)
The message stated that you need a permission android.permission.BIND_INPUT_METHOD. Why not to add it to your manifest file?Trichromatism
D
6

You can't do this. The platform requires that input method services require the BIND_INPUT_METHOD permission, and no third party applications can get that permission. This is an important security mechanism to ensure that only the platform itself can interact with an input method service, and no applications can spoof the platform while the user is interacting with the input method.

This is described in the "Security" section here: http://developer.android.com/reference/android/view/inputmethod/InputMethodManager.html

If this is some other app's input method service, that is the end of the story, the only way to interact with it is through the formal IME architecture of the platform.

If this is your own app's input method service, there are many tricks you can use to interact with it since you are running in the same process as it. The easiest is just to have it set a global variable of the service object when it is created, which you can access from elsewhere in your app.

If you really need to actually put the service in the started state... well, you can't do that, because that is not how input methods work. You will need to make a second service that you start and coordinate between the two services. Again, these should all be running in the same process, so you can take advantage of that to directly call between them to do whatever interactions you want.

Dacey answered 28/11, 2011 at 3:36 Comment(0)
T
5

You need to add the permission.

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.my.package">
<application android:label="@string/ime_name">
    <service android:name="MyService">
        <intent-filter>
            <action android:name="android.view.InputMethod" />
        </intent-filter>
        <meta-data android:name="android.view.im" android:resource="@xml/method" />
    </service>
    <activity android:name=".MyKeyboard" android:theme="@style/Theme.Transparent">
    </activity>

    <uses-permission android:name="android.permission.BIND_INPUT_METHOD"/>
</application>

You are setting it wrong.

Trebizond answered 18/11, 2011 at 21:45 Comment(1)
If I take the permission out of the service, then the keyboard won't show up as a possible input method. Also, I tried just adding the permission where you have it, and I get the same error.Longueur
M
1

Another suggestion: You need both the android:permission in the service and the uses-permission in the application - outside the service - at the same time

Mudcat answered 23/11, 2011 at 23:39 Comment(0)
M
-2

In manifest: First: remove the dot btw my and package Next - if First doesn't help: put a dot in front of service name:

Mudcat answered 23/11, 2011 at 15:57 Comment(2)
First: If you remove the dot before my, you will break the manifest file path. Second, the dot in front doesn't really do anything. If it is not present, it is assumed. This answer doesn't really help with anything.Trebizond
I'm not talking of 'dot before my' - I suggest replacing 'package="com.my.package"' with 'package="com.mypackage"', but according to the stacktrace it seems to be a typo made after the stacktrace was generated, because .Activity is replaced by com.mypackage.Activity - dot in front of a name is replace by the package string.Mudcat

© 2022 - 2024 — McMap. All rights reserved.