0

I wrote an App which has a Launcher activity and two Map activities.

When I run it, one Map activity works like a dream, while the other crashes with a java.lang.NoClassDefFoundError. The one that crashes has a "Link of class failed" warning before I invoke it.

I have been through all the applicable solutions on SO and none seem to help.I have:

  • checked and rechecked the Android Manifest,

  • done all that was advised to do to the Java Build Path.

  • checked all the imports of the activity (that crashes) to see that they were not implemented after the android:minSdkVersion in the Manifest

Since my App uses com.google.android.maps.* classes I considered putting a

<uses-library android:name="com.google.android.maps" />

element in the Manifest, but that produced an

Installation error: INSTALL_FAILED_MISSING_SHARED_LIBRARY

which according to Commonsware, Mar 27 '14:

< You have a element in your manifest. Either

  • that should not be there, or

  • you are attempting to install the app on a device that does not have that library. >

I tried inserting the maps.jar into my device's folders manually but that didn't get rid of the error either.

So here is my code: Launcher Activity class (called Selector.class):

package com.thenewboston.googlemaps;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class Selector extends Activity implements View.OnClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.select_activity);

        Button bMain = (Button)findViewById(R.id.button1);
        Button bOther = (Button)findViewById(R.id.button2);

        bMain.setOnClickListener(this);
        bOther.setOnClickListener(this);


    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        switch (v.getId()){
        case R.id.button1:
            Intent main_intent = new Intent(this,MainActivity.class);
            startActivity(main_intent);
            break;
        case R.id.button2:
            Intent other_intent = new Intent(this,OtherActivity.class);
            startActivity(other_intent);
            break;
        }

    }

}

My 2nd Map Activity called OtherActivity.class (which crashes):

package com.thenewboston.googlemaps;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class OtherActivity extends MapActivity implements LocationListener{

    MapView  myMapView;
    long start,stop;
    int x,y;
    GeoPoint touchedPoint;
    Drawable d;
    List<Overlay> overlayList;
    LocationManager lm;
    String towers;

    @Override
    protected void onCreate(Bundle arg0) {
        // TODO Auto-generated method stub
        super.onCreate(arg0);
        setContentView(R.layout.otheractivity);
        myMapView = (MapView)findViewById(R.id.mvMain);
        myMapView.setBuiltInZoomControls(true);

        TouchControls tc = new TouchControls(); // set instance of touch controls
        @SuppressWarnings("unchecked")
        List<Overlay> overlayList = (List<Overlay>)myMapView.getOverlay();
        overlayList.add(tc);

        d = getResources().getDrawable(R.drawable.ic_launcher);

        // placing pinpoint at location
        lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        int lat = 0;
        int longi = 0;
        GeoPoint ourLocation = new GeoPoint(lat,longi); 
        OverlayItem overlayItem = new OverlayItem(ourLocation,"What's up?","2nd string");
        CustomPinpoints custom = new CustomPinpoints(d,OtherActivity.this);
        custom.insertPinpoint(overlayItem);
        overlayList.add(custom);
     }

    public class TouchControls extends Overlay{

            // Point p;
            AlertDialog alert;
            @Override
            public boolean onTouchEvent(MotionEvent arg0,
                    com.google.android.maps.MapView arg1) {
                // TODO Auto-generated method stub

                if (arg0.getAction() == MotionEvent.ACTION_DOWN){
                    start = arg0.getEventTime();
                    x = (int)arg0.getX();
                    y = (int)arg0.getY();
                // p = new Point(x,y);
                    touchedPoint = myMapView.getProjection().fromPixels(x,y);
                }
                if (arg0.getAction() == MotionEvent.ACTION_UP){
                    stop = arg0.getEventTime();
                }
                if (stop - start > 1500){
                    alert = new AlertDialog.Builder(OtherActivity.this).create();
                    alert.setTitle("Pick an option");
                    alert.setMessage("I told you to pick an option");
                    int whichButton = 0;
                    alert.setButton(whichButton, "place a pinpoint",new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // TODO Auto-generated method stub
                            OverlayItem overlayItem = new OverlayItem(touchedPoint,"What's up?","2nd string");
                            CustomPinpoints custom = new CustomPinpoints(d,OtherActivity.this);
                            custom.insertPinpoint(overlayItem);
                            overlayList.add(custom);
                        }
                    } );
                    int whichButton2 = 0;
                    alert.setButton(whichButton2 ,"get address",new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // TODO Auto-generated method stub
                            Geocoder geocoder = new Geocoder(getBaseContext(),Locale.getDefault());
                            try {
                                List<Address> address = geocoder.getFromLocation(touchedPoint.getLatitudeE6()/1E6, touchedPoint.getLongitudeE6()/1E6, 1);
                                String display = "";
                                if (address.size() > 0){
                                    for(int i = 0; i < address.get(0).getMaxAddressLineIndex(); i++){
                                        display += address.get(0).getAddressLine(i) + "\n";
                                    }
                                Toast t = Toast.makeText(getBaseContext(), display, Toast.LENGTH_LONG);
                                t.show();
                                }

                            } catch (IOException e ){
                                e.printStackTrace();
                            } finally {

                            }

                        }
                    } );
                    int whichButton3 = 0;
                    alert.setButton(whichButton3 ,"Toggle View",new DialogInterface.OnClickListener() {

                        @SuppressWarnings("deprecation")
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            // TODO Auto-generated method stub
                            if (myMapView.isSatellite()){
                                myMapView.setSatellite(false);
                                myMapView.setStreetView(true);
                            } else {
                                myMapView.setStreetView(false);
                                myMapView.setSatellite(true);
                            }
                        }
                    } );

                    alert.show();
                 } //if 3

        return false;
        } 
    } // onTouchEvent

    @Override
    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void onLocationChanged(Location arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderDisabled(String arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderEnabled(String arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }
}

The Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.thenewboston.googlemaps"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="15"
        android:targetSdkVersion="21" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true" />
"
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >


        <activity
            android:name=".Selector"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".OtherActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
        <activity
            android:name=".CustomPinpoints"
            android:label="@string/app_name" >
        </activity>

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="whatever" />
    </application>

My LogCat:

02-12 12:43:02.930: W/dalvikvm(14102): Unable to resolve superclass of Lcom/thenewboston/googlemaps/OtherActivity; (4650)
02-12 12:43:02.930: W/dalvikvm(14102): Link of class 'Lcom/thenewboston/googlemaps/OtherActivity;' failed
02-12 12:43:02.930: E/dalvikvm(14102): Could not find class 'com.thenewboston.googlemaps.OtherActivity', referenced from method com.thenewboston.googlemaps.Selector.onClick
02-12 12:43:02.930: W/dalvikvm(14102): VFY: unable to resolve const-class 4662 (Lcom/thenewboston/googlemaps/OtherActivity;) in Lcom/thenewboston/googlemaps/Selector;


02-12 12:44:10.200: D/AndroidRuntime(14102): Shutting down VM
02-12 12:44:10.200: W/dalvikvm(14102): threadid=1: thread exiting with uncaught exception (group=0x415e9ba8)
02-12 12:44:10.210: E/AndroidRuntime(14102): FATAL EXCEPTION: main
02-12 12:44:10.210: E/AndroidRuntime(14102): Process: com.thenewboston.googlemaps, PID: 14102
02-12 12:44:10.210: E/AndroidRuntime(14102): java.lang.NoClassDefFoundError: com.thenewboston.googlemaps.OtherActivity
02-12 12:44:10.210: E/AndroidRuntime(14102):    at com.thenewboston.googlemaps.Selector.onClick(Selector.java:35)
02-12 12:44:10.210: E/AndroidRuntime(14102):    at android.view.View.performClick(View.java:4438)
02-12 12:44:10.210: E/AndroidRuntime(14102):    at android.view.View$PerformClick.run(View.java:18422)
02-12 12:44:10.210: E/AndroidRuntime(14102):    at android.os.Handler.handleCallback(Handler.java:733)
02-12 12:44:10.210: E/AndroidRuntime(14102):    at android.os.Handler.dispatchMessage(Handler.java:95)
02-12 12:44:10.210: E/AndroidRuntime(14102):    at android.os.Looper.loop(Looper.java:136)
02-12 12:44:10.210: E/AndroidRuntime(14102):    at android.app.ActivityThread.main(ActivityThread.java:5017)
02-12 12:44:10.210: E/AndroidRuntime(14102):    at java.lang.reflect.Method.invokeNative(Native Method)
02-12 12:44:10.210: E/AndroidRuntime(14102):    at java.lang.reflect.Method.invoke(Method.java:515)
02-12 12:44:10.210: E/AndroidRuntime(14102):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:813)
02-12 12:44:10.210: E/AndroidRuntime(14102):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
02-12 12:44:10.210: E/AndroidRuntime(14102):    at dalvik.system.NativeStart.main(Native Method)

