Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

OBSOLETE - Providing Android resources in Assets/Plugins/Android/res is deprecated...

Discussion in 'Android' started by almo, Apr 2, 2015.

  1. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    Yeah that's not the recommended way.

    You better include this icon as a resource to an Android plugin, and then reference it in Java code as usual.
     
  2. inakiktp

    inakiktp

    Joined:
    Nov 6, 2014
    Posts:
    35
    @Yury Habets Thanks for confirming it, will do it the recommended way. ;)
     
    Yury-Habets likes this.
  3. zleisure

    zleisure

    Joined:
    Oct 13, 2015
    Posts:
    4
    @Yury Habets
    Hello
    I have a problem has been confused,i write a android plugin for unity using Android Studio.Add a layout (eg.layout/activity_main.xml) in my android stuido project and use it as
    this.setContentView(R.layout.activity_main) in a activity.
    Then,i put .jar,res and AndroidManifest.xml into Unity(Assets/Plugins/Android...),it's good using Unity5.2.4f1,but not in Unity4.x,and Android Studio version is 1.5.1.In Unity4.x,it crash:java.lang.NoClassDefFoundError: Failed resolution of: Lcom/example/bfmj/R$layout;
    Please tell me why?
    Thanks!
     
  4. Yuriy-Ivanov

    Yuriy-Ivanov

    Joined:
    Jun 12, 2015
    Posts:
    495
    Hi Yury,

    I'm one of developers of UTNotifications asset. We're currently updating the Android native plugin to use .aar istead of .jar, and also changing folders structure. The asset allows clients specifying their own notification icons. Currently, we do a trick in order to make it possible on Android: the icons were put into Assets/Plugins/Android/UTNotifications/res/drawable when players specified icons in the editor, and Unity successfully merged them into the resulting .apk's res/drawable on build. Now we don't have a .jar plugin, and it is important to keep the .aar's source code outside of the Assets/Plugins/Android, so we can't use the same trick anymore. And using Assets/Plugins/Android/res/ is obsolete. Of course, we can do a very dirty hack for solving the issue: adding an empty Eclipse-like project under Assets/Plugins/Android/ and keep using the original approach. But it is really ugly and I'm afraid this method can once cease working in some of future updates of Unity.

    Is there a better way to put some custom Android resources into the resulting apk (without forcing the asset's users to build their icons into an Android native plugin themselfs - it is absolutely not an option)?

    P.S. I still don't understand why Unity decided to make using of Assets/Plugins/Android/res obsolete...

    Thanks in advance,
    Yuriy, Universal Tools team.
     
    Last edited: Apr 24, 2016
    JohnTube likes this.
  5. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    Hi @Yuriy Ivanov !

    res/ folder is obsolete because there's no good way to deal with resource conflicts. Android Libraries and AARs can handle that.

    On your questions:
    - if you want to switch to .aar, you may not want the source code to be added to Unity project at all :) Just one plugin.aar file, with source available on GitHub or anywhere else. It should work and be really handy for the users to have a single plugin file.
    - if that does not work for you - use Android Library (what you called "Eclipse-like project"). This is an official and supported way: http://developer.android.com/tools/projects/index.html#LibraryModules , just more files to handle for the user.

    Hope that helps.
    If you have more questions - don't hesitate to ask!
     
  6. Martin_k

    Martin_k

    Joined:
    Feb 19, 2015
    Posts:
    6
    Hey guys, I fall in real trouble with your android plugins and android library
    I have to make plugin for firebase cloud messaging.
    I tried to do this with Android Studio and .jar file, but I couldn't, because fcm need google-services.json with ids to be initialized, and as I know, jar files doesn't contains resources.
    using res folder is obsolete, but even when I place resources in res/values/vlaues.xml (ids), MainActivity starts, but firebase is not initialized for some reason.
    when i try to make android library, I have even more troubles. I have .aar file with my MainActivity (inherits UnityPlayerActivity) packed in jar, Android manifest like in Manual's example and my values.xml that are generated by android studio from google-services.json. After build I have two icons and when I run application it says that my methods in MainActivity doesn't exist (no such non-static method).
    I'am new in plugin-writing and android studio and java, I haven't seen good tutorials for making android library plugins for unity.
    Can you please tell me what I'am doing wrong ?
    Can you please give me link on some docs or tutorial ?

    Thanks in advance.

    Java
    Code (JavaScript):
    1.  
    2. public class MainActivity extends UnityPlayerActivity {
    3.  
    4.     private static final String TAG = "MainActivity";
    5.  
    6.     protected void onCreate(Bundle savedInstanceState) {
    7.  
    8.         // call UnityPlayerActivity.onCreate()
    9.         super.onCreate(savedInstanceState);
    10.  
    11.         if (!FirebaseApp.getApps(this).isEmpty()) {
    12.             FirebaseDatabase.getInstance().setPersistenceEnabled(true);
    13.         }
    14.     }
    15.  
    16.     public void SubscribeToTopic() {
    17.         FirebaseMessaging messaging = FirebaseMessaging.getInstance();
    18.         messaging.subscribeToTopic("news");
    19.         Log.d(TAG, "Subscribed to news topic");
    20.     }
    21.  
    22.     public void LogToken() {
    23.         FirebaseInstanceId instanceId = FirebaseInstanceId.getInstance();
    24.         Log.d(TAG, "InstanceID token: " + instanceId.getToken());
    25.     }
    26.  
    27.     public void shareText(String subject, String body) {
    28.         Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
    29.         sharingIntent.setType("text/plain");
    30.         sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
    31.         sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, body);
    32.         startActivity(Intent.createChooser(sharingIntent, "Share via"));
    33.     }
    34. }
    unity3D C#
    Code (CSharp):
    1. public class FirebaseTest : MonoBehaviour
    2. {
    3.     [SerializeField] Text logField;
    4.  
    5.     private void Awake()
    6.     {
    7.         Application.logMessageReceived += (condition, trace, type) => { logField.text += "\n" + condition; };
    8.     }
    9.  
    10.     string subject = "WORD-O-MAZE";
    11.     string body = "PLAY THIS AWESOME. GET IT ON THE PLAYSTORE";
    12.  
    13.     AndroidJavaClass unity;
    14.     AndroidJavaObject currentActivity;
    15.  
    16.     private void Start()
    17.     {
    18.         unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    19.         currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
    20.     }
    21.  
    22.     public void CallShareApp()
    23.     {
    24.         currentActivity.Call("shareText", subject, body);
    25.     }
    26.  
    27.     public void SendMessagePressed()
    28.     {
    29.         Debug.Log("SendMessagePressed");
    30.  
    31.         currentActivity.Call("SubscribeToTopic");
    32.     }
    33.  
    34.     public void InstanceIdPressed()
    35.     {
    36.         Debug.Log("InstanceIdPressed");
    37.  
    38.         currentActivity.Call("LogToken");
    39.     }
    40. }
    41.  
    manifest
    Code (CSharp):
    1. <?xml version="1.0" encoding="utf-8"?>
    2. <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="my.bundle.id">
    3.   <application android:icon="@drawable/app_icon" android:label="@string/app_name">
    4.     <activity android:name="my.bundle.id.MainActivity"
    5.              android:label="@string/app_name"
    6.              android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">
    7.         <intent-filter>
    8.             <action android:name="android.intent.action.MAIN" />
    9.             <category android:name="android.intent.category.LAUNCHER" />
    10.         </intent-filter>
    11.     </activity>
    12.   </application>
    13. </manifest>
    gradle
    Code (CSharp):
    1. apply plugin: 'com.android.library'
    2.  
    3. android {
    4.     compileSdkVersion 23
    5.     buildToolsVersion "23.0.2"
    6.  
    7.     defaultConfig {
    8.         minSdkVersion 15
    9.         targetSdkVersion 23
    10.         versionCode 1
    11.         versionName "1.0"
    12.     }
    13.     buildTypes {
    14.         release {
    15.             minifyEnabled false
    16.             proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    17.         }
    18.     }
    19. }
    20.  
    21. dependencies {
    22.     compile fileTree(include: ['*.jar'], dir: 'libs')
    23.     compile 'com.android.support:appcompat-v7:23.2.1'
    24.     compile 'com.google.firebase:firebase-messaging:9.0.0'
    25.     compile 'com.google.firebase:firebase-iid:9.0.0'
    26.     compile 'com.google.firebase:firebase-database:9.0.0'
    27.     compile 'com.google.gms:google-services:3.0.0'
    28.     compile files('libs/classes.jar')
    29. }
    30.  
    31. apply plugin: 'com.google.gms.google-services'
     
    Last edited: May 31, 2016
    matbou likes this.
  7. harryd31

    harryd31

    Joined:
    Oct 16, 2015
    Posts:
    3
    I have updated to 5.4 however we want to localize our app name. I tried having the res folder however that does not work. What is the proper way of doing it?
     
  8. Abrar199

    Abrar199

    Joined:
    Oct 23, 2016
    Posts:
    1
    Hi @yury Habets, I have not Android folder in the plugins folder, why is that?
    sorry for the question i'm beginner :p
     
  9. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
  10. liortal

    liortal

    Joined:
    Oct 17, 2012
    Posts:
    3,562
    What do you mean? why doesn't it work ?
     
  11. kemuri

    kemuri

    Joined:
    Mar 6, 2015
    Posts:
    3
    I struggle around the same problem. I have an android plugin and need to rely on "dynamic" resources which others will provide when they use it.
    I'm looking into public resources which are embedded to another .aar and alternatively into passing a path to application resources from unity to android.
    Will keep u updated with my progress
     
  12. kesbetik

    kesbetik

    Joined:
    Nov 3, 2018
    Posts:
    1
    Hey Inakiktp, Can you please tell me where to find this: "Project/Assets/Plugins/Android/assets/" ? I am looking for it and I cannot find it anywhere.
     
  13. Yuriy-Ivanov

    Yuriy-Ivanov

    Joined:
    Jun 12, 2015
    Posts:
    495
    Hi @Yury-Habets and all,

    Unity's own Unity Mobile Notifications Package uses Assets/Plugins/Android/res to store Android resources (https://docs.unity3d.com/Packages/com.unity.mobile.notifications@1.0/manual/index.html):
    Does it mean we can use the same approach ignoring that OBSOLETE message for similar needs?

    Please note, that "Eclipse-like project" way is not supported since Unity 2020 (we relied on it before).
     
    Last edited: Aug 16, 2020
  14. unity_LucasLTN

    unity_LucasLTN

    Unity Technologies

    Joined:
    Apr 16, 2019
    Posts:
    7
    Hi Yuriy-Ivanov,
    Can you please submit a bug :)
    This way it will be user facing when it is solved.

    Cheers
    Lucian
     
  15. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
    Hi @Yuriy-Ivanov !
    Please follow Lucian's advice and submit a bug report, please post the case # here.

    I agree we shouldn't recommend an obsolete way of dealing with things in the manual.
    What do you mean by "eclipse-like project"?
     
  16. Yuriy-Ivanov

    Yuriy-Ivanov

    Joined:
    Jun 12, 2015
    Posts:
    495
    It's from your reply some time ago:
    Sure, I can submit the bug about updating the docs. The problems is, what's the alternative? I.e., assets/plugin providers supply prebuilt .aar libraries, but our customers need to be able to add appropriate resources, such as icons and sounds, as some of Android native APIs require those to be in resources (in the API you specify them in the form of the resource id and nothing else). Previously we used an "eclipse-like" obsolete Android library structure (one which in the old times would be built as a .jar), which was recognised by Unity as a library, and put the resource files in its res folder. Since Unity 2020 they are not recognised by Unity as Android libraries, so we have to use the obsolete Assets/Plugins/Android/res folder again - it warns, but it works at least. Potentially we could dynamically build .aar resource-only libraries automatically and update them with users' icons and sounds, but it potentially causes much more problems: we have to use the currently specified Android SDK, which changes its version all the time (besides different customers use different versions of Android SDK with the same version of Unity), so building those .aar resource-only libraries would break all the time. No surprise Unity's own notifications package uses the same approach with Assets/Plugins/Android/res folder.

    My suggestion instead is to finally recognise Assets/Plugins/Android/res as a totally valid way to provide Android native resources and don't warn about it anymore.
     
    Last edited: Aug 20, 2020
  17. Yury-Habets

    Yury-Habets

    Unity Technologies

    Joined:
    Nov 18, 2013
    Posts:
    1,167
  18. Yuriy-Ivanov

    Yuriy-Ivanov

    Joined:
    Jun 12, 2015
    Posts:
    495
    You don't seem to get it. .aar libs work fine of course. The problem here is _generating_ .aar libs as a part of Unity build process. Most of the customers of our asset can't build .aar libraries themselves (this is why they buy our asset), so we provide a Unity editor interface for them to configure icons and sounds for their notifications. These icons and sounds must be built as Android .apk resources, which we previously achieved by generating a .jar-structured project in the form of folders and files in Assets/Plugins/Android, which was recognised by Unity up to 2019.4 and would produce Android resources in the apk artifact. Since Unity 2020, these folders are not recognised as an Android library anymore, but we still need a way to generate (dynamically!) these Android resources.
    Again, absolutely the same issue is solved by Unity's own Notification Package, and Unity itself uses Assets/Plugins/Android/res for that purpose.
     
    john_goren and cdr9042 like this.
  19. yuliyF

    yuliyF

    Joined:
    Nov 15, 2012
    Posts:
    194
    guys, where can I put my icons for notifications? Old path was: Assets\Plugins\res\ and here was a few icons
     
    andersemil likes this.
  20. kjyv

    kjyv

    Joined:
    Feb 20, 2018
    Posts:
    53
    Same issue here that we need to know how to read from res folder from java.

    We have our plugin in Plugins/<PluginName>/ which includes iOS and Android subfolders.
    Within the Android folder, there is java code, a bridge java class and some .cs files that use AndroidJavaObject to connect to the bridge class. We don't really want to use .aar files (it doesn't really make sense to put precompiled binaries with our own code into our SCM).
    Since Unity 2021, having an Assets/Plugins/res/ folder will fail the build, so the files need to go elsewhere. As we need them for notifications as well, they apparently need to be loaded from a res folder because a resource file index needs to be supplied. So.
    It seems the only option then is to use an .androidlib folder which will include all the files from the Android folder, minus the .cs files. If I do that, I'm not sure if Unity builds it correctly but it appears along with other Firebase androidlib paths in Library/Bee/Android/.../unityLibrary.
    However, when run on device, I just get a AndroidJavaException: java.lang.ClassNotFoundException: <PackageName>.Bridge. when trying to create a AndroidJavaObject with the bridge class.

    So how is the C# code supposed to access the classes in the androidlib folder?
     
  21. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,952
    Looks like you want to have your java source files directly in the project instead of having .aar files. Let us share our few cents on this topic.

    Unity recommends to use .aar files instead of having jars/android projects instead. There are some reasons for this recommendation
    1. Its easy to place this single file
    2. No restriction on where you place it as it will be detected by unity automatically.

    However, from pretty long time we are favouring non-aar approach for all of our plugins (we do plan to move to aar pretty soon though). This has following

    Pros:
    We can dynamically enable/disable specific jar files based on the features devs select
    Can generate AndroidManifest dynamically based on the features used (this way we can remove all the permissions which are not used anymore by the developer)
    Cons:
    Can't place the project clubbed within our root plugin project as it expects to be in Assets/Plugins/Android folder(as we support from 2018+)

    If your use-case is to have the java source, I guess thats something supported in recent versions of unity where you can place the complete android project with in unity. We didn't take this approach as our plugins support from 2018+.
    So, we are limited to using .androidlib folders and placing our jar files in libs folder within it.

    Here as a sample project which you can place in Assets/Plugins/Android folder and can place your jars in libs (or java source files in src if you are supporting only latest unity versions).

    We suggest to separate the native plugin files from .cs files and proceed with the .androidlib approach only if .aar is not working for you.
     
  22. kjyv

    kjyv

    Joined:
    Feb 20, 2018
    Posts:
    53
    Thanks for your answer. I don't know when using aar is ever a good idea except for 3rd party assets that don't want to give their source away. It seems always to be a bad idea to use precompiled code. It won't be rebuilt with newer compilers when updating Unity and is less maintainable. Unity's recommendation seems wrong to me. Anyway, .androidlib is exactly that, it allows the binaries to be rebuilt when building the project.

    Now, the problem was that our code when moved to an .androidlib did not get built in such a way that the bridge C# code could load the resulting class so we couldn't use it anymore.
    I've now resorted to leaving all the code as it was in an Android folder (which I think is fine, you can put it anywhere within Assets) and just put the res folder in an .androidlib which made the files available to java as resources again as before when they were in Plugins/Android/res. That's probably also a solution for all the use cases where you want to update images without updating an .aar all the time.
     
  23. Voxel-Busters

    Voxel-Busters

    Joined:
    Feb 25, 2015
    Posts:
    1,952
    To some extent true. But .aar is portable compared to .androidlib and can be placed in any of the folders. Considering our customers(our plugin users), we are directed towards using aar in future + some customisation to overcome its cons.