Category Archives: Android

Time to expand my horizons!

I’m going to check out http://www.cocos2d-x.org/ as a cross platform language for some utility work that needs to be deployed on both Android & iOS.  I’d prefer to use Unity, but the client I’m talking with doesn’t want to spring for a full Unity license (turns out you can’t just buy the monthly sub for 4 months, release a product and then cancel…).

Can’t wait – especially given how much I love Javascript </sarcasm>.

 

More Java issues

I’ve upgraded some of the projects I’ve been working on to Unity 5 and at the same time, I upgraded the Google Play Unity plugin to the latest version.

The GP plugin now uses AAR files (a android library file) instead of JARs (a standard java library file).  Unity 5 prefers AAR’s so that makes sense.  However, I ran into a headscratcher when my plugins (JAR files) started giving me the ‘java.lang.NoSuchMethodError’ errors again.

I verified I had all the libraries I needed in my Plugin folder so I couldn’t see what the problem was.  As I was messing with various debug additions I noticed the the standard GooglePlay folder was being deleted by something in Unity from my Plugin folder, and that this was the root of the problem.

A little more digging and I discovered that the new version of the GPlay plugin will remove that folder from Plugin/Android and then includes the ‘referenced’ parts of the library when you compile it for your android build.  As their plugin didn’t use the advertising or analytic’s part of the GPlay libraries, it was not including it in the final APK, and my plugins would then fail as I use both of those.

They have a mechanism to create a c# class that their code will pull in and let you add additional dependencies, which in turn enables those sections to be included in the APK.  I wasn’t able to figure that out, and in frustration (I’d already spent several hours tracking this down) I just modified a file in their plugin to include the dependencies I wanted.

I modified the static constructor by adding two lines to PlayServicesResolver.cs

        static PlayServicesResolver()
        {
            svcSupport = PlayServicesSupport.CreateInstance(
                PlayServicesResolver,
                EditorPrefs.GetString(AndroidSdkRoot),
                ProjectSettings);
            //CG  added the following two lines
            svcSupport.DependOn(com.google.android.gms, playservicesads, GooglePlayGames.PluginVersion.PlayServicesVersionConstraint);
            svcSupport.DependOn(com.google.android.gms, playservicesanalytics, GooglePlayGames.PluginVersion.PlayServicesVersionConstraint);

        }

These two lines keep the analytics and AdMob modules in the final APK and most importantly, let my plugins function as expected.  When I have time, I’ll figure out the correct way to do this.

AndroidJavaException: java.lang.NoSuchMethodError: no static method

I’ve been working on updating my Unity3D Android plugins, and decided to make a new project to test them in.  On and off for the past few days I’ve been trying to nail down the reason for the following error:

AndroidJavaException: java.lang.NoSuchMethodError: no static method “Lcom/purplebuttons/unity/PBAndroidUtils;.PBInitAndroidUtils(Lcom.unity3d.player.UnityPlayerNativeActivity;Z)V”

I get this error when the plugin is initialized, and it looks like Unity can’t find my static method.  I checked my parameters, verified that the method name was correct, checked that the JAR was in my plugins/android folder.  Everything checked out, but I was still getting the error.

I rolled the plugin back to a version from another project I knew worked as intended.  No difference, same error.  Lots of google searching and still nothing obvious.  The most common cause is either the parameters not matching, an incorrect java class path, or a misspelled method name.  I had none of those.

So I duplicated a working project that called the plugin without any errors, and started stripping it back.  Removed lots of scripts, objects, images & sounds. Finally I started pairing down the plugins/android directory, and that’s when it happened – I found the error.

Turns out I needed to include the ‘google-play-services_lib’ in my plugins/android folder.  The plugin jar used various bits & bobs from this lib and without it included in the APK, the plugin would fail to load when called, and return the error above, which didn’t really explain what was going on.

When I created the test project, I didn’t think to copy that forward, and hence my wasted time…

Dangers of copying files (Google Play Services Lib)

Had an issue today where after upgrading to the latest version of the Google Play Services the build process threw up a ton of  cryptic error messages like “Temp/StagingArea/android-libraries/google-play-services_lib/res/values/common_colors.xml:4: error: Resource entry common_signin_btn_dark_text_default is already defined.”

Turns out that while upgrading the Google Play Services folder, instead of replacing the old folder completely, the new folder was merged with the old one.  This left the old ‘colors.xml’ file which then conflicted with the new ‘common_colors.xml’ file.  Deleting the old folder and then copying in the new folder fixed it!

Obviously we figured it out, but it did manage to waste 30 minutes.  Hopefully, by writing this entry, I’ll remember the next time this happens, and maybe even help some other unfortunate soul from wasting their own 30 minutes.

 

Debugging Unity on Android

Android debugging can be a fairly intense process when using Unity. There are times your app will crash or not work correctly, and finding why can be a real pain.  A couple of things I do to make adb more usable.

Use ‘adb logcat -c’ to clear the logcat buffer.  I’ll do this after killing my app using ‘Advanced Task Killer’.

On the Mac, use CMD-K to clear the Terminal window in which you are running adb.

Use ‘adb logcat -s Unity’ to have logcat only display Unity Debug.Log messages – which you sprinkle throughout your code.  This keeps the logcat display from printing all the normal stuff you see when you run it in it’s default mode.