25

是否可以在不复制 shortcuts.xml 的情况下为多种风格定义静态快捷方式?我有两种口味:

  • 主要(包:com.test)
  • 免费(包:com.test.free)

快捷方式.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>

问题是intent中的包名不能引用字符串资源,必须在xml中硬编码。

为了还提供免费风味的快捷方式,我必须复制快捷方式.xml 并将targetPackage更改为 com.test.free,这是一个糟糕的解决方案。

4

4 回答 4

6

您可以在各自的构建变体文件夹中拥有多个shortcuts.xml不同的targetPackage(根据您的应用程序 ID)。例如 :

app/src/debug/res/xml/shortcuts.xml

app/src/staging/res/xml/shortcuts.xml

这个对我有用。

于 2018-07-25T12:16:28.837 回答
6

我创建了一个插件,可以在资源中使用 manifestPlaceholders,并且可以与 3.0.0 版的 android gradle 插件一起使用

https://github.com/timfreiheit/ResourcePlaceholdersPlugin

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="${applicationId}"/>
</shortcut>
于 2017-10-29T12:25:28.910 回答
3

重要提示:由于资源处理方式的变化,此解决方案仅适用于 3.0 之前的 android gradle 插件版本。

所以现在就解决这个问题,因为.debug我们的应用程序 id 上的后缀用于调试构建。这是我们的解决方法(注意这是我们代码库中未经测试的改编):

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 {
  ...
}
于 2017-06-30T06:57:25.870 回答
2

在对此进行调查时,我遇到了这个库,它似乎可以解决问题:

https://github.com/Zellius/android-shortcut-gradle-plugin

缺点:你不能在你的应用程序shortcuts.xmlres文件夹中拥有你的,因为插件获取文件,修改它以自动添加targetPackage,然后在构建期间将其放入,如果你已经定义了一个,它会导致重复资源错误。

除了这个缺点,似乎工作得很好!

于 2017-10-24T21:11:07.297 回答