@@ -39,6 +39,8 @@ public class UnityCompat {
39
39
private const string UNITY_ANDROID_EXTENSION_ASSEMBLY = "UnityEditor.Android.Extensions" ;
40
40
private const string UNITY_ANDROID_JAVA_TOOLS_CLASS = "UnityEditor.Android.AndroidJavaTools" ;
41
41
private const string UNITY_ANDROID_SDKTOOLS_CLASS = "UnityEditor.Android.AndroidSDKTools" ;
42
+ private const string UNITY_ANDROID_EXTERNAL_TOOLS_SETTINGS_CLASS =
43
+ "UnityEditor.Android.AndroidExternalToolsSettings" ;
42
44
private const string UNITY_ANDROID_POST_PROCESS_ANDROID_PLAYER_CLASS =
43
45
"UnityEditor.Android.PostProcessAndroidPlayer" ;
44
46
private const string WRITE_A_BUG =
@@ -151,6 +153,64 @@ private static bool SetAndroidSDKVersion(int sdkVersion, string propertyName) {
151
153
[ ObsoleteAttribute ( "InBatchMode is obsolete, use ExecutionEnvironment.InBatchMode instead" ) ]
152
154
public static bool InBatchMode { get { return ExecutionEnvironment . InBatchMode ; } }
153
155
156
+ private static Type AndroidExternalToolsClass {
157
+ get {
158
+ return Type . GetType ( UNITY_ANDROID_EXTERNAL_TOOLS_SETTINGS_CLASS + ", " +
159
+ UNITY_ANDROID_EXTENSION_ASSEMBLY ) ;
160
+ }
161
+ }
162
+
163
+ /// <summary>
164
+ /// Get a property of the UnityEditor.Android.AndroidExternalToolsSettings class which was
165
+ /// introduced in Unity 2019.
166
+ /// </summary>
167
+ /// <param name="propertyName">Name of the property to query.</param>
168
+ /// <returns>Value of the string property or null if the property isn't found or isn't a
169
+ /// string.</returns>
170
+ private static string GetAndroidExternalToolsSettingsProperty ( string propertyName ) {
171
+ string value = null ;
172
+ var androidExternalTools = AndroidExternalToolsClass ;
173
+ if ( androidExternalTools != null ) {
174
+ var property = androidExternalTools . GetProperty ( propertyName ) ;
175
+ if ( property != null ) {
176
+ value = property . GetValue ( null , null ) as string ;
177
+ }
178
+ }
179
+ return value ;
180
+ }
181
+
182
+ /// <summary>
183
+ /// Get the JDK path from UnityEditor.Android.AndroidExternalToolsSettings if it's
184
+ /// available.
185
+ /// </summary>
186
+ public static string AndroidExternalToolsSettingsJdkRootPath {
187
+ get { return GetAndroidExternalToolsSettingsProperty ( "jdkRootPath" ) ; }
188
+ }
189
+
190
+ /// <summary>
191
+ /// Get the Android NDK path from UnityEditor.Android.AndroidExternalToolsSettings if it's
192
+ /// available.
193
+ /// </summary>
194
+ public static string AndroidExternalToolsSettingsNdkRootPath {
195
+ get { return GetAndroidExternalToolsSettingsProperty ( "ndkRootPath" ) ; }
196
+ }
197
+
198
+ /// <summary>
199
+ /// Get the Android SDK path from UnityEditor.Android.AndroidExternalToolsSettings if it's
200
+ /// available.
201
+ /// </summary>
202
+ public static string AndroidExternalToolsSettingsSdkRootPath {
203
+ get { return GetAndroidExternalToolsSettingsProperty ( "sdkRootPath" ) ; }
204
+ }
205
+
206
+ /// <summary>
207
+ /// Get the Gradle path from UnityEditor.Android.AndroidExternalToolsSettings if it's
208
+ /// available.
209
+ /// </summary>
210
+ public static string AndroidExternalToolsSettingsGradlePath {
211
+ get { return GetAndroidExternalToolsSettingsProperty ( "gradlePath" ) ; }
212
+ }
213
+
154
214
private static Type AndroidJavaToolsClass {
155
215
get {
156
216
return Type . GetType (
@@ -248,54 +308,70 @@ private static int WarnOnAndroidSdkFallbackVersion() {
248
308
public static int FindNewestInstalledAndroidSDKVersion ( ) {
249
309
var androidSdkToolsClass = AndroidSDKToolsClass ;
250
310
if ( androidSdkToolsClass != null ) {
251
- var androidSdkToolsInstance = AndroidSDKToolsInstance ;
252
- if ( androidSdkToolsInstance == null ) return WarnOnAndroidSdkFallbackVersion ( ) ;
253
- // Unity 2019+ only has a method to list the installed targets, so we need to parse
254
- // the returned list to determine the newest Android SDK version.
255
- var listTargetPlatforms = androidSdkToolsClass . GetMethod (
256
- "ListTargetPlatforms" , BindingFlags . Instance | BindingFlags . NonPublic ) ;
257
- if ( listTargetPlatforms != null ) {
258
- var sdkVersionList = new List < int > ( ) ;
259
- const string PLATFORM_STRING_PREFIX = "android-" ;
260
- IEnumerable < string > platformStrings = null ;
261
- try {
262
- // Unity 2019+
263
- platformStrings = ( IEnumerable < string > ) listTargetPlatforms . Invoke (
264
- androidSdkToolsInstance , null ) ;
265
- } catch ( Exception ) {
266
- }
267
- if ( platformStrings != null ) {
311
+ // To fetch the Android SDK version Unity runs tools in the Android SDK but doesn't
312
+ // set the JAVA_HOME environment variable before launching them via these internal
313
+ // methods. Therefore, we override JAVA_HOME in the process with the directory specified
314
+ // in Unity's settings while querying the Android SDK and then restore the JAVA_HOME
315
+ // variable to it's default state when we're finished.
316
+ var previousJavaHome = Environment . GetEnvironmentVariable ( JavaUtilities . JAVA_HOME ) ;
317
+ var javaHome = JavaUtilities . JavaHome ;
318
+ if ( ! String . IsNullOrEmpty ( javaHome ) ) {
319
+ Environment . SetEnvironmentVariable ( JavaUtilities . JAVA_HOME , javaHome ,
320
+ EnvironmentVariableTarget . Process ) ;
321
+ }
322
+ try {
323
+ var androidSdkToolsInstance = AndroidSDKToolsInstance ;
324
+ if ( androidSdkToolsInstance == null ) return WarnOnAndroidSdkFallbackVersion ( ) ;
325
+ // Unity 2019+ only has a method to list the installed targets, so we need to parse
326
+ // the returned list to determine the newest Android SDK version.
327
+ var listTargetPlatforms = androidSdkToolsClass . GetMethod (
328
+ "ListTargetPlatforms" , BindingFlags . Instance | BindingFlags . NonPublic ) ;
329
+ if ( listTargetPlatforms != null ) {
330
+ var sdkVersionList = new List < int > ( ) ;
331
+ const string PLATFORM_STRING_PREFIX = "android-" ;
332
+ IEnumerable < string > platformStrings = null ;
268
333
try {
269
- // Unity 2018 +
334
+ // Unity 2019 +
270
335
platformStrings = ( IEnumerable < string > ) listTargetPlatforms . Invoke (
271
- androidSdkToolsInstance , new object [ ] { AndroidJavaToolsInstance } ) ;
336
+ androidSdkToolsInstance , null ) ;
272
337
} catch ( Exception ) {
273
338
}
274
- }
275
- if ( platformStrings != null ) {
276
- foreach ( var platformString in platformStrings ) {
277
- if ( platformString . StartsWith ( PLATFORM_STRING_PREFIX ) ) {
278
- int sdkVersion ;
279
- if ( Int32 . TryParse (
280
- platformString . Substring ( PLATFORM_STRING_PREFIX . Length ) ,
281
- out sdkVersion ) ) {
282
- sdkVersionList . Add ( sdkVersion ) ;
283
- }
339
+ if ( platformStrings != null ) {
340
+ try {
341
+ // Unity 2018+
342
+ platformStrings = ( IEnumerable < string > ) listTargetPlatforms . Invoke (
343
+ androidSdkToolsInstance , new object [ ] { AndroidJavaToolsInstance } ) ;
344
+ } catch ( Exception ) {
284
345
}
285
346
}
286
- sdkVersionList . Sort ( ) ;
287
- var numberOfSdks = sdkVersionList . Count ;
288
- if ( numberOfSdks > 0 ) {
289
- return sdkVersionList [ numberOfSdks - 1 ] ;
347
+ if ( platformStrings != null ) {
348
+ foreach ( var platformString in platformStrings ) {
349
+ if ( platformString . StartsWith ( PLATFORM_STRING_PREFIX ) ) {
350
+ int sdkVersion ;
351
+ if ( Int32 . TryParse (
352
+ platformString . Substring ( PLATFORM_STRING_PREFIX . Length ) ,
353
+ out sdkVersion ) ) {
354
+ sdkVersionList . Add ( sdkVersion ) ;
355
+ }
356
+ }
357
+ }
358
+ sdkVersionList . Sort ( ) ;
359
+ var numberOfSdks = sdkVersionList . Count ;
360
+ if ( numberOfSdks > 0 ) {
361
+ return sdkVersionList [ numberOfSdks - 1 ] ;
362
+ }
290
363
}
291
364
}
292
- }
293
- var getTopAndroidPlatformAvailable =
294
- androidSdkToolsClass . GetMethod ( "GetTopAndroidPlatformAvailable" ) ;
295
- if ( getTopAndroidPlatformAvailable != null ) {
296
- return ( int ) getTopAndroidPlatformAvailable . Invoke (
297
- androidSdkToolsInstance , BindingFlags . NonPublic , null ,
298
- new object [ ] { null } , null ) ;
365
+ var getTopAndroidPlatformAvailable =
366
+ androidSdkToolsClass . GetMethod ( "GetTopAndroidPlatformAvailable" ) ;
367
+ if ( getTopAndroidPlatformAvailable != null ) {
368
+ return ( int ) getTopAndroidPlatformAvailable . Invoke (
369
+ androidSdkToolsInstance , BindingFlags . NonPublic , null ,
370
+ new object [ ] { null } , null ) ;
371
+ }
372
+ } finally {
373
+ Environment . SetEnvironmentVariable ( JavaUtilities . JAVA_HOME , previousJavaHome ,
374
+ EnvironmentVariableTarget . Process ) ;
299
375
}
300
376
}
301
377
0 commit comments