0

每次我尝试在我的手机上测试我的应用程序时,它都会显示一条提示“不幸的是,该应用程序已停止”。

我已经检查了构建路径,并确保添加了 Google Play 服务库。我已经尝试搜索几个关于如何修复的线程,但它们都没有工作。所以我把这篇文章作为最后的手段让别人手动检查。

显现:

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

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

    <permission
          android:name="in.wptrafficanalyzer.locationmarkersqlite.permission.MAPS_RECEIVE"
          android:protectionLevel="signature"/>

    <uses-permission android:name="in.wptrafficanalyzer.locationmarkersqlite.permission.MAPS_RECEIVE"/>

    <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
        <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="in.wptrafficanalyzer.locationmarkersqlite.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

         <provider 
            android:name="LocationsContentProvider"
            android:authorities="in.wptrafficanalyzer.locationmarkersqlite.locations"
            android:exported="false" />

        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="YOUR_ANDROID_API_KEY" />

    </application>

</manifest>

活动主要:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"    
    tools:context=".MainActivity" >

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

</RelativeLayout>

主要活动.java:

package in.wptrafficanalyzer.locationmarkersqlite;

import android.app.Dialog;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.view.Menu;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends FragmentActivity implements LoaderCallbacks<Cursor> {

    GoogleMap googleMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Getting Google Play availability status
        int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getBaseContext());

        // Showing status
        if(status!=ConnectionResult.SUCCESS){ // Google Play Services are not available

            int requestCode = 10;
            Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this, requestCode);
            dialog.show();

        }else { // Google Play Services are available           

            // Getting reference to the SupportMapFragment of activity_main.xml
            SupportMapFragment fm = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

            // Getting GoogleMap object from the fragment
            googleMap = fm.getMap();

            // Enabling MyLocation Layer of Google Map
            googleMap.setMyLocationEnabled(true);           

            // Invoke LoaderCallbacks to retrieve and draw already saved locations in map
            getSupportLoaderManager().initLoader(0, null, this);            
        }        

        googleMap.setOnMapClickListener(new OnMapClickListener() {

            @Override
            public void onMapClick(LatLng point) {      


                // Drawing marker on the map
                drawMarker(point);          

                // Creating an instance of ContentValues
                ContentValues contentValues = new ContentValues();

                // Setting latitude in ContentValues
                contentValues.put(LocationsDB.FIELD_LAT, point.latitude );

                // Setting longitude in ContentValues
                contentValues.put(LocationsDB.FIELD_LNG, point.longitude);

                // Setting zoom in ContentValues
                contentValues.put(LocationsDB.FIELD_ZOOM, googleMap.getCameraPosition().zoom);

                // Creating an instance of LocationInsertTask
                LocationInsertTask insertTask = new LocationInsertTask();

                // Storing the latitude, longitude and zoom level to SQLite database
                insertTask.execute(contentValues);                

                Toast.makeText(getBaseContext(), "Marker is added to the Map", Toast.LENGTH_SHORT).show();                  

            }
        }); 


        googleMap.setOnMapLongClickListener(new OnMapLongClickListener() {              
            @Override
            public void onMapLongClick(LatLng point) {

                // Removing all markers from the Google Map
                googleMap.clear();

                // Creating an instance of LocationDeleteTask
                LocationDeleteTask deleteTask = new LocationDeleteTask();

                // Deleting all the rows from SQLite database table
                deleteTask.execute();

                Toast.makeText(getBaseContext(), "All markers are removed", Toast.LENGTH_LONG).show();

            }
        });
    }


    private void drawMarker(LatLng point){
        // Creating an instance of MarkerOptions
        MarkerOptions markerOptions = new MarkerOptions();                  

        // Setting latitude and longitude for the marker
        markerOptions.position(point);

        // Adding marker on the Google Map
        googleMap.addMarker(markerOptions);         
    }


    private class LocationInsertTask extends AsyncTask<ContentValues, Void, Void>{
        @Override
        protected Void doInBackground(ContentValues... contentValues) {

            /** Setting up values to insert the clicked location into SQLite database */           
            getContentResolver().insert(LocationsContentProvider.CONTENT_URI, contentValues[0]);            
            return null;
        }       
    }

    private class LocationDeleteTask extends AsyncTask<Void, Void, Void>{
        @Override
        protected Void doInBackground(Void... params) {

            /** Deleting all the locations stored in SQLite database */
            getContentResolver().delete(LocationsContentProvider.CONTENT_URI, null, null);          
            return null;
        }       
    }   


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


    @Override
    public Loader<Cursor> onCreateLoader(int arg0,
            Bundle arg1) {

        // Uri to the content provider LocationsContentProvider
        Uri uri = LocationsContentProvider.CONTENT_URI;

        // Fetches all the rows from locations table
        return new CursorLoader(this, uri, null, null, null, null);

    }


    @Override
    public void onLoadFinished(Loader<Cursor> arg0,
            Cursor arg1) {
        int locationCount = 0;
        double lat=0;
        double lng=0;
        float zoom=0;

        // Number of locations available in the SQLite database table
        locationCount = arg1.getCount();

        // Move the current record pointer to the first row of the table
        arg1.moveToFirst();

        for(int i=0;i<locationCount;i++){

            // Get the latitude
            lat = arg1.getDouble(arg1.getColumnIndex(LocationsDB.FIELD_LAT));

            // Get the longitude
            lng = arg1.getDouble(arg1.getColumnIndex(LocationsDB.FIELD_LNG));

            // Get the zoom level
            zoom = arg1.getFloat(arg1.getColumnIndex(LocationsDB.FIELD_ZOOM));

            // Creating an instance of LatLng to plot the location in Google Maps
            LatLng location = new LatLng(lat, lng);

            // Drawing the marker in the Google Maps
            drawMarker(location);

            // Traverse the pointer to the next row
            arg1.moveToNext();
        }

        if(locationCount>0){
            // Moving CameraPosition to last clicked position
            googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(lat,lng)));

            // Setting the zoom level in the map on last position  is clicked
            googleMap.animateCamera(CameraUpdateFactory.zoomTo(zoom));  

        }       
    }

    @Override
    public void onLoaderReset(Loader<Cursor> arg0) {
        // TODO Auto-generated method stub      
    }   
}

