Статические сочетания клавиш для Android на несколько вкусов?
Можно ли определить статические ярлыки для нескольких вариантов, не дублируя файл shortcuts.xml? У меня есть два вкуса:
- главная (пакет: com.test)
- бесплатно (пакет: com.test.free)
Shortcuts.xml выглядит так:
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:enabled="true"
android:icon="@drawable/ic_shortcut_add_photo"
android:shortcutId="new_photo"
android:shortcutLongLabel="@string/new_photo"
android:shortcutShortLabel="@string/new_photo">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.test.MainActivity"
android:targetPackage="com.test"/>
</shortcut>
Проблема в том, что имя пакета в намерении не может ссылаться на строковый ресурс и должно быть жестко закодировано в xml.
Чтобы также предоставить ярлыки для бесплатной версии, я должен скопировать shortcuts.xml и изменить targetPackage на com.test.free, что является плохим решением.
4 ответа
Вы можете иметь несколько shortcuts.xml
с разными targetPackage
(согласно идентификаторам вашего приложения) в соответствующей папке вариантов сборки. Например:
app/src/debug/res/xml/shortcuts.xml
app/src/staging/res/xml/shortcuts.xml
Меня устраивает.
Я создал плагин, который позволяет использовать manifestPlaceholder в ресурсах и может использоваться с версией 3.0.0 плагина Android Gradle
https://github.com/timfreiheit/ResourcePlaceholdersPlugin
SRC / Основной / RES /shortcuts.xml:
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:enabled="true"
android:icon="@drawable/ic_shortcut_add_photo"
android:shortcutId="new_photo"
android:shortcutLongLabel="@string/new_photo"
android:shortcutShortLabel="@string/new_photo">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.test.MainActivity"
android:targetPackage="${applicationId}"/>
</shortcut>
ВАЖНО: Это решение работает только для версий плагинов Android Gradle до 3.0 из-за изменений в способе обработки ресурсов.
Так что просто поразить эту проблему сейчас из-за .debug
суффикс идентификатора нашего приложения для отладочных сборок. Это наш обходной путь (обратите внимание на непроверенную адаптацию из нашей базы кода):
src/main/res/shortcuts.xml
:
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
<shortcut
android:enabled="true"
android:icon="@drawable/ic_shortcut_add_photo"
android:shortcutId="new_photo"
android:shortcutLongLabel="@string/new_photo"
android:shortcutShortLabel="@string/new_photo">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="com.test.MainActivity"
android:targetPackage="@string/application_id"/>
</shortcut>
<android module name>/build.gradle
:
apply plugin: 'com.android.application'
//region: Fix shortcuts.xml by manually replacing @string/application_id
final String APPLICATION_ID_STRING_RES_KEY = "application_id"
android.applicationVariants.all { variant ->
// Add the application id to the strings resources
// We do this so that in the future if google fixes the
// processing of the shortcuts.xml we can leave this
// and remove the `mergeResources.doLast` block below
resValue "string", APPLICATION_ID_STRING_RES_KEY, variant.applicationId
// Manually replace @string/application_id with `variant.applicationId`
variant.mergeResources.doLast {
println("variant = ${variant.applicationId}")
final File valuesFile = file("${buildDir}/intermediates/res/merged/${variant.dirName}/xml/shortcuts.xml")
final String content = valuesFile.getText('UTF-8')
final String updatedContent = content
.replace("@string/${APPLICATION_ID_STRING_RES_KEY}", variant.applicationId)
valuesFile.write(updatedContent, 'UTF-8')
}
}
//endregion
android {
...
}
Исследуя это, я наткнулся на эту библиотеку, которая, кажется, делает свое дело:
https://github.com/Zellius/android-shortcut-gradle-plugin
Недостаток: Вы не можете иметь свой shortcuts.xml
в пределах res
папка вашего приложения, так как плагин принимает файл, изменяет его, чтобы автоматически добавить targetPackage
, а затем сбрасывает его во время сборки, и, если оно уже определено, это вызовет ошибку дублирующихся ресурсов.
Помимо этого недостатка, похоже, отлично работает!