Android XML Preferences can give you a headache when trying to connect your Activities, especially in multi-flavor builds. It was my first time digging into this as the solution currently used was to connect all Preferences via OnPreferenceClickListener in code. Well this is okay - but you might end up with lots of boilerplate code for connecting Preferences and many anonymous listeners which leads to highly confusing code.

So my weapon of choice was to connect the target Activities directly in XML so the Android system handles all these calls for me and my code stays clean. Remember XML Preferences which do typically look like this (or even more specifically when using one of the subclasses):

<Preference

android:key="MY_PREF_KEY"

android:title="My Preference title"

android:summary="Fancy Preference summary"

/>

You mostly have a key and a title followed by all the optional elements you need. First stumbling block was the setup of the Intent element:

<Preference android:title="My Preference title" >

<intent android:targetPackage="com.my.app"

android:targetClass="com.my.activities.ShowMeActivity"/>

</Preference>

Always keep in mind, that targetPackage refers to the package name of your app, see applicationId in your build.gradle file. targetClass is used to find your target Activity within your app so the full qualified class path is needed here.

Multi-Flavor Builds

Multi-Flavor builds add the next challenge: you need to adapt the package name as this is mostly different for each flavor. You could overcome this by having your preference.xml copied in each variant and adapt the applicationId but this would unnecessarily duplicate your code. Also having them linked via code would be an easy option but remember - we do not want this.

A more simple way is to add a custom field to our build.gradle which then get’s written into a file named generated.xml at compile time. Entries from there can be referenced the common way known from referencing strings from strings.xml. The result is short and easy:

productFlavors {

flavor1{

applicationId "com.my.flavor1"

resValue "string", "applicationId", applicationId

}

flavor2{

applicationId "com.my.flavor2"

resValue "string", "applicationId", applicationId

}

}

So we can then easily reference the applicationId in the preference.xml file and start the Activity:

<Preference android:title="My preference title" >

<intent android:targetPackage="@string/applicationId"

android:targetClass="com.my.activities.ShowMeActivity"/>

</Preference>

Well that’s already it. I hope I saved you from struggling and appreciate your feedback.