my App's Project Explorer enter image description here

Any ideas about what to do?

Jo Mo
  • 317
  • 1
  • 3
  • 14
  • I would like to understand, why did someone give me -1? (At least, give a reason) – Jo Mo Feb 12 '15 at 14:19
  • `Unable to resolve superclass of Lcom/thenewboston/googlemaps/OtherActivity;` -- the superclass is `com.google.android.maps.MapActivity`, so it's apparently not finding the Google maps classes. That's a bit weird for two activities in the same APK. Does the other (working) class also extend MapActivity? – fadden Feb 12 '15 at 17:55
  • @fadden No, it extends Activity and implements OnMapReadyCallback and uses the MapFragment class. – Jo Mo Feb 15 '15 at 09:03
  • Possible duplicate of http://stackoverflow.com/questions/22340762/mapactivity-could-not-be-found-android-studio-0-5-1 – fadden Feb 15 '15 at 16:01
  • @fadden That link says that "with Google Maps Android API v2 , MapActivity is not available anymore. You need to use the MapFragment". I am using Google Maps Android API v2 and the activity that works for me uses MapActivity and the one that crashes uses MapFragment ! Could the activity that works be wrecking it for the other? It doesn't sound like it. – Jo Mo Feb 16 '15 at 12:36
  • @fadden that's it! You cracked it! I am using Google Maps Android v2 API and therefore Mapview is not going to work with it, only MapFragment. what can I do with all that code? throw it in the garbage? – Jo Mo Feb 16 '15 at 13:17

1 Answers1

-1

I guess while creating the api key for your map, you have not mentioned about the package name of both the activities but only for the first one..

Saurabh Rajpal
  • 1,537
  • 9
  • 14
  • Both activities are under one package name! – Jo Mo Feb 12 '15 at 14:11
  • I really pity the person who has down voted the answer here.. Though it's not relevant in case of Jo Mo, it's a very common error that people make.. Anyone looking out for a probable solution, please don't get misleaded by a downvote on this answer by a probable naive android developer.. Thanks.. – Saurabh Rajpal Feb 16 '15 at 20:19