Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Documentation/guides/building-apps/build-targets.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,20 @@ MSBuild /t:Install ProjectName.csproj /p:AdbTarget=-e
Calls the [`GetAndroidDependencies`](#getandroiddependencies) target, then installs
the Android SDK packages specified in the `@(AndroidDependency)` item group.

```dotnetcli
dotnet build -t:InstallAndroidDependencies -f net8.0-android "-p:AndroidSdkDirectory=<path to sdk>" "-p:JavaSdkDirectory=<path to java sdk>"
```

The `-f net8.0-android` is required as this target is a .NET Android specific target. If you omit this argument
you will get the following error:

```
error MSB4057: The target "InstallAndroidDependencies" does not exist in the project.
```

The `AndroidSdkDirectory` and `JavaSdkDirectory` properties are required as we need to know where to install the required components. These directories can be empty or existing. Sdk components
will be installed on top on an existing sdk installation.

The [`$(AndroidManifestType)`](~/android/deploy-test/building-apps/build-properties.md#androidmanifesttype)
MSBuild property controls which
[Visual Studio SDK Manager repository](~/android/get-started/installation/android-sdk.md?tabs=windows#repository-selection)
Expand Down
27 changes: 24 additions & 3 deletions Documentation/guides/messages/xa5207.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,35 @@ ms.date: 06/26/2019

## Example messages

```
```dotnetcli
XA5207: Could not find android.jar for API Level 28. This means the Android SDK platform for API Level 28 is not installed. Either install it in the Android SDK Manager (Tools > Android > Android SDK Manager...), or change your Xamarin.Android project to target an API version that is installed.
```

## Issue

In order to build a project, the Android SDK Platform matching the target API level must be installed.
In order to build a project, the Android SDK Platform matching the target API level must be installed.

## Solution

Use the Android SDK Manager to install the Android SDK Platform for the desired API level.
Use the Android SDK Manager (Tools &gt; Android &gt; Android SDK Manager...) to install the Android SDK Platform for the desired API level. Alternatively you can install the missing API level by running the following command from a terminal or command prompt:

```dotnetcli
dotnet build -t:InstallAndroidDependencies -f net8.0-android "-p:AndroidSdkDirectory=<path to sdk directory>"
```

Part of the new .net android system is when upgrading projects you will automatically be
upgraded to the latest API level. For example net7.0-android allowed you to target API 33,
but net8.0-android will automatically target API 34. If you want to keep your current
target API level you will need to add the 'uses-sdk' `android:targetSdkVersion` to your `AndroidManifest.xml` file.

```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.companyname.myapp">
<uses-sdk android:targetSdkVersion="33">
<application android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" />
</manifest>
```

You might then need to run the `InstallAndroidDependencies` target as mentioned above to ensure that the required API level is installed.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 10 additions & 8 deletions src/Xamarin.Android.Build.Tasks/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -867,19 +867,21 @@ Remove the '{0}' reference from your project and add the '{1}' NuGet package ins
{0} - The missing tool name</comment>
</data>
<data name="XA5207" xml:space="preserve">
<value>Could not find android.jar for API level {0}. This means the Android SDK platform for API level {0} is not installed. Either install it in the Android SDK Manager ({2}), or change the Xamarin.Android project to target an API version that is installed. ({1} missing.)</value>
<value>Could not find android.jar for API level {0}. This means the Android SDK platform for API level {0} is not installed. {2} ({1} missing.) See https://aka.ms/xa5207 for more details.</value>
<comment>The following are literal names and should not be translated: android.jar
{0} - The API level name
{1} - The expected path of the android.jar file
{2} - The menu location in Visual Studio that can be used to launch the Android SDK Manager</comment>
</data>
<data name="XA5207_SDK_Manager_macOS" xml:space="preserve">
<value>Tools &gt; Open Android SDK Manager...</value>
<comment>This string is the location of a menu command in Visual Studio for Mac.</comment>
{2} - The instructions to install the missing component</comment>
</data>
<data name="XA5207_SDK_Manager_Windows" xml:space="preserve">
<value>Tools &gt; Android &gt; Android SDK Manager...</value>
<comment>This string is the location of a menu command in Visual Studio.</comment>
<value>Either install it in the Android SDK Manager (Tools &gt; Android &gt; Android SDK Manager...), or change the Xamarin.Android project to target an API version that is installed.</value>
<comment>This string is the instrucitons to install the component</comment>
</data>
<data name="XA5207_SDK_Manager_CLI" xml:space="preserve">
<value>You can install the missing API level by running `dotnet build -t:InstallAndroidDependencies -f {0} -p:AndroidSdkDirectory={1}`, or change the project to target an API version that is installed.</value>
<comment>This string is the instrucitons to install the component
{0} - The TargetFramework the app is targeting.
{1} - The current AndroidSdkDirectory path.</comment>
</data>
<data name="XA5211" xml:space="preserve">
<value>Embedded Wear app package name differs from handheld app package name ({0} != {1}).</value>
Expand Down
10 changes: 9 additions & 1 deletion src/Xamarin.Android.Build.Tasks/Tasks/GetJavaPlatformJar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@ public class GetJavaPlatformJar : AndroidTask

public bool DesignTimeBuild { get; set; }

public bool BuildingInsideVisualStudio { get; set; }

public string SupportedOSPlatformVersion { get; set; }

public string TargetFramework { get; set; }

public string AndroidSdkDirectory { get; set; }

[Output]
public string JavaPlatformJarPath { get; set; }

Expand Down Expand Up @@ -95,7 +101,9 @@ public override bool RunTask ()
}

platform = GetTargetSdkVersion (platform, target_sdk);
JavaPlatformJarPath = MonoAndroidHelper.TryGetAndroidJarPath (Log, platform, designTimeBuild: DesignTimeBuild);
JavaPlatformJarPath = MonoAndroidHelper.TryGetAndroidJarPath (Log, platform,
designTimeBuild: DesignTimeBuild, buildingInsideVisualStudio: BuildingInsideVisualStudio,
targetFramework: TargetFramework, androidSdkDirectory: AndroidSdkDirectory);
TargetSdkVersion = MonoAndroidHelper.SupportedVersions.GetApiLevelFromId (platform).ToString ();
if (JavaPlatformJarPath == null)
return !Log.HasLoggedErrors;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -778,7 +778,7 @@ public void BuildInDesignTimeMode ([Values(false, true)] bool useManagedParser)
}

[Test]
public void IfAndroidJarDoesNotExistThrowXA5207 ()
public void IfAndroidJarDoesNotExistThrowXA5207 ([Values(true, false)] bool buildingInsideVisualStudio)
{
var path = Path.Combine ("temp", TestName);
var AndroidSdkDirectory = CreateFauxAndroidSdkDirectory (Path.Combine (path, "android-sdk"), "24.0.1", new ApiInfo [] { new ApiInfo { Id = "30" } });
Expand All @@ -788,6 +788,7 @@ public void IfAndroidJarDoesNotExistThrowXA5207 ()

using (var builder = CreateApkBuilder (Path.Combine (path, proj.ProjectName), false, false)) {
builder.ThrowOnBuildFailure = false;
builder.BuildingInsideVisualStudio = buildingInsideVisualStudio;
Assert.IsTrue (builder.DesignTimeBuild (proj), "DesignTime build should succeed.");
Assert.IsFalse (builder.LastBuildOutput.ContainsText ("error XA5207:"), "XA5207 should not have been raised.");
builder.Target = "AndroidPrepareForBuild";
Expand All @@ -797,6 +798,10 @@ public void IfAndroidJarDoesNotExistThrowXA5207 ()
}), "Build should have failed");
Assert.IsTrue (builder.LastBuildOutput.ContainsText ("error XA5207:"), "XA5207 should have been raised.");
Assert.IsTrue (builder.LastBuildOutput.ContainsText ($"Could not find android.jar for API level {proj.TargetSdkVersion}"), "XA5207 should have had a good error message.");
if (buildingInsideVisualStudio)
Assert.IsTrue (builder.LastBuildOutput.ContainsText ($"Either install it in the Android SDK Manager"), "XA5207 should have an error message for Visual Studio.");
else
Assert.IsTrue (builder.LastBuildOutput.ContainsText ($"You can install the missing API level by running"), "XA5207 should have an error message for the command line.");
}
Directory.Delete (AndroidSdkDirectory, recursive: true);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -482,14 +482,14 @@ public static IEnumerable<string> Executables (string executable)
yield return executable;
}

public static string TryGetAndroidJarPath (TaskLoggingHelper log, string platform, bool designTimeBuild = false)
public static string TryGetAndroidJarPath (TaskLoggingHelper log, string platform, bool designTimeBuild = false, bool buildingInsideVisualStudio = false, string targetFramework = "", string androidSdkDirectory = "")
{
var platformPath = MonoAndroidHelper.AndroidSdk.TryGetPlatformDirectoryFromApiLevel (platform, MonoAndroidHelper.SupportedVersions);
if (platformPath == null) {
if (!designTimeBuild) {
var expectedPath = MonoAndroidHelper.AndroidSdk.GetPlatformDirectoryFromId (platform);
var sdkManagerMenuPath = OS.IsWindows ? Properties.Resources.XA5207_SDK_Manager_Windows : Properties.Resources.XA5207_SDK_Manager_macOS;
log.LogCodedError ("XA5207", Properties.Resources.XA5207, platform, Path.Combine (expectedPath, "android.jar"), sdkManagerMenuPath);
var sdkManagerMenuPath = buildingInsideVisualStudio ? Properties.Resources.XA5207_SDK_Manager_Windows : Properties.Resources.XA5207_SDK_Manager_CLI;
log.LogCodedError ("XA5207", Properties.Resources.XA5207, platform, Path.Combine (expectedPath, "android.jar"), string.Format (sdkManagerMenuPath, targetFramework, androidSdkDirectory));
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,12 @@ projects.
<Target Name="_GetJavaPlatformJar">
<GetJavaPlatformJar
AndroidSdkPlatform="$(_AndroidApiLevel)"
AndroidSdkDirectory="$(AndroidSdkDirectory)"
AndroidManifest="$(_AndroidManifestAbs)"
DesignTimeBuild="$(DesignTimeBuild)"
BuildingInsideVisualStudio="$(BuildingInsideVisualStudio)"
SupportedOSPlatformVersion="$(SupportedOSPlatformVersion)"
TargetFramework="$(TargetFramework)"
>
<Output TaskParameter="JavaPlatformJarPath" PropertyName="JavaPlatformJarPath" />
<Output TaskParameter="TargetSdkVersion" PropertyName="_AndroidTargetSdkVersion" />
Expand Down