我正在创建一个GPS跟踪应用程序,我处于开始阶段,我使用LocationManager跟踪纬度和经度,现在接下来要做的就是将所有数据存储在数据库中,我已经创建了Adapter类和我从MainActivity调用它但在绑定Context和打开数据库时遇到NullPointerException,请查看我的Logcat详细信息,并建议我一个解决方案。
我收到
附近的错误消息dbAdapter = new LocationDbAdapter(this);
dbAdapter.open();
错误日志:
android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:234)
android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:149)
om.example.androidtrackingapplication.LocationDbAdapter.open(LocationDbAdapter.java:78)
我已经在下面附上了完整的Logcat文件,请检查并告诉我错误的地方。
我将位置发送到适配器类,它将获取值并存储在表中。
当我获得locationupdate时,我正在调用数据库实例,当我点击时 找到Button,它将调用LocationManager以获取位置更新(这是我的应用程序崩溃的点)。
LocationDbAdapter.java
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.location.Location;
import android.util.Log;
public class LocationDbAdapter {
public static final String KEY_NAME = "name";
public static final String KEY_LATITUDE = "latitude";
public static final String KEY_LONGITUDE = "longitude";
public static final String KEY_ACCURACY = "accuracy";
public static final String KEY_TIME = "time";
public static final String KEY_ROWID = "_id";
private static final String TAG = "LocationDbAdapter";
private DatabaseHelper mDbHelper;
private SQLiteDatabase mDb;
private static final String DATABASE_CREATE =
"create table locations (_id integer primary key autoincrement, "
+ "name text not null, latitude real not null, longitude real not null, accuracy integer not null, time integer not null);";
private static final String DATABASE_NAME = "data";
private static final String DATABASE_TABLE = "locations";
private static final int DATABASE_VERSION = 4;
private final Context mCtx;
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(DATABASE_CREATE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS locations");
onCreate(db);
}
}
/**
* Constructor - takes the context to allow the database to be
* opened/created
*
* @param ctx the Context within which to work
*/
public LocationDbAdapter(Context ctx) {
this.mCtx = ctx;
}
/**
* Open the notes database. If it cannot be opened, try to create a new
* instance of the database. If it cannot be created, throw an exception to
* signal the failure
*
* @return this (self reference, allowing this to be chained in an
* initialization call)
* @throws SQLException if the database could be neither opened or created
*/
public LocationDbAdapter open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
mDbHelper.close();
}
/**
* Add new location. If the location is
* successfully created return the new rowId, otherwise return
* a -1 to indicate failure.
*
* @param location
* @return rowId or -1 if failed
*/
public long addLocation(Location location) {
Log.i(TAG, "Writing new location:"+location.toString());
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_NAME, location.getProvider());
contentValues.put(KEY_LATITUDE, location.getLatitude());
contentValues.put(KEY_LONGITUDE, location.getLongitude());
contentValues.put(KEY_ACCURACY, location.getAccuracy());
contentValues.put(KEY_TIME, location.getTime());
return mDb.insert(DATABASE_TABLE, null, contentValues);
}
public int clearDatabase() {
Log.i(TAG, "clearDatabase()");
return mDb.delete(DATABASE_TABLE, null, null);
}
public Cursor fetchAllLocations() {
return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME, KEY_LATITUDE, KEY_LONGITUDE, KEY_ACCURACY,
KEY_TIME}, null, null, null, null, null);
}
}
MainActivity.java
package com.example.androidtrackingapplication;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity
{
LocationManager mlocManager ;
LocationListener mlocListener ;
Location loc;
double lat;
double longitude;
EditText Lat;
EditText Long,battery,hitTime,intervalTime;
int level = -1;
static int i;
Button Send,Reset,Locate,Close;
private LocationDbAdapter dbAdapter;
Timer t;
protected CountDownTimer waitTimer;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Lat= (EditText) findViewById(R.id.editText1);
Long=(EditText) findViewById(R.id.editText2);
//hitTime= (EditText) findViewById(R.id.editText3);
//intervalTime=(EditText) findViewById(R.id.editText4);
Locate=(Button) findViewById(R.id.button1);
Send= (Button) findViewById(R.id.button2);
Close=(Button) findViewById(R.id.button3);
Locate.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// String hit=hitTime.getText().toString();
// int hit1= Integer.parseInt(hit);
// System.out.println("Hit"+hit1);
Send.setEnabled(false);
Lat.setText(" ");
Long.setText(" ");
/* Enable the Gps */
Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", true);
sendBroadcast(intent);
waitTimer = new CountDownTimer(60000,1000) {
public void onTick(long millisUntilFinished) {
i = i+1;
System.out.println("IN:"+i);
mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mlocListener = new MyLocationListener();
loc = mlocManager.getLastKnownLocation( LocationManager.GPS_PROVIDER);
// mlocManager.requestLocationUpdates( LocationManager.GPS_PROVIDER,300000, 0, mlocListener);
//mlocManager.requestSingleUpdate(LocationManager.GPS_PROVIDER,mlocListener, null);
mlocManager.requestSingleUpdate(LocationManager.GPS_PROVIDER,mlocListener, null);
}
public void onFinish() {
System.out.println("Location not found");
Toast.makeText(getApplicationContext(), "Location Not Found ", Toast.LENGTH_LONG).show();
if(mlocManager!=null)
{
}
Lat.setText(" ");
Long.setText(" ");
if(loc!=null)
{
Lat.setText(String.valueOf(loc.getLatitude()));
Long.setText(String.valueOf(loc.getLongitude()));
}
Toast.makeText(getApplicationContext(), "Last Location ",Toast.LENGTH_LONG).show();
Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);
}
}.start();
}
});
Send.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// String lat1="15.012345";
// String longitude1="75.012345";
HttpClient httpClient = new DefaultHttpClient();
String postURL = "";
postURL = "http://bb.trackfleet.biz/android_gps/lat_long.php?lat="+lat+"&long="+longitude;
HttpPost httpPost = new HttpPost(postURL);
HttpResponse httpResponse = null;
try
{
Toast.makeText(getApplicationContext(),"send", Toast.LENGTH_SHORT).show();
httpResponse = httpClient.execute(httpPost);
String str = inputStreamToString(httpResponse.getEntity().getContent()).toString();
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
}
catch(Exception ex)
{
Toast.makeText(getApplicationContext(),"error", Toast.LENGTH_SHORT).show();
}
}
});
Close.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(mlocManager!=null)
{
mlocManager.removeUpdates(mlocListener);
mlocManager=null;
}
Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);
finish();
}
});
}
private StringBuilder inputStreamToString(InputStream is) {
String line = "";
StringBuilder total = new StringBuilder();
// Wrap a BufferedReader around the InputStream
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
// Read response until the end
try {
while ((line = rd.readLine()) != null) {
total.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
// Return full string
return total;
}
MyLocationListener服务
public class MyLocationListener extends Service implements LocationListener
{
@Override
public void onCreate() {
dbAdapter = new LocationDbAdapter(this);
dbAdapter.open();
}
@Override
public void onLocationChanged(Location loc)
{
if(loc!=null)
{
dbAdapter = new LocationDbAdapter(this);
dbAdapter.open();
long id=dbAdapter.addLocation(loc);
Toast.makeText(getApplicationContext(), "Added Data Sucessfully " +id ,Toast.LENGTH_SHORT).show();
}
lat=loc.getLatitude();
longitude=loc.getLongitude();
waitTimer.cancel();
String Text = "My current location is: " +
"Latitud = " + loc.getLatitude() +
"Longitud = " + loc.getLongitude();
Lat.setText(String.valueOf(lat));
Long.setText(String.valueOf(longitude));
if((Lat.getText()!=null) && (Long.getText()!=null))
{
Send.setEnabled(true);
Send.performClick();
}
}
@Override
public void onProviderDisabled(String provider)
{
Toast.makeText( getApplicationContext(),"Gps Disabled Pls Enable It",Toast.LENGTH_SHORT ).show();
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
@Override
public void onProviderEnabled(String provider)
{
Toast.makeText( getApplicationContext(),"Gps Enabled",Toast.LENGTH_SHORT).show();
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
{
}
@Override
public void onDestroy()
{
super.onDestroy();
dbAdapter.close();
mlocManager.removeUpdates(this);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
}
答案 0 :(得分:0)
如果您问我的架构对于sqlite不正确,如果sqlite的'autoincrement'是您需要的功能,则必须使用:
id INTEGER PRIMARY KEY
你在那里的自动增量不应该存在。
或者自动增量不起作用。请参阅create文档
顺便说一句,如果使用INTEGERS来保存坐标,而不是浮点数/双精度等,你可以大大加快应用程序的速度。查看this answer of mine解释如何轻松使用整数。能够使用整数非常有用。 (索引,内存缓存密钥等)
更新:在sqlite2 / 3上测试过。适用于sqlite3但不适用于sqlite2:
SQL error: near "autoincrement": syntax error
因此,如果目标是sqlite3,那么你的好处就是去。