无法启动活动... java.lang.NullPointerException

时间:2014-01-24 10:21:31

标签: java android google-maps google-play-services

在此代码中找到我的错误确实很困难。被困在了一段令人尴尬的长时间。找到问题的任何帮助都会有很大的帮助。

这是抛出错误的类

    package ggow.teamt.mdrs;

    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.GooglePlayServicesClient;
    import com.google.android.gms.common.GooglePlayServicesClient.ConnectionCallbacks;
    import com.google.android.gms.common.GooglePlayServicesUtil;
    import com.google.android.gms.location.LocationClient;
    import com.google.android.gms.location.LocationListener;
    import com.google.android.gms.maps.GoogleMap;
    import com.google.android.gms.maps.GoogleMap.OnMyLocationButtonClickListener;
    import com.google.android.gms.maps.MapFragment;
    import android.location.Location;
    import android.os.Bundle;
    import android.app.Activity;
    import android.app.Dialog;
    import android.content.Intent;
    import android.content.IntentSender;
    import android.support.v4.app.DialogFragment;
    import android.support.v4.app.FragmentActivity;
    import android.util.Log;
    import android.view.Menu;
    import android.view.View;
    import android.widget.Toast;

    public class MapViewActivity extends FragmentActivity
    implements
    GooglePlayServicesClient.ConnectionCallbacks,
    GooglePlayServicesClient.OnConnectionFailedListener,
    LocationListener,
    OnMyLocationButtonClickListener{

    private final static int
    CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
    private static final String LOG_TAG = "MapView - MDRS";
    private GoogleMap mMap;
    private LocationClient mLocationClient;
    public Location mCurrentLocation;
    public final static String START_LOCATION = "ggow.teamt.mdrs.location";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.v(LOG_TAG, "into onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map_view);
        setUpMapIfNeeded();
        mLocationClient = new LocationClient(this, this, this);
        mCurrentLocation = mLocationClient.getLastLocation();
        Toast.makeText(this, "Current location found.",
                Toast.LENGTH_SHORT).show();
        Log.v(LOG_TAG, "made it to the end of onCreate");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.v(LOG_TAG, "into onStart");

        // Connect the client.
        mLocationClient.connect();
    }

    @Override
    protected void onStop() {
        // Disconnecting the client invalidates it.
        mLocationClient.disconnect();
        super.onStop();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.map_view, menu);
        return true;
    }

    public void startRecording(View view){
        Intent intent = new Intent(this, RecordingActivity.class);
        intent.putExtra(START_LOCATION, mCurrentLocation);
    }

    private void setUpMapIfNeeded() { //would be used onResume I would assume
        Log.v(LOG_TAG, "into SuMiN");

        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
                    .getMap();
            mMap.setMyLocationEnabled(true);
            mMap.getUiSettings().setCompassEnabled(true);
            mMap.getUiSettings().setMyLocationButtonEnabled(true);
            mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                Log.e(LOG_TAG, "Map's all good brah");
            }
        }
    }

    @Override
    public boolean onMyLocationButtonClick() {
        System.err.println("in onMyLocationButtonClick()");
        return false;
    }


    @Override
    public void onLocationChanged(Location arg0) {
        System.err.println("in onLocChanged");
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        System.err.println("Connection failed");
        /*
         * Google Play services can resolve some errors it detects.
         * If the error has a resolution, try sending an Intent to
         * start a Google Play services activity that can resolve
         * error.
         */
        if (connectionResult.hasResolution()) {
            try {
                // Start an Activity that tries to resolve the error
                connectionResult.startResolutionForResult(
                        this,
                        CONNECTION_FAILURE_RESOLUTION_REQUEST);
                /*
                 * Thrown if Google Play services cancelled the original
                 * PendingIntent
                 */
            } catch (IntentSender.SendIntentException e) {
                // Log the error
                e.printStackTrace();
            }
        } else {
            /*
             * If no resolution is available, display a dialog to the
             * user with the error.
             */
            showDialog(connectionResult.getErrorCode());
        }
    }

    /**
     * Callback called when connected to GCore. Implementation of {@link ConnectionCallbacks}.
     */
    @Override
    public void onConnected(Bundle connectionHint) {
        Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
    }

    /**
     * Callback called when disconnected from GCore. Implementation of {@link ConnectionCallbacks}.
     */
    @Override
    public void onDisconnected() {
        Toast.makeText(this, "Disconnected. Please re-connect.",
                Toast.LENGTH_SHORT).show();
    }

    public static class ErrorDialogFragment extends DialogFragment {
        // Global field to contain the error dialog
        private Dialog mDialog;
        // Default constructor. Sets the dialog field to null
        public ErrorDialogFragment() {
            super();
            mDialog = null;
        }
        // Set the dialog to display
        public void setDialog(Dialog dialog) {
            mDialog = dialog;
        }
        // Return a Dialog to the DialogFragment.
        @Override
        public Dialog onCreateDialog(Bundle savedInstanceState) {
            return mDialog;
        }
    }
    /*
     * Handle results returned to the FragmentActivity
     * by Google Play services
     */
    @Override
    protected void onActivityResult(
            int requestCode, int resultCode, Intent data) {
        // Decide what to do based on the original request code
        switch (requestCode) {
        case CONNECTION_FAILURE_RESOLUTION_REQUEST :
            /*
             * If the result code is Activity.RESULT_OK, try
             * to connect again
             */
            switch (resultCode) {
            case Activity.RESULT_OK :
                /*
                 * Try the request again
                 */
                break;
            }
        }
    }

    @SuppressWarnings("unused")
    private boolean servicesConnected() {
        // Check that Google Play services is available
        int resultCode =
                GooglePlayServicesUtil.
                isGooglePlayServicesAvailable(this);
        // If Google Play services is available
        if (ConnectionResult.SUCCESS == resultCode) {
            // In debug mode, log the status
            Log.d("Location Updates",
                    "Google Play services is available.");
            // Continue
            return true;
            // Google Play services was not available for some reason
        } else {
            // Get the error code
            Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(
                    resultCode,
                    this,
                    CONNECTION_FAILURE_RESOLUTION_REQUEST);

            // If Google Play services can provide an error dialog
            if (errorDialog != null) {
                // Create a new DialogFragment for the error dialog
                ErrorDialogFragment errorFragment =
                        new ErrorDialogFragment();
                // Set the dialog in the DialogFragment
                errorFragment.setDialog(errorDialog);
                // Show the error dialog in the DialogFragment
                errorFragment.show(getSupportFragmentManager(),
                        "Location Updates");
            }
            return false;
        }
    }
}

