0

Using Xamarin I want to produce an android apk, that contains a large number of assets. I don't want to have to add each one individually in the csproj, due to the large number and due to the changeability of the assets. (produced via a prior build step)

This needs to work for both in single apk mode and one apk per ABI mode.

Tom
  • 6,325
  • 4
  • 31
  • 55

1 Answers1

1

Assets location on disk

In Project directory create the following directories:

ExtraAssets\assets
ExtraAssets-armeabi-v7a-23.0.0\assets 
ExtraAssets-x86_64-23.0.0\assets  

(A platform less one and one for each required supported platform) out of:

armeabi, armeabi-v7a, arm64-v8a, x86, x86_64

Where 23.0.0 is the targeted Android API.

Place all required asset files into the assets directories.

Modify csproj

In the Droid csproj (eg. MyApp.Droid.csproj) add the following section:

(A Exec for each required supported platform, plus a platform less one)

<Target Name="DebugDeploy" BeforeTargets="_Sign">
  <Exec Command="&quot;$(JavaToolPath)\jar.exe&quot; -uMf &quot;$(MonoAndroidIntermediate)android\bin\$(_AndroidPackage).apk&quot; -C &quot;$(ProjectDir)\ExtraAssets-x86-64-$(AndroidSdkBuildToolsVersion)&quot; assets" Condition="Exists('$(OutDir)\$(_AndroidPackage).apk') and '$(Configuration)|$(Platform)' == 'Debug|AnyCPU'" />  
  </Target>
  <Target Name="BeforePublish" BeforeTargets="_Sign">  
    <Exec Command="&quot;$(JavaToolPath)\jar.exe&quot; -uMf  &quot;$(MonoAndroidIntermediate)android\bin\$(_AndroidPackage).apk&quot; -C &quot;$(ProjectDir)\ExtraAssets&quot; assets" Condition="Exists('$(OutDir)\$(_AndroidPackage).apk')" />
    <Exec Command="&quot;$(JavaToolPath)\jar.exe&quot; -uMf &quot;$(MonoAndroidIntermediate)android\bin\$(_AndroidPackage)-armeabi-v7a.apk&quot; -C &quot;$(ProjectDir)\ExtraAssets-armeabi-v7a-$(AndroidSdkBuildToolsVersion)&quot; assets" Condition="Exists('$(OutDir)\$(_AndroidPackage)-armeabi-v7a.apk')" />
    <Exec Command="&quot;$(JavaToolPath)\jar.exe&quot; -uMf &quot;$(MonoAndroidIntermediate)android\bin\$(_AndroidPackage)-x86_64.apk&quot; -C &quot;$(ProjectDir)\ExtraAssets-x86_64-$(AndroidSdkBuildToolsVersion)&quot; assets" Condition="Exists('$(OutDir)\$(_AndroidPackage)-x86_64.apk')" />     
  </Target>

The DebugDeploy Target helps when debugging with an emulator, where you just want to produce a single apk.

This should run after the Package creation of the apk, and insert all files from the ExtraAsserts\assets into the (platform less) apk, before the apk signing happens.

The platform specific ExtraAsserts get inserted into the platform specific apks.

Xamarin specific BuildVars descriptions:

_BuildTargetAbis - deploy target abi eg: "armeabi-v7a;x86_64"

_AndroidPackage - package name without platform and .apk ext

JavaToolPath - location of java tools - needed for jar.exe

AndroidSdkBuildToolsVersion - android API version. (eg: "23.0.0")

ApkFileIntermediate - Path tp the apk file in the obj dir - this is the one that gets signed (instead of the one in OutDir)

MonoAndroidIntermediate - the obj directory containing "android\bin\" where the file referenced by ApkFileIntermedate file is located.

Tom
  • 6,325
  • 4
  • 31
  • 55