2015-10-20 94 views
0

我在OnLoadFinished()方法上收到錯誤我不知道要解決這個問題。在Android SQLite數據庫中存儲Google Map的位置錯誤

清單:

<?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> 

主要activity.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  
    } 
} 

LocationDB.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; 
    } 
} 

登錄貓

10-20 16:44:13.606 15122-15483/com.mtksofts.here.frienzapp E/ActivityThread:無法找到供應商信息對於 com.mtksofts.here.frienzapp.locations

10-20 16:44:13.618 15122-15122/com.mtksofts.here.frienzapp I /編舞:跳過51幀!其主線程上的應用程序可能也做了太多的工作。 10-20 16:44:13.679 15122-15122/com.mtksofts.here.frienzapp D/AndroidRuntime:關閉 關閉VM 10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:致命例外:main 10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:進程: com.mtksofts.here.frienzapp,PID:15122 10-20 16:44 :13.682 15122-15122/com.mtksofts.here.frienzapp E/Android運行時間: java.lang.NullPointerException:試圖調用接口方法 'int android.database.Cursor.getCount()'null對象引用 10 -20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:在 com.mtksofts.here.frienzapp.MapsActi vity.onLoadFinished(MapsActivity.java:213) 10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:at com.mtksofts.here.frienzapp.MapsActivity.onLoadFinished(MapsActivity .java:31) 10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:at android.support.v4.app.LoaderManagerImpl $ LoaderInfo.callOnLoadFinished(LoaderManager.java: 476) 10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:在 android.support.v4.app.LoaderManagerImpl $ LoaderInfo.onLoadComplete(LoaderManager.java:444) 10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:在 android.support.v4.content.Loader.deliverResult(Loader.java:126)10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime: at android.support。 v4.content.CursorLoader.deliverResult(CursorLoader.java:105) 10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:at android.support.v4.content.CursorLoader .deliverResult(CursorLoader.java:37) 10-20 16:44:13.682 15122-15122/com.mtksofts.here。frienzapp E/AndroidRuntime:在 android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:249) 10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime :在 android.support.v4.content.AsyncTaskLoader $ LoadTask.onPostExecute(AsyncTaskLoader.java:77) 10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:在 android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:466) 10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:at android.support.v4 .content.ModernAsyncTask.access $ 400(ModernAsyncTask.java:48) 10- 20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:at android.support.v4.content.ModernAsyncTask $ InternalHandler.handleMessage(ModernAsyncTask.java:483) 10-20 16: 44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:at android.os.Handler.dispatchMessage(Handler.java:102)10-20 16:44:13.682 15122-15122/com。 mtksofts.here.frienzapp E/AndroidRuntime: at android.os.Looper.loop(Looper.java:135)10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:at android.app.ActivityThread.main(ActivityThread.java:5236)10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime: a t java.lang.reflect.Method.invoke(Native Method)10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:at java.lang.reflect.Method.invoke( Method.java:372)10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java: 898) 10-20 16:44:13.682 15122-15122/com.mtksofts.here.frienzapp E/AndroidRuntime:在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)

+0

您應該嘗試將代碼範圍縮小到與錯誤實際相關的信息。我們都在這裏幫助診斷特定問題,而不是掃描您的項目文件以查找所有可能的錯誤。只是試圖幫助你得到答案。 – Felipe

回答

1

驗證以下內容..

1>匹配PROVIDER_NAME權威明顯嗎?

2>LocationsContentProvider.CONTENT_URIUriMatcher

3>調試查詢方法是返回null?

4>在清單中設置讀取權限。