这是它的.xml布局文件:

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MapViewActivity" >

    <ImageButton
        android:id="@+id/recButton"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:contentDescription="@string/recButtonContentDescription"
        android:onClick="startRecording" />

    <fragment 
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.MapFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment"
         />

</RelativeLayout>

应用程序的清单以备不时之需:

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

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="ggow.teamt.mdrs.MapViewActivity"
            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="ggow.teamt.mdrs.SettingsActivity"
            android:label="@string/title_activity_settings"
            android:parentActivityName="MapViewActivity" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="MapViewActivity" />
        </activity>
        <activity
            android:name="ggow.teamt.mdrs.RecordingActivity"
            android:label="@string/title_activity_recording" >
        </activity>
        <activity
            android:name="ggow.teamt.mdrs.UploadActivity"
            android:label="@string/title_activity_upload"
            android:parentActivityName="MapViewActivity" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="MapViewActivity" />
        </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="AIzaSyAK8ETmyOtd9DZ0RvG9DjEgRnc7Ps3uHkU" />
    </application>

</manifest>

这给了我真正的问题,我已经梳理过它,似乎无法弄明白。任何帮助表示赞赏。

编辑: 这是堆栈跟踪。遗憾。

01-24 10:42:19.491: V/MapView - MDRS(24003): into onCreate
01-24 10:42:19.591: D/dalvikvm(24003): GC_FOR_ALLOC freed 232K, 2% free 17008K/17272K, paused 11ms, total 12ms
01-24 10:42:19.671: D/dalvikvm(24003): GC_FOR_ALLOC freed 333K, 3% free 17172K/17544K, paused 14ms, total 14ms
01-24 10:42:19.721: D/dalvikvm(24003): GC_FOR_ALLOC freed 252K, 2% free 17432K/17716K, paused 13ms, total 13ms
01-24 10:42:19.761: D/dalvikvm(24003): GC_FOR_ALLOC freed 156K, 2% free 17726K/17932K, paused 12ms, total 16ms
01-24 10:42:19.801: D/dalvikvm(24003): GC_FOR_ALLOC freed 62K, 1% free 18062K/18232K, paused 11ms, total 11ms
01-24 10:42:19.801: V/MapView - MDRS(24003): into SuMiN
01-24 10:42:19.811: E/MapView - MDRS(24003): Map's all good brah
01-24 10:42:19.811: D/AndroidRuntime(24003): Shutting down VM
01-24 10:42:19.811: W/dalvikvm(24003): threadid=1: thread exiting with uncaught exception (group=0x4158bba8)
01-24 10:42:19.811: E/AndroidRuntime(24003): FATAL EXCEPTION: main
01-24 10:42:19.811: E/AndroidRuntime(24003): Process: ggow.teamt.mdrs, PID: 24003
01-24 10:42:19.811: E/AndroidRuntime(24003): java.lang.RuntimeException: Unable to start activity ComponentInfo{ggow.teamt.mdrs/ggow.teamt.mdrs.MapViewActivity}: java.lang.IllegalStateException: Not connected. Call connect() and wait for onConnected() to be called.
01-24 10:42:19.811: E/AndroidRuntime(24003):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at android.app.ActivityThread.access$800(ActivityThread.java:135)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at android.os.Handler.dispatchMessage(Handler.java:102)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at android.os.Looper.loop(Looper.java:136)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at android.app.ActivityThread.main(ActivityThread.java:5017)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at java.lang.reflect.Method.invokeNative(Native Method)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at java.lang.reflect.Method.invoke(Method.java:515)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at dalvik.system.NativeStart.main(Native Method)
01-24 10:42:19.811: E/AndroidRuntime(24003): Caused by: java.lang.IllegalStateException: Not connected. Call connect() and wait for onConnected() to be called.
01-24 10:42:19.811: E/AndroidRuntime(24003):    at com.google.android.gms.internal.dk.bB(Unknown Source)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at com.google.android.gms.internal.fm.a(Unknown Source)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at com.google.android.gms.internal.fm$c.bB(Unknown Source)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at com.google.android.gms.internal.fl.getLastLocation(Unknown Source)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at com.google.android.gms.internal.fm.getLastLocation(Unknown Source)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at com.google.android.gms.location.LocationClient.getLastLocation(Unknown Source)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at ggow.teamt.mdrs.MapViewActivity.onCreate(MapViewActivity.java:47)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at android.app.Activity.performCreate(Activity.java:5231)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
01-24 10:42:19.811: E/AndroidRuntime(24003):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
01-24 10:42:19.811: E/AndroidRuntime(24003):    ... 11 more
01-24 10:42:19.971: D/dalvikvm(24003): GC_FOR_ALLOC freed 336K, 2% free 18233K/18604K, paused 10ms, total 10ms
01-24 10:42:20.031: W/ActivityThread(24003): ClassLoader.loadClass: The class loader returned by Thread.getContextClassLoader() may fail for processes that host multiple applications. You should explicitly specify a context class loader. For example: Thread.setContextClassLoader(getClass().getClassLoader());

1 个答案:

答案 0 :(得分:0)

您说您正在获取NullPointerException,但您发布的堆栈跟踪列出了IllegalStateException。这一行可能是一个线索:

01-24 10:42:19.811: E/AndroidRuntime(24003): Caused by: java.lang.IllegalStateException: Not connected. Call connect() and wait for onConnected() to be called.

查看您的代码,似乎在您的onCreate()方法中,您将直接请求位置:

    mLocationClient = new LocationClient(this, this, this);
    mCurrentLocation = mLocationClient.getLastLocation();

在调用onConnected()回调之前,不应该调用getLastLocation()。 The documentation is a little unclear,但我的建议是将你的getLastLocation()调用放在onConnected()方法中,然后从那里运行任何需要当前位置的逻辑。