Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActivityNotFoundException when different package's targetClass in PreferenceScreen

The application's default package is "example.app".

and the target activity's package is "example.app.abc".

Calling startActivity() for "example.app.abc.TheActivity" in java code just works,

but specifying it on preference.xml doesn't work:

<PreferenceScreen android:key="key"
    android:title="@string/title"
>
    <intent android:action="android.intent.action.MAIN"
        android:targetPackage="example.app.abc"
        android:targetClass="TheActivity"
/>
</PreferenceScreen>

I tried android:targetClass="example.app.abc.TheActivity" but it doesn't work too.

Is it impossible to start an activity of non-default package, in preference?

like image 683
shkim Avatar asked Dec 05 '10 17:12

shkim


2 Answers

I just ran into the same problem when trying to use a custom preference screen from a library project for the AccountManager account settings. No matter how I tried to tweak the targetPackage and targetClass attributes, it would throw an exception (except, since it's an account, it crashes the phone).

I think we'll just have to assume this is an Android limitation. It's clumsy, but all you really need to do is declare a wrapper class for the activity within your application's namespace:

public class MyPreferences extends ActualPreferences {
}

Declare it in your AndroidManifest.xml

<activity android:name=".MyPreferences"/>

Then you can specify the class in your intent

<intent android:targetPackage="com.my.package"
        android:targetClass="com.my.package.MyPreferences" />

By the way, the syntax is extremely fussy, at least for account preferences. All these variations fail:

<!-- fails --> <intent android:targetClass="com.my.package.MyPreferences" />
<!-- fails --> <intent android:targetClass="MyPreferences" 
                       android:targetPackage="com.my.package"/>
<!-- fails --> <intent android:targetClass=".MyPreferences"
                       android:targetPackage="com.my.package"/>
<!-- fails --> <intent android:targetClass="settings.MyPreferences"
                       android:targetPackage="com.my.package"/>
<!-- fails --> <intent android:targetClass=".settings.MyPreferences"
                       android:targetPackage="com.my.package"/>
<!-- fails --> <intent android:targetClass="com.my.other.package.MyPreferences"
                       android:targetPackage="com.my.package"/>

The critical factor is apparently that the android:targetPackage attribute matches the application package. If you want, you can put the activity in a sub-package. This works:

<intent android:targetPackage="com.my.package"
        android:targetClass="com.my.package.settings.MyPreferences" />
like image 75
ehartwell Avatar answered Nov 13 '22 07:11

ehartwell


as already said its not working with libraries. Do it programatically, something like this:

preference_my_pref.setOnPreferenceClickListener(new OnPreferenceClickListener() {
                public boolean onPreferenceClick(Preference preference) {
                    Intent intent = new Intent(MyActivity.this, ActivityToStart.class);
                    startActivity(intent);
                    return true;
                }
            });
like image 35
user1324936 Avatar answered Nov 13 '22 05:11

user1324936