位置数据库.java:

package in.wptrafficanalyzer.locationmarkersqlite;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;


public class LocationsDB extends SQLiteOpenHelper{

    /** Database name */
    private static String DBNAME = "locationmarkersqlite";

    /** Version number of the database */
    private static int VERSION = 1;

    /** Field 1 of the table locations, which is the primary key */
    public static final String FIELD_ROW_ID = "_id";

    /** Field 2 of the table locations, stores the latitude */
    public static final String FIELD_LAT = "lat";

    /** Field 3 of the table locations, stores the longitude*/
    public static final String FIELD_LNG = "lng";

    /** Field 4 of the table locations, stores the zoom level of map*/
    public static final String FIELD_ZOOM = "zom";

    /** A constant, stores the the table name */
    private static final String DATABASE_TABLE = "locations";

    /** An instance variable for SQLiteDatabase */
    private SQLiteDatabase mDB;  


    /** Constructor */
    public LocationsDB(Context context) {
        super(context, DBNAME, null, VERSION);  
        this.mDB = getWritableDatabase();
    }


    /** This is a callback method, invoked when the method getReadableDatabase() / getWritableDatabase() is called 
      * provided the database does not exists 
    * */
    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql =    "create table " + DATABASE_TABLE + " ( " +
                            FIELD_ROW_ID + " integer primary key autoincrement , " +
                            FIELD_LNG + " double , " +
                            FIELD_LAT + " double , " +
                            FIELD_ZOOM + " text " +
                        " ) ";

        db.execSQL(sql);
    }

    /** Inserts a new location to the table locations */
    public long insert(ContentValues contentValues){
        long rowID = mDB.insert(DATABASE_TABLE, null, contentValues);
        return rowID;

    }   


    /** Deletes all locations from the table */
    public int del(){
        int cnt = mDB.delete(DATABASE_TABLE, null , null);      
        return cnt;
    }

    /** Returns all the locations from the table */
    public Cursor getAllLocations(){
        return mDB.query(DATABASE_TABLE, new String[] { FIELD_ROW_ID,  FIELD_LAT , FIELD_LNG, FIELD_ZOOM } , null, null, null, null, null);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

}

LocationContenteProvider.java:

package in.wptrafficanalyzer.locationmarkersqlite;

import java.sql.SQLException;

import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;

/** A custom Content Provider to do the database operations */
public class LocationsContentProvider extends ContentProvider{

    public static final String PROVIDER_NAME = "in.wptrafficanalyzer.locationmarkersqlite.locations";

    /** A uri to do operations on locations table. A content provider is identified by its uri */
    public static final Uri CONTENT_URI = Uri.parse("content://" + PROVIDER_NAME + "/locations" );

    /** Constant to identify the requested operation */
    private static final int LOCATIONS = 1; 

    private static final UriMatcher uriMatcher ;

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(PROVIDER_NAME, "locations", LOCATIONS);       
    }

    /** This content provider does the database operations by this object */
    LocationsDB mLocationsDB;

    /** A callback method which is invoked when the content provider is starting up */
    @Override
    public boolean onCreate() {
        mLocationsDB = new LocationsDB(getContext());
        return true;
    }

    /** A callback method which is invoked when insert operation is requested on this content provider */
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        long rowID = mLocationsDB.insert(values);
        Uri _uri=null;
        if(rowID>0){
            _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
        }else {     
            try {
                throw new SQLException("Failed to insert : " + uri);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return _uri;    
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        // TODO Auto-generated method stub
        return 0;
    }



    /** A callback method which is invoked when delete operation is requested on this content provider */
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int cnt = 0;        
        cnt = mLocationsDB.del();   
        return cnt;
    }

    /** A callback method which is invoked by default content uri */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 

        if(uriMatcher.match(uri)==LOCATIONS){
            return mLocationsDB.getAllLocations();
        }
        return null;
    }


    @Override
    public String getType(Uri uri) {        
        return null;
    }   
}

日志猫:

11-06 18:13:23.327: E/AndroidRuntime(2219): FATAL EXCEPTION: main
11-06 18:13:23.327: E/AndroidRuntime(2219): java.lang.RuntimeException: Unable to start activity ComponentInfo{in.wptrafficanalyzer.locationmarkersqlite/in.wptrafficanalyzer.locationmarkersqlite.MainActivity}: java.lang.NullPointerException
11-06 18:13:23.327: E/AndroidRuntime(2219):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at android.os.Looper.loop(Looper.java:137)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at android.app.ActivityThread.main(ActivityThread.java:5041)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at java.lang.reflect.Method.invokeNative(Native Method)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at java.lang.reflect.Method.invoke(Method.java:511)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at dalvik.system.NativeStart.main(Native Method)
11-06 18:13:23.327: E/AndroidRuntime(2219): Caused by: java.lang.NullPointerException
11-06 18:13:23.327: E/AndroidRuntime(2219):     at in.wptrafficanalyzer.locationmarkersqlite.MainActivity.onCreate(MainActivity.java:60)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at android.app.Activity.performCreate(Activity.java:5104)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
11-06 18:13:23.327: E/AndroidRuntime(2219):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
4

1 回答 1

1

我还尝试了我解决的相同代码一个问题,onMapClickListner() 的错误在android:name="com.google.android.gms.maps.SupportMapFragment" 您的 MapActivity 布局文件中

于 2015-10-20T11:47:02.603 回答