Search Unity

Does Unity support using aar package as Android plugin library?

Discussion in 'Android' started by wenzhi, Oct 8, 2014.

  1. wenzhi

    wenzhi

    Joined:
    Sep 19, 2013
    Posts:
    1
    I'm trying to build a Unity Android plugin and use a Android library, which is a aar instead of a jar. It seem Unity doesn't recognize the aar library at all when I test on my app.

    I can change the library back to jar, but I prefer not to. Does Unity support aar as a Android plugin library at all? What should I do to make it work?

    Thank you!~
     
  2. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    I don't think so. The new format for Android Archives (.aar) is integrated with the new Gradle build system, however, Unity does not use that when building the project for Android yet.

    You could raise this issue in http://www.feedback.unity3d.com
     
  3. Face_Mcgace

    Face_Mcgace

    Joined:
    Aug 29, 2013
    Posts:
    8
    You can compile the .aar file, extract it, and use the 'classes.jar' to access the java classes inside the project you have. ( I've used this method when I converted from Eclipse to Android Studio ). Everything seems to work fine.
     
    s3xandch0c0late likes this.
  4. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    The whole point of an .aar is to also include other assets alongside compiled code (e.g: resources).

    If you only extract the code from it, what's the major benefit of using this format ?
     
  5. Face_Mcgace

    Face_Mcgace

    Joined:
    Aug 29, 2013
    Posts:
    8
    No, you'll have to build your assets inside unity. First, the main benefit is using android functions in Unity. For me this means accessing the bluetooth, connecting it to our custom sensors, and receiving that information in Unity and modifying/using this data in C#. Second, you don't have to use eclipse -- which for me ( coming from VS2013 ) it is horrible and outdated especially compared with Intellij.

    Whats the major benefit of using the resources ( I'm asking this based off of curiosity -- maybe I could improve my workflow somehow )?
     
  6. Ogen

    Ogen

    Joined:
    Sep 2, 2014
    Posts:
    11
    Can you elaborate on how to do this exactly?
     
  7. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    open as zip file
     
  8. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    AAR plugin support has been added in 5.0b19. Feel free to try latest beta, your feedback is welcome.

    Just drop an .aar file into any folder of Unity project, it should be detected as Android-only plugin, and enjoy :)
     
  9. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Now if only the Android Studio was easier to link to the Unity class file without including it into the plugin ;-)

    Awesome!

    Any plans on making some tool to make manifest merges?
    My plugin does not alter anything Unity needs to run, it just sets some additional activities and such.
    It's easy to merge, but still some users find this step difficult.

    Use case:
    - Being able to include a manifest inside the aar as a default
    - Allowing the user to extract the file and make some changes to override built in file
    - Combine it with their other plugins.
    - Combine the outcome with the manifest Unity uses to build

    It should be easy enough there is even a tool for this by google:
    http://tools.android.com/tech-docs/new-build-system/user-guide/manifest-merger

    I'm sure the devs have more things to do then sink hours of work into adding this feature just to
    save asset store customers of android plugins two minutes of work (and still get headaches due to other plugins demanding that they override the UnityActivity), but perhaps as a side project someone would like to look into this.
     
  10. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    With 'provided' not working properly (it should link but not include, yet includes into the jar anyways).

    symlink the classes.jar into a libs folder in your project.
    Add this to your build.gradle file
    This worked for excluding the unity classes.jar while still allowing the code to compile.

    Lib size now down to 37 KB for AAR vs 28 KB for JAR
    I still need to filter out some of the junk in there, I guess making libraries is not really a main use case for Android Studio yet.
     
  11. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    I thought the docs mention that they DO merge any manifest for android libraries with the main manifest... doesn't it ?
     
  12. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    I have not been able to get it to work so far.

    I would expect you place a manifest with only the XML nodes needed without those entered by Unity.
    But the end result is that it does nothing to include or merge those nodes into the end result.
     
    Last edited: Jan 17, 2015
  13. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    We are using manifmerger to merge Unity main manifest with the Android library manifests (AAR come here too).

    If this doesn't work for you - please file a bug.
     
  14. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Tagging this into case 643592, manifests from inside the aar is not merged, it is also not merged when extracted.
    The only thing Unity seems to do is replace a few select properties.

    Tested this again today on Unity 5 RC 1
     
  15. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Found a cleaner solution
    Create a new Unity Module in your project, select Import .JAR, select the unity classes.jar, name the module UnityClasses and then in your main module add the following to your build.gradle:

    Code (JavaScript):
    1.  
    2. dependencies {
    3.     compile project(':UnityClasses')
    4. }
    This includes the classes as a compile time resource, without copying it into the output.
     
  16. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    Hold on, I'm looking at your bug report and cannot understand - do you have any problems with AndroidManifest.xml inside an AAR plugin not merged into Unity manifest? If so, please submit a bug report with a repro project, and what you expect to be in the manifest.

    If you are talking about an XML resource file - it is processed by AAPT and should be accessible in your application AFAIR. If it is not the case, please submit a bug.

    If you are talking about providing resources in Plugins/Android/res - then this is deprecated because it can cause resource conflicts, hence the warning. Please create an Android Library: http://developer.android.com/tools/projects/index.html#LibraryProjects
     
  17. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234

    Already replied to the case 643592, posting here so the community might learn / help as well.

    The case is either of the above, I have tried many methods.
    The only good result is when I supply the full manifest in the Plugins/Android folder

    Res file deprecation I could live with, though it is a shame to lose the ability for users to tweak settings in a xml file needed for certain Android methodologies (specifically adding paths to a file provider). Altering the aar file would not be asset update friendly.

    The manifest in the aar is not merged, it could be I misunderstand how they designed it, that is certainly possible.

    It also is not merged when the manifest is not complete in the plugins root, it is simply copied as is in that case.

    Here is the manifest, as I understand it we should only need to declare what the plugin needs, this is than merged with similar nodes at similar paths within the final manifest.

    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    3.     package="com.ElicitIce.ImagePicker"
    4.     android:versionCode="1"
    5.     android:versionName="1.0" >
    6.  
    7.     <uses-sdk
    8.         android:minSdkVersion="9"
    9.         android:targetSdkVersion="21" />
    10.  
    11.     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    12.  
    13.     <application>
    14.  
    15.         <activity
    16.             android:name="com.ElicitIce.Plugin.ImagePicker"
    17.             android:theme="@android:style/Theme.Translucent.NoTitleBar" >
    18.             <intent-filter>
    19.                 <action android:name="android.intent.action.SEND" />
    20.  
    21.                 <category android:name="android.intent.category.DEFAULT" />
    22.  
    23.                 <data android:mimeType="image/*" />
    24.             </intent-filter>
    25.         </activity>
    26.  
    27.         <provider
    28.             android:name=".FileProvider"
    29.             android:authorities="com.ElicitIce.ImagePickerExample.fileprovider"
    30.             android:exported="false"
    31.             android:grantUriPermissions="true" >
    32.             <meta-data
    33.                 android:name="android.support.FILE_PROVIDER_PATHS"
    34.                 android:resource="@xml/sharepaths" />
    35.         </provider>
    36.     </application>
    37. </manifest>
     
  18. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    This sounds correct.
    If you paste the aar manifest along with the resulting manifest - that can help shed some light on your issues.

    Again, the manifest merging is carried out by Android utils, this is not something reinvented in Unity. We can potentially miss a file when building the command line, so I'm trying to understand whether it's the case.
     
  19. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    that was the manifest from the aar ( I did remove some additional nodes to abbreviate te example)

    Unity uses it's default manifest, which can be overruled with a custom manifest.
    But it seems like there can only be one such manifest.

    The manifest from a library aar does not seem to be used at all by unity (so it would need to be manually extracted to work).

    The only correct workaround is the old way, manually creating the full manifest (unity will make some changes based on android platform settings).
    In the case of my plugin this would not be necessary if I got manifest merging to work.

    Either I misunderstood Google's Android development documentations on manifest merging, or Unity is not handling this use case correctly (probably a command line issue or unpack/repack issue).
     
  20. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Digging a little further into the staging area

    there is an StagingArea\aar folder, where the plugin gets copied
    it shows that this aar is then extracted into the StagingArea\android-libraries\

    StagingArea\android-libraries\ImagePicker
    does show the unpacked AndroidManifest.xml
    it also shows the classes.jar in a bin folder, the sharepaths.xml in res and r.txt as well as a project.properties
    and a bunch of mandatory empty folders (yay for android google standards)

    StagingArea\ contains two manifest xmls

    AndroidManifest.xml
    AndroidManifest-main.xml
    One of these is surely to be the one that Unity then passes to the APK packager.
    But neither seem to get merged into the Package_unaligned.apk
    opening up the compresses manifest.xml shows that all strings still in plaintext with a lot of garble. The blob is too small to contain the complete XML from the plugin and it contains no mention of the aar plugin manifest defined nodes (nor any of it's strings).


    Running
    aapt l -a name.apk
    on the final APK, shows that the manifest is identical to AndroidManifest.xml (and contains no nodes merged from the aar manifest)
     
    Last edited: Feb 19, 2015
  21. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @Freezy , we have a bug reported for the manifest merging issue, it has a fix already and will soon land into a build. Thanks for the heads up!
     
    Freezy likes this.
  22. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Awesome, I was starting to lose my sanity figuring out if I was doing something wrong.
    Eagerly awaiting developments :p
     
  23. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Could you confirm wether this fix is in the Unity 5f4 release?
    I just tested it and I still get a whole bunch of nothing or the identical manifest.

    from the 5f4 manual en/Manual/PluginsForAndroid.html:
    AndroidManifest.xml from these folders will get automatically merged with the main manifest file when the project is built.

    Nope, it uses it like the main manifest (but only if the manifest was extracted from the aar) and flips some minor changes, the unity main activity is not even injected.
     
  24. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    Sorry - this fix didn't make it into 5.0f4.
    Good news - it should be in 5.0p1 :)
     
    Freezy likes this.
  25. Chongzey

    Chongzey

    Joined:
    Jan 29, 2013
    Posts:
    2
    Hi, do you guys have some documents or tutorials for using the aar files as library ? I saw this new feature, but have no idea how to use it.

    with best regards.
     
  26. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Is there a keyword we could use to insert the package name into a manifest?
    This is needed for authority nodes, which google decided would not need automatic package prefix ability, but they will block installation if yo have an identical authority in a different package... oh google...

    Normally you would use name=".NameOfThing", and the manifest would prefix it with the package identifier, but for authorities this is not allowed.

    It would be wonderful if we could add a simple search for replace X with Y constants (Like the list of preprocessors we have for coding).

    Now we could use Android Studio (somehow) to build the Unity project, giving us access to a gradle file we could use to insert this small but important detail.
    But as a plugin publisher this is not the best way to make Android plugins easy to use.

    Currently the best solution I found is to supply the required manifest nodes in the plugin, with the optional ones in a separate manifest, this merges nicely.

    It still requires the user of the plugin to manually edit the separate manifest to change the provider authority.
     
  27. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Trying to merge incompatible /manifest/application/activity[@name=com.ElicitIce.Plugin.ImagePicker] element:
    <activity
    -- @android:label="@String/app_name"
    -- @android:name="com.ElicitIce.Plugin.ImagePicker">
    -- <intent-filter>
    <activity
    ++ @android:name="com.ElicitIce.Plugin.ImagePicker"
    ++ @android:theme="@android:style/Theme.Translucent.NoTitleBar"
    ++ @tools:node="remove">


    I am trying to create a small manifest in the plugin aar, with a larger one containing optional options that could be set.

    Is Unity manifest merging set to a forced strict mode? as none of the tools:attr modes seem to make a bit of difference.

    Also, is there a placeholder we can use that will be replaced with the application ID? Like the default gradle ${applicationID}, this would be awesome for authority attributes, which need to be unique or they will block installation.
     
  28. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    We are using manifmerger to merge manifests, no bicycle reinvented here ;)

    I can't really tell why your manifest merging fails. Could be one of properties that is considered incompatible, or even their order.
     
    DBarlok likes this.
  29. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    I'll try and do a manual merge with the manifmerger and see if that gives me the same result.
    When I supply two plugins merge seems to work fine, but with a main manifest there is always a incompatible merge between identical nodes with a simple theme attribute added. Overriding the theme is also not compatible, even when flagged at both ends.

    So the question becomes does the manifmerger tool used support the android merge tools?
    is it the one in the SDK folder or did it ship with Unity?

    Also when using a single main manifest XML resources are not picked up from plugins, which makes sense but I really need to add a configurable XML alongside the plugin, as well as a method of combining the bare minimum manifest with all the bells and whistles manifest.

    Android -> bin -> plugin.aar (contains bare minimum manifest, with default theme)
    Android -> AndroidManifest.xml (contains all the bells and whistles, no theme (should merge), or override theme (should replace)

    using a second aar is the best solution I have found so far, but users of my plugin would then have to open it up with a zip program, which is not that user friendly.
    I have also created an android studio project to build a wrapper with the plugin, but again, not that user friendly.
    For some reason or another I thought Unity could also pick up the android gradle and build the project, then pick up the output.

    I am trying to follow: https://developer.android.com/tools/building/manifest-merge.html
    Which should work right?
     
  30. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
    Then again, if the manifmerger would just support insertion of the "bundle identifier" then I would just add all the bells and whistles.

    Then advanced users could replace the manifest when needed and keep a backup copy in case the asset gets updated.
    Or they could try to get merging to work properly, removing the unneeded nodes.

    But... there is no "bundle identifier" token / replace / placeholder available is there?
    Such idiocy to demand a unique Content Provider authority but not support a way to actually make it unique in a user friendly way. (Sorry just really frustrated I spent the entire day trying to fix this simple use case)
     
  31. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
  32. Freezy

    Freezy

    Joined:
    Jul 15, 2012
    Posts:
    234
  33. pweeks

    pweeks

    Joined:
    Mar 29, 2011
    Posts:
    104
    i thought i posted a reply but i dont see it...I have a plugin that over rides UnityPlayerActivity, i had it working up till 5.2 with a jar and res file in the plugins/android folder...5.2 broke that so i figured switch to AAR...i'm also working with unity support but wanted to see if the community has anything to offer...i've tried everything i can think of, yet while i can build an apk, trying to run, my plugin activity is never found so insta-crash...whats the trick?
     
  34. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @pweeks something must be missing - can you please post your project and the errors you are getting?
     
  35. goat

    goat

    Joined:
    Aug 24, 2009
    Posts:
    5,182
    I saw this thread along the same lines of importing Android .aar / .pom to use in Unity and as I've never tried to write code to use a plugin before this thread looks like the place to ask:

    I know what I want to do: convert 3 java app source files that use the needed .aar / .pom and port them to C# and replace the Android UI calls with Unity UI calls.

    My problem I'm not sure what class declaration abilities in java are converted as in C# as in this java source code, which is a helper class for the Android aar library:

    Code (csharp):
    1.  
    2. package com.esri.android.geotrigger.geodes;
    3.  
    4. import android.app.Activity;
    5. import android.app.AlertDialog;
    6. import android.app.Dialog;
    7. import android.content.Context;
    8. import android.content.DialogInterface;
    9. import android.content.Intent;
    10. import android.location.LocationManager;
    11. import android.net.wifi.WifiManager;
    12. import android.os.Build;
    13. import android.provider.Settings;
    14. import android.util.Log;
    15. import android.widget.Toast;
    16.  
    17. import com.esri.android.geotrigger.GeotriggerService;
    18. import com.google.android.gms.common.ConnectionResult;
    19. import com.google.android.gms.common.GooglePlayServicesUtil;
    20.  
    21. /** * A class that packages some convenience methods for starting the GeotriggerService. */public final class GeotriggerHelper {
    22. private static final String TAG = "GeotriggerHelper";
    23. private static boolean sDeclinedPlayServicesInstall;
    24.  
    25. private GeotriggerHelper() {}
    26.  
    27. private enum AvailableProviders {GPS, NETWORK, BOTH, NEITHER}
    28.  
    29. /** * Start the GeotriggerService by first prompting the user to (1) install Google Play Services if not already installed, * (2) enable GPS and Network providers if not already enabled, and (3) enable background wifi scanning if not * already enabled. * * <p>A good place to call this would be from the{@link android.app.Activity#onStart} method of an {@link android.app.Activity} * that uses the Geotrigger SDK. * * @param activity The {@link android.app.Activity} that is currently displayed. * @param clientId Client ID from https://developers.arcgis.com/en/applications * @param senderId Project number from https://code.google.com/apis/console * @param tags A list of tag names to apply to the device as soon as possible. * @param profile The tracking profile (ie: FINE, ADAPTIVE, ROUGH, OFF) to start the service in. */public static void startGeotriggerService(final Activity activity, String clientId, String senderId, String[] tags,
    30. String profile) {
    31. startGeotriggerService(activity, Integer.MIN_VALUE, clientId, senderId, tags, profile);
    32. }
    33.  
    34. /** * Start the GeotriggerService by first prompting the user to (1) install Google Play Services if not already installed, * (2) enable GPS and Network providers if not already enabled, and (3) enable background wifi scanning if not * already enabled. This version of the method allows you to specify the "request code" that may be returned * in {@link Activity#onActivityResult} if overridden in the provided {@link Activity}. * * <p>A good place to call this would be from the{@link Activity#onStart} method of an {@link Activity} * that uses the Geotrigger SDK. * * @param activity The {@link Activity} that is currently displayed. * @param requestCode A request that may be returned in {@link Activity#onActivityResult} * if overridden in the provided {@link Activity} * @param clientId Client ID from https://developers.arcgis.com/en/applications * @param senderId Project number from https://code.google.com/apis/console * @param tags A list of tag names to apply to the device as soon as possible. * @param profile The tracking profile (ie: FINE, ADAPTIVE, ROUGH, OFF) to start the service in. */public static void startGeotriggerService(final Activity activity, int requestCode, String clientId,
    35. String senderId, String[] tags, String profile) {
    36. if (activity == null) {
    37. throw new IllegalArgumentException("Activity cannot be null.");
    38. }
    39.  
    40. int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(activity);
    41.  
    42. if (status != ConnectionResult.SUCCESS && !sDeclinedPlayServicesInstall) {
    43. // We could not detect Google Play Services, and the user hasn't indicated a desire to skip // installation of Google Play Services, so let's check if this error can be recovered from.if (GooglePlayServicesUtil.isUserRecoverableError(status)) {
    44. // This error can be fixed, and Google Play Services provides a dialog for doing so:Dialog playServicesDialog = GooglePlayServicesUtil.getErrorDialog(status, activity,
    45. requestCode, new DialogInterface.OnCancelListener() {
    46.  
    47. @Overridepublic void onCancel(DialogInterface dialog) {
    48. Toast.makeText(activity, activity.getString(R.string.play_services_dialog_cancel_toast),
    49. Toast.LENGTH_LONG).show();
    50.  
    51. // The user has decided not to install Google Play Services. // We should just start Geotriggers without Google Play Services.sDeclinedPlayServicesInstall = true;
    52. }
    53. });
    54.  
    55. if (playServicesDialog != null) {
    56. playServicesDialog.show();
    57. }
    58. } else {
    59. Log.d(TAG, "Google Play Services not available, and cannot be installed on this device.");
    60.  
    61. // Geotriggers can still work, using an older, less battery-efficient mode of operation.}
    62.  
    63. } else {
    64. Log.d(TAG, "Google Play Services is available (or user has declined to install it). " +
    65. "Checking on GPS and Network providers.");
    66.  
    67. // Check for GPS and Network Provider, and prompt the user to enable them if not available.if (checkForRequiredProviders(activity) == AvailableProviders.BOTH) {
    68. // We have both providers enabled, great! // Our usages of the WifiManager below require the permission: // <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />WifiManager wifiManager = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE);
    69.  
    70. // Let's also verify that we get make the most efficient use of the Network provider by checking // that devices running SDK 18 (Jelly Bean MR2) and above have enabled background scanning, // and that those below SDK 18 have wifi itself enabled.if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
    71. if (!wifiManager.isScanAlwaysAvailable()) {
    72. showSettingsDialog(activity, WifiManager.ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE,
    73. activity.getString(R.string.enable_background_scanning));
    74. return;
    75. }
    76. } else {
    77. // When running on SDK 17 and below, wifi background scanning is not available. // Enabling Wifi will drastically improve performance, particularly for Adaptive mode, // which uses Geofencing.if (!wifiManager.isWifiEnabled()) {
    78. showSettingsDialog(activity, Settings.ACTION_WIFI_SETTINGS,
    79. activity.getString(R.string.enable_wifi));
    80. return;
    81. }
    82. }
    83.  
    84. // For devices running an older version of Android, or those that have background scanning // enabled, we have enough information to start the GeotriggerService and be reasonably sure // that it will perform well.GeotriggerService.init(activity, clientId, senderId, tags, profile);
    85. } else {
    86. Log.d(TAG, "Delaying the start of Geotriggers, as we are awaiting the availability of " +
    87. "at least one provider.");
    88. }
    89. }
    90. }
    91.  
    92. /** * This method checks to see if we can access GPS and Wi-Fi data, prompting the user to enable them if not. * * @param context* @return*/private static AvailableProviders checkForRequiredProviders(final Context context) {
    93. if (context == null) {
    94. throw new IllegalArgumentException("Context cannot be null.");
    95. }
    96.  
    97. AvailableProviders returnVal;
    98. LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
    99.  
    100. boolean gotGps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    101. boolean gotNetwork = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    102.  
    103. String msg;
    104. if (!gotGps && !gotNetwork) {
    105. msg = context.getString(R.string.both_gps_and_network_disabled);
    106. returnVal = AvailableProviders.NEITHER;
    107. } else if (!gotGps) {
    108. msg = context.getString(R.string.gps_provider_disabled);
    109. returnVal = AvailableProviders.NETWORK;
    110. } else if (!gotNetwork) {
    111. msg = context.getString(R.string.network_provider_disabled);
    112. returnVal = AvailableProviders.GPS;
    113. } else {
    114. Log.d(TAG, "Both GPS and Network providers are available.");
    115. return AvailableProviders.BOTH;
    116. }
    117.  
    118. showSettingsDialog(context, android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS, msg);
    119.  
    120. return returnVal;
    121. }
    122.  
    123. /** * A helper method for putting up a settings dialog. * * @param context* @param action* @param msg*/private static void showSettingsDialog(final Context context, final String action, String msg) {
    124. AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
    125. dialogBuilder.setMessage(msg);
    126. dialogBuilder.setPositiveButton(context.getString(R.string.settings), new DialogInterface.OnClickListener() {
    127. @Overridepublic void onClick(DialogInterface dialog, int which) {
    128. context.startActivity(new Intent(action));
    129. }
    130. });
    131.  
    132. dialogBuilder.setNegativeButton(context.getString(R.string.cancel), new DialogInterface.OnClickListener() {
    133. @Overridepublic void onClick(DialogInterface dialog, int which) {}
    134. });
    135.  
    136. dialogBuilder.show();
    137. }
    138. }
    139.  
     
    Last edited: Oct 19, 2015
  36. goat

    goat

    Joined:
    Aug 24, 2009
    Posts:
    5,182
    OK, so I used a Java to C# converter and it converts the code how I'd guess. Now I just need to separate and replace the Android UI calls with Unity UI calls.

    I've included the .aar and .pom Android archives needed in my Unity project. And I use them by a typical C# using include statement:

    Code (csharp):
    1.  
    2. using Activity = android.app.Activity;
    3. using AlertDialog = android.app.AlertDialog;
    4. using Dialog = android.app.Dialog;
    5. using Context = android.content.Context;
    6. using DialogInterface = android.content.DialogInterface;
    7. using Intent = android.content.Intent;
    8. using LocationManager = android.location.LocationManager;
    9. using WifiManager = android.net.wifi.WifiManager;
    10. using Build = android.os.Build;
    11. using Settings = android.provider.Settings;
    12. using Log = android.util.Log;
    13. using Toast = android.widget.Toast;
    14.  
    15. using ConnectionResult = com.google.android.gms.common.ConnectionResult;
    16. using GooglePlayServicesUtil = com.google.android.gms.common.GooglePlayServicesUtil;
    17.  
    Looks like I'm set then but I'll be back if I have trouble with changing the Android UI to Unity UI.
     
  37. JKasten

    JKasten

    Joined:
    Apr 11, 2013
    Posts:
    23
    @Yury Habets
    Is it possible to include a gradle project in Unity 5.0+ instead of ANT projects? I would like to able to set `manifestPlaceholders` to make the setup process more automatic for users of my plugin. Specifically reading the `applicationId` (AKA the Android bundle id).
    Code (JavaScript):
    1. manifestPlaceholders = [manifestApplicationId:"${applicationId}"]
    Also is it possible to use Google dependencies like Google Play service libraries without having to release AAR files with my plugin? Example:
    Code (JavaScript):
    1. compile "com.google.android.gms:play-services-gcm:+"
    Lastly is there any Unity documentation on the new AAR and gradle support? Or is your post here on the forums the best source for information on this?

    Thanks.
     
  38. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @JKasten:
    We don't support gradle building yet.
    So unfortunately if your plugin depends on Play Services - you will have to include it, or provide the way for your user to add it on his own (and control the version).

    Documentation... I have the "update docs" card in our Trello board, hopefully will soon get to that. In the meanwhile feel free to ask here :)
     
  39. Biro456

    Biro456

    Joined:
    Dec 22, 2012
    Posts:
    8
    I'm using Unity 5.1.2f1 and am having the same problem described here.
    As it seems, the AAR extractor assumes there will always be a classes.jar, which is not the case with the play-services aar.
     
  40. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @Biro456: Please file a bug report, we'll fix that.
     
  41. wtowns

    wtowns

    Joined:
    Feb 11, 2014
    Posts:
    4
    @Yury Habets: Did @Biro456 create a bug report for that? I'd like to follow the progress on it.

    Loosely related: it seems that Unity 5.3.1 doesn't find Android Libraries that *aren't* zipped into .aar files. How exactly does Unity determine if a folder is considered an Android Library?
     
  42. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @wtowns: not that I am aware of.

    In order for the folder to be detected as an Android library, it has to be:
    - a subfolder of Assets/Plugins/Android. Yes sad but true, but we don't detect libraries outside that dir, or it will cause severe asset importing performance regressions.
    - have AndroidManifest.xml and project.properties which must contain android.library=true
     
  43. wtowns

    wtowns

    Joined:
    Feb 11, 2014
    Posts:
    4
    Ah, bummer, but that makes sense.

    My dream layout of a project would be structured such that each plugin could be put in "Assets/<company name>/<plugin name>" (company name optional), with their own "Editor" and "Plugins" folders. Then I'd be able to manage each plugin as a submodule/subtree in git, and I don't need to reverse-engineer the changes made to a shared AndroidManifest.xml when I remove that plugin later on. It's a lofty dream, for sure.

    It is interesting that Unity will find ".aar" files anywhere in the project. I've been using that to my advantage in that I'll have the project structure I'm looking for and just combine the contents of that plugin's "Plugins/Android" folder into an .aar file. Hence my interest in the classes.jar requirement: for plugins that really only need to add elements to AndroidManifest.xml, I still need to create a stub class and compile it. In the end, I'll end up with a project looking something like this:

    Code (csharp):
    1.  
    2. Assets
    3. ├── CoolPlugin
    4. │   ├── Plugins
    5. │   │   ├── Android
    6. │   │   │   └── CoolPlugin.aar
    7. │   │   └── iOS
    8. │   │       ├── CoolPlugin.h
    9. │   │       └── CoolPlugin.mm
    10. │   └── Scripts
    11. │       └── CoolPlugin.cs
    12. └── OurCompany
    13.     └── OurSharedLibrary
    14.         ├── Editor
    15.         │   └── SomeEditorExtensions.cs
    16.         └── Scripts
    17.             └── SomeMultiProjectCode.cs
    18.  
    Regardless, thanks for clarifying how Unity finds Android plugins. It looks like the .aar solutions is the way to go, or symlinking folders from outside the Assets directory.
     
    leni8ec, DBarlok and Yury-Habets like this.
  44. SteveCastro

    SteveCastro

    Joined:
    Nov 10, 2014
    Posts:
    1
    It seems Unity 5.2.3 does not recognize AAR files in /Assets/Plugins/Android/(folder_name)/, probably because it's assuming it's a library folder. I had to move them up one level for it to work.
     
  45. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @SteveCastro : this is correct, everything inside Assets/Plugins/Android/{folder_name} is not passed to the Asset importer as we consider it being a part of the library plugin.
     
  46. rganeyev

    rganeyev

    Joined:
    Dec 16, 2015
    Posts:
    6
    Does unity 4.7 support aar?
     
  47. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
  48. Lszt

    Lszt

    Joined:
    Sep 28, 2015
    Posts:
    38
    I have some request or question :

    1.
    I'm not totally convinced of this solution :/

    I know a lot of people just integrated their Android plugin @ the "Plugins/Android" root.
    But some people (and I'm one of them like to have a clean hierarchy !)

    So to handle this, I need to move files in "Plugins/Android" in a Preprocess method during my build to reset their plugin importer value to a valid state then bring them back in their current folder.
    Could you give to the developer at least a choice to choose if they want a scan in Plugins/Android/{folder_name} ?

    I understand your vision concerning libraries folder but trust me it's quite clean to have this hierarchy "Plugins/Android/{plugins_folder} than to put all plugins in the Android root :/

    2.
    Will you support Gradle build for Android Studio Project ? By this I mean do you have an ETA ? It could be much simplier for Android developer that need to create an Android project to remove unused references from their project :) or maybe just allow your builder to do this clean when we create an "apk" file ? :)

    3.
    What is currently your project format ? IntelliJ or Eclipse ? I think it's the second one but just to be sure I prefer to ask.
     
    Last edited: Mar 8, 2016
    leni8ec likes this.
  49. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    @Lszt :

    1. Unfortunately we can't give the option to allow scanning Plugins/Android/{plugins_folder}. What is your use case? Are you using jar, aar or library projects? Just wondering how you would want to sort them.

    2. Unfortunately no ETA on Gradle build, though it's in our backlog.

    3. This is called Android project: http://developer.android.com/training/basics/firstapp/creating-project.html . The "Create a Project with Command Line Tools" link is broken - it used to be "android create project -p . ........."
     
  50. Lszt

    Lszt

    Joined:
    Sep 28, 2015
    Posts:
    38
    Hi !
    In our building pipe we have jar / aar files.
    But they are in Plugins/Android/{plugins_folder}/bin or libs but when we moved them in this particular hierarchy all jar / aar files are messed up. No informations displayed in the inspector.

    To avoid this, our solution is to create a little C# method in Preprocess build to move all libs folder to Plugins/Android/libs patch them then move them to their true position (which was the one said before) and the file is after this non-broken.

    Concerning the Android Project forrmat, I asked this because when we exported it in Android Studio he want to convert it to Gradle format whereas I thought it was already created in a good way with Unity (but maybe not)