2010-12-05 48 views
15

Le package par défaut de l'application est "example.app".ActivityNotFoundException lorsque targetClass du package différent dans PreferenceScreen

et le package de l'activité cible est "example.app.abc".

Appel startActivity() pour "example.app.abc.TheActivity" dans le code java fonctionne,

mais en précisant sur preference.xml ne fonctionne pas:

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

J'ai essayé android : targetClass = "example.app.abc.TheActivity" mais cela ne fonctionne pas aussi.

Est-il impossible de démarrer une activité de package non-par défaut, de préférence?

+0

Je ne sais pas s'il est possible de démarrer un paquet non par défaut. Whydont vous essayez à nouveau avec un "." devant la classe cible. comme android: targetClass = ". TheActivity" – Varun

+1

Où voyez-vous la fonctionnalité "" imbriquée documentée? – CommonsWare

+0

Il ne doit pas être documenté, car il s'agit d'une API interne non prise en charge. L'application peut être rejetée en l'utilisant. – Pentium10

Répondre

30

Je viens de rencontrer le même problème lorsque j'essaie d'utiliser un custom preference screen à partir d'un projet de bibliothèque pour les paramètres du compte AccountManager. Peu importe comment j'ai essayé de modifier les attributs targetPackage et targetClass, une exception serait levée (sauf, comme c'est un compte, cela bloque le téléphone).

Je pense que nous devrons supposer que c'est une limitation Android. Il est maladroit, mais tout ce que vous avez vraiment besoin de faire est de déclarer une classe wrapper pour l'activité au sein de l'espace de noms de votre application:

public class MyPreferences extends ActualPreferences { 
} 

Déclarez dans votre AndroidManifest.xml

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

Ensuite, vous pouvez spécifier la classe dans votre intention

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

par ailleurs, la syntaxe est extrêmement difficile, au moins pour les préférences de compte. Toutes ces variations échouent:

<!-- 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"/> 

Le facteur critique est apparemment que l'attribut android:targetPackage correspond au package d'application. Si vous le souhaitez, vous pouvez placer l'activité dans un sous-package. Cela fonctionne:

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

+1 pour cette excellente explication –

+0

cela devrait être marqué comme une réponse – sidon

+0

Ceci est génial, merci pour l'excellente réponse! –

1

comme déjà dit son ne fonctionne pas avec les bibliothèques. Faites-le par programme, quelque chose comme ceci:

preference_my_pref.setOnPreferenceClickListener(new OnPreferenceClickListener() { 
       public boolean onPreferenceClick(Preference preference) { 
        Intent intent = new Intent(MyActivity.this, ActivityToStart.class); 
        startActivity(intent); 
        return true; 
       } 
      }); 
+0

vous pourriez vouloir copier les extras de l'intention originale comme' newIntent.putExtras (oldIntent) ' – NikkyD