0

I've seen posts about this before, but none of the solutions seem to have worked for me.

I downloaded/installed Eclipse for Mobile(http://www.eclipse.org/downloads/packages/eclipse-mobile-developers/junosr2), and created an Android application, then using instructions found from this guy's video tutorial(http://www.youtube.com/watch?v=TazEIIoNVA0) to make it a Library so I can drop it into Unity.

Of course, his tutorial is for Mobclix, I am trying to build a GCM plugin, but the process is similar. I think I have included all dependencies I need. In Eclipse, in the project I see "Android Dependencies" which includes: classes.jar(Contains Unity player hooks), gcm.jar and android-support-v4.jar. Under "Android 4.2.2" I see "android.jar". Under "Referenced Libraries" I see classes.jar and gcm.jar. Following other forum posts(such as this one: GCM : java.lang.noclassdeffounderror: com.google.android.gcm.GCMRegistrar) about this error I had manually copied gcm.jar and classes.jar to the "libs" folder(I am using ADT 17), then selected to Add To Build Path.

After all of this, I still see 2 errors when I deploy to test on a device, the first is the title error, followed by a NoClassDefFoundError. I've gone through 3 devices for compatibility, and I'm currently using a Motorola with 2.3.3 on it(So it should support GCM). If anyone knows what else could be causing this please let me know. I am not very familiar with Eclipse(Or even Java for that matter), so I'm betting it's in the Java project somehow.

My Manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" package="com.my.package.testapp" android:versionName="1.0" android:versionCode="1">

    <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" />

    <supports-screens
        android:smallScreens="true"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"
        android:anyDensity="true"
    />

    <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="false">

        <activity android:name="com.unity3d.player.UnityPlayerProxyActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="my_test_scheme" android:host="*" />
            </intent-filter>
        </activity>

        <activity
            android:name="com.unity3d.player.UnityPlayerActivity"
            android:label="@string/app_name"
            android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
            android:screenOrientation="portrait"
        />

        <activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="portrait">
            <meta-data android:name="android.app.lib_name" android:value="unity" />
            <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" />
        </activity>

        <activity
            android:name="com.unity3d.player.VideoPlayer"
            android:label="@string/app_name"
            android:screenOrientation="behind"
            android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen"
        />

        <receiver
            android:name="com.google.android.gcm.GCMBroadcastReceiver"
            android:permission="com.google.android.c2dm.permission.SEND" >
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
                <action android:name="com.google.android.c2dm.intent.REGISTRATION" />
                <category android:name="com.my.package.testapp" />
            </intent-filter>
        </receiver>

        <service android:name="com.my_provider.gcm.GCMIntentService" />
    </application>

    <uses-feature android:glEsVersion="0x00020000" />

    <uses-permission android:name="com.my.package.testapp.permission.C2D_MESSAGE" />    
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

    <permission
        android:name="com.my.package.testapp.permission.C2D_MESSAGE"
        android:protectionLevel="signature"
    />

</manifest>

My Logcat:

I/Unity   (16312): MyApplication::MyApplication()
I/Unity   (16312): 
I/Unity   (16312):  
I/Unity   (16312): (Filename: ./Runtime/ExportGenerated/AndroidManaged/UnityEngineDebug.cpp Line: 43)
I/Unity   (16312): 
D/dalvikvm(16344): GC_CONCURRENT freed 1309K, 55% free 3034K/6727K, external 1625K/2137K, paused 2ms+3ms
D/dalvikvm(16344): GC_CONCURRENT freed 539K, 54% free 3137K/6727K, external 1625K/2137K, paused 2ms+2ms
D/DeviceProfile(16344): ************************** Properties ****************************
D/DeviceProfile(16344): * android.vm.dexfile: true
D/DeviceProfile(16344): * file.encoding: UTF-8
D/DeviceProfile(16344): * file.separator: /
D/DeviceProfile(16344): * http.agent: Dalvik/1.4.0 (Linux; U; Android 2.3.4; LG-P999 Build/GRJ22)
D/DeviceProfile(16344): * java.boot.class.path: /system/framework/core.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/core-junit.jar
D/DeviceProfile(16344): * java.class.path: .
D/DeviceProfile(16344): * java.class.version: 46.0
D/DeviceProfile(16344): * java.compiler: 
D/DeviceProfile(16344): * java.ext.dirs: 
D/DeviceProfile(16344): * java.home: /system
D/DeviceProfile(16344): * java.io.tmpdir: /sdcard
D/DeviceProfile(16344): * java.library.path: /vendor/lib:/system/lib
D/DeviceProfile(16344): * java.net.preferIPv6Addresses: true
D/DeviceProfile(16344): * java.runtime.name: Android Runtime
D/DeviceProfile(16344): * java.runtime.version: 0.9
D/DeviceProfile(16344): * java.specification.name: Dalvik Core Library
D/DeviceProfile(16344): * java.specification.vendor: The Android Project
D/DeviceProfile(16344): * java.specification.version: 0.9
D/DeviceProfile(16344): * java.vendor: The Android Project
D/DeviceProfile(16344): * java.vendor.url: http://www.android.com/
D/DeviceProfile(16344): * java.version: 0
D/DeviceProfile(16344): * java.vm.name: Dalvik
D/DeviceProfile(16344): * java.vm.specification.name: Dalvik Virtual Machine Specification
D/DeviceProfile(16344): * java.vm.specification.vendor: The Android Project
D/DeviceProfile(16344): * java.vm.specification.version: 0.9
D/DeviceProfile(16344): * java.vm.vendor: The Android Project
D/DeviceProfile(16344): * java.vm.vendor.url: http://www.android.com/
D/DeviceProfile(16344): * java.vm.version: 1.4.0
D/DeviceProfile(16344): * javax.net.ssl.trustStore: /system/etc/security/cacerts.bks
D/DeviceProfile(16344): * line.separator: 
D/DeviceProfile(16344): * mngspkphone: true
D/DeviceProfile(16344): * os.arch: armv7l
D/DeviceProfile(16344): * os.name: Linux
D/DeviceProfile(16344): * os.version: 2.6.32.9
D/DeviceProfile(16344): * path.separator: :
D/DeviceProfile(16344): * recording.auto-focus: true
D/DeviceProfile(16344): * recording.ffc.camera-sensor: 1
D/DeviceProfile(16344): * recording.ffc.video: 320x240 15 low
D/DeviceProfile(16344): * recording.hd.video: 1280x720 24 hd
D/DeviceProfile(16344): * recording.live.audio-aux: EhAAAA==
D/DeviceProfile(16344): * recording.live.video: 176x144 15 low
D/DeviceProfile(16344): * recording.live.video-aux: AUKAHv/hAAhnQoAelaCxMQEABGjOPIA=
D/DeviceProfile(16344): * recording.live.video-aux-rotation-90: AUKAHv/hAAhnQoAelaCRcQEABGjOPIA=
D/DeviceProfile(16344): * recording.liveffc.audio-aux: EhAAAA==
D/DeviceProfile(16344): * recording.liveffc.camera-sensor: 1
D/DeviceProfile(16344): * recording.liveffc.video: 176x144 15 low
D/DeviceProfile(16344): * recording.liveffc.video-aux: AUKAHv/hAAhnQoAelaCxMQEABGjOPIA=
D/DeviceProfile(16344): * recording.liveffc.video-aux-rotation-90: AUKAHv/hAAhnQoAelaCRcQEABGjOPIA=
D/DeviceProfile(16344): * recording.normal.video: 640x480 15 medium
D/DeviceProfile(16344): * user.dir: /
D/DeviceProfile(16344): * user.home: 
D/DeviceProfile(16344): * user.language: en
D/DeviceProfile(16344): * user.name: 
D/DeviceProfile(16344): * user.region: US
D/DeviceProfile(16344): ******************************************************************
I/ActivityManager( 1111): No longer want com.google.android.gsf.login (pid 15960): hidden #16
I/dalvikvm(16312): Could not find method com.google.android.gcm.GCMRegistrar.checkDevice, referenced from method com.my_provider.gcm.RegisterActivity.RegisterDevice
W/dalvikvm(16312): VFY: unable to resolve static method 382: Lcom/google/android/gcm/GCMRegistrar;.checkDevice (Landroid/content/Context;)V
D/dalvikvm(16312): VFY: replacing opcode 0x71 at 0x0000
D/dalvikvm(16312): VFY: dead code 0x0003-001c in Lcom/my_provider/gcm/RegisterActivity;.RegisterDevice (Landroid/app/Activity;)V
W/Unity   (16312): Font size and style overrides are only supported for dynamic fonts.
W/Unity   (16312):  
W/Unity   (16312): (Filename: ./Runtime/GUI/TextMeshGenerator2.cpp Line: 65)
W/Unity   (16312): 
W/Unity   (16312): Font size and style overrides are only supported for dynamic fonts.
W/Unity   (16312):  
W/Unity   (16312): (Filename: ./Runtime/GUI/TextMeshGenerator2.cpp Line: 65)
W/Unity   (16312): 
W/dalvikvm(16312): threadid=9: thread exiting with uncaught exception (group=0x4001d560)
E/AndroidRuntime(16312): FATAL EXCEPTION: GLThread 10
E/AndroidRuntime(16312): java.lang.NoClassDefFoundError: com.google.android.gcm.GCMRegistrar
E/AndroidRuntime(16312):    at com.my_provider.gcm.RegisterActivity.RegisterDevice(RegisterActivity.java:23)
E/AndroidRuntime(16312):    at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
E/AndroidRuntime(16312):    at com.unity3d.player.UnityPlayer.onDrawFrame(Unknown Source)
E/AndroidRuntime(16312):    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1363)
E/AndroidRuntime(16312):    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1118)
W/ActivityManager( 1111):   Force finishing activity com.my.package.testapp/com.unity3d.player.UnityPlayerNativeActivity

The code is very simple with two files

RegisterActivity.java:

package com.my_provider.gcm;

import android.os.Bundle;
import android.app.Activity;
import com.google.android.gcm.GCMRegistrar;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

public class RegisterActivity extends UnityPlayerActivity
{
    public static String ProjectID;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    }

    public static void RegisterDevice(final Activity activity)
    {
        try
        {
            GCMRegistrar.checkDevice(activity);
            GCMRegistrar.checkManifest(activity);

            final String regId = GCMRegistrar.getRegistrationId(activity);

            if (regId.equals(""))
                GCMRegistrar.register(activity, ProjectID);
        }
        catch(Exception e)
        {
            UnityPlayer.UnitySendMessage("ErrorHandlerGameObject", "OnError", e.getMessage());
        }
    }
}

And lastly the service GCMBroadcastReceiver.java:

package com.my_provider.gcm;
import android.content.Context;
import android.content.Intent;

import com.google.android.gcm.GCMBaseIntentService;
import com.unity3d.player.UnityPlayer;

public class GCMBroadcastReceiver extends GCMBaseIntentService {

    public GCMBroadcastReceiver()
    {
        super(RegisterActivity.ProjectID);
    }

    @Override
    protected void onRegistered(Context context, String deviceID)
    {
        UnityPlayer.UnitySendMessage("DeviceRegisteringGameObject", "OnRegisteredAndroidDevice", deviceID);
    }

    @Override
    protected void onUnregistered(Context context, String deviceID)
    {
        UnityPlayer.UnitySendMessage("DeviceRegisteringGameObject", "OnUnregisteredAndroidDevice", deviceID);
    }

    @Override
    public void onError(Context context, String errorID)
    {
        UnityPlayer.UnitySendMessage("DeviceRegisteringGameObject", "OnError", errorID);
    }

    @Override
    protected void onMessage(Context context, Intent intent)
    {
        UnityPlayer.UnitySendMessage("DeviceRegisteringGameObject", "OnMessageAndroid", intent.getStringExtra("message"));
    }
}
Community
  • 1
  • 1
sidestepper
  • 115
  • 3
  • 10

1 Answers1

1

I had manually copied gcm.jar and classes.jar to the "libs" folder(I am using ADT 17), then selected to Add To Build Path.

I have no idea what classes.jar is.

Simply having gcm.jar in your libs/ folder is sufficient for a regular Android app -- manually changing your build path with "Add to Build Path" is a mistake.

Whether the process for a Unity plugin is different, I cannot say.

The error indicates that you have gcm.jar in your compile-time build path (e.g., via Add to Build Path) but it is not in the APK (e.g., you do not have gcm.jar in libs/, or adding it to your build path manually prevented it from being added to your APK).

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Classes.jar is tricky to find, it contains Unity specific hooks, more on it here: http://answers.unity3d.com/questions/182912/location-of-playbackenginesandroidplayerbin-on-a-m.html. I will try to build without adding gcm.jar to my build path and see if that does anything – sidestepper May 14 '13 at 18:34
  • 1
    looks like for Unity, you need to make sure those aren't in the build path, but instead dropped in along side the plugin jar you make, so yes, this did seem to fix the issue. Thanks – sidestepper May 14 '13 at 19:39