0

当我单击确认按钮将配置文件详细信息保存到 sqlite 数据库时,我得到一个空指针异常并且我的应用程序关闭。我有一个读数日志,它们具有相同的基本编码结构(显然不同的列名等)并且工作得很好。我似乎无法弄清楚出了什么问题。它说错误在 ProfileDetailActivity 文件的第 90 行,但我看不到 Logdetail 活动中几乎完全相同的结构如何完美地工作!!!!任何帮助将不胜感激,因为我快把头发扯掉了!

谢谢

简介详细活动

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import michelle.glucose.contentprovider.MyLogContentProvider;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;


   /*
    * TodoDetailActivity allows to enter a new todo item 
    * or to change an existing
    */
public class ProfileDetailActivity extends Activity  {
private EditText sms;
private EditText email ;
private EditText  name;
private EditText  DOB;
public  TextView textView1;
public  TextView  textView2 ;
private Spinner type;
private Spinner units;
private Spinner Gender;

private EditText max;
private EditText min;


  private Uri progUri;
  @Override
    protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.pro_pref);


textView1 = (TextView) findViewById(R.id.textView1);
textView2 = (TextView) findViewById(R.id.textView2);

type = (Spinner) findViewById(R.id.type);
units = (Spinner) findViewById(R.id.units);
Gender = (Spinner) findViewById(R.id.Gender);
max = (EditText) findViewById(R.id.max);
min = (EditText) findViewById(R.id.min);
sms = (EditText) findViewById(R.id.sms);
email = (EditText) findViewById(R.id.Email);
DOB = (EditText) findViewById(R.id.dob);
name = (EditText) findViewById(R.id.name);



Button confirmButton = (Button) findViewById(R.id.Confirm);

Bundle extras = getIntent().getExtras();

// Check from the saved Instance
progUri = (bundle == null) ? null : (Uri) bundle
    .getParcelable(MyLogContentProvider.CONTENT_ITEM_TYPE);

// Or passed from the other activity
if (extras != null) {
  progUri = extras
      .getParcelable(MyLogContentProvider.CONTENT_ITEM_TYPE);

  fillData(progUri);
}

confirmButton.setOnClickListener(new View.OnClickListener() {
  public void onClick(View view) {
    if (TextUtils.isEmpty(DOB.getText().toString())) { SAYS ERROR HERE???
      makeToast();
    } else {
      setResult(RESULT_OK);
      finish();
    }
  }

   });


   }

  public void fillData(Uri uri) {
    String[] projection =              {ProTable.COLUMN_NAME,ProTable.COLUMN_DOB,
   ProTable.COLUMN_GENDER,ProTable.COLUMN_UNIT,                   ProTable.COLUMN_MIN,ProTable.COLUMN_MAX,                                         
            ProTable.COLUMN_TYPE, ProTable.COLUMN_EMAIL,ProTable.COLUMN_NUMBER,
        ProTable.COLUMN_ID };
Cursor cursor = getContentResolver().query(uri, projection, null, null,
    null);
if (cursor != null) {
  cursor.moveToFirst();
  String idstr = cursor.getString(cursor.getColumnIndexOrThrow(ProTable.COLUMN_ID));

  String u = cursor.getString(cursor
      .getColumnIndexOrThrow(ProTable.COLUMN_UNIT));

  for (int i = 0; i < units.getCount(); i++) {

    String s = (String) units.getItemAtPosition(i);
    if (s.equalsIgnoreCase(u))
      units.setSelection(i);
    }


String g = cursor.getString(cursor.getColumnIndexOrThrow(ProTable.COLUMN_GENDER));
  for (int i = 0; i < Gender.getCount(); i++) {

    String s = (String) Gender.getItemAtPosition(i);
    if (s.equalsIgnoreCase(g)) {
      Gender.setSelection(i);
    }
  }



  String t = cursor.getString(cursor.getColumnIndexOrThrow(ProTable.COLUMN_TYPE));
  for (int i = 0; i < type.getCount(); i++) {

    String s = (String) type.getItemAtPosition(i);
    if (s.equalsIgnoreCase(t)) {
      type.setSelection(i);
    }
  }  


  name.setText(cursor.getString(cursor
      .getColumnIndexOrThrow(ProTable.COLUMN_NAME)));
  DOB.setText(cursor.getString(cursor
      .getColumnIndexOrThrow(ProTable.COLUMN_DOB)));
  min.setText(cursor.getString(cursor
          .getColumnIndexOrThrow(ProTable.COLUMN_MIN)));
      max.setText(cursor.getString(cursor
          .getColumnIndexOrThrow(ProTable.COLUMN_MAX)));
      email.setText(cursor.getString(cursor
              .getColumnIndexOrThrow(ProTable.COLUMN_EMAIL)));
          sms.setText(cursor.getString(cursor
              .getColumnIndexOrThrow(ProTable.COLUMN_NUMBER)));

  // Always close the cursor
  cursor.close();}
}


   protected void onSaveInstanceState(Bundle outState) {
   super.onSaveInstanceState(outState);
   saveState();
    outState.putParcelable(MyLogContentProvider.CONTENT_ITEM_TYPE, progUri);
    }

       @Override
   protected void onPause() {
      super.onPause();
saveState();
     }

     private void saveState() {



  String t = (String) type.getSelectedItem();
  String u = (String) units.getSelectedItem();
String g = (String) Gender.getSelectedItem();
String n = name.getText().toString();
String d = DOB.getText().toString();
String mi = min.getText().toString();
String ma = max.getText().toString();
String e = email.getText().toString();
String s = sms.getText().toString();
// Only save if either summary or description
// is available

if (d.length() ==0) {
  return;
}


ContentValues values = new ContentValues();

values.put(ProTable.COLUMN_NAME, n);
values.put(ProTable.COLUMN_DOB, d);
values.put(ProTable.COLUMN_GENDER, g);
values.put(ProTable.COLUMN_UNIT, u);
values.put(ProTable.COLUMN_TYPE, t);
values.put(ProTable.COLUMN_MIN, mi);
values.put(ProTable.COLUMN_MAX, ma);
values.put(ProTable.COLUMN_EMAIL, e);
values.put(ProTable.COLUMN_NUMBER, s);
if (progUri == null) {
  // New log
  progUri = getContentResolver().insert(MyLogContentProvider.CONTENT_URI, values);
} else {
  // Update log
  getContentResolver().update(progUri, values, null, null);
}
  }

 private void makeToast() {
Toast.makeText(ProfileDetailActivity.this, "Please maintain a glucose log",
    Toast.LENGTH_LONG).show();
  }

数据库内容提供者

  import java.util.Arrays;
 import java.util.HashSet;


   import michelle.glucose.ProTable;
  import michelle.glucose.ProfileDatabaseHelper;

  import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
  import android.database.Cursor;
   import android.database.sqlite.SQLiteDatabase;
  import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;


public class MyProfileContentProvider extends ContentProvider {

    // database
    private ProfileDatabaseHelper database;

  // Used for the UriMacher
  private static final int PRO = 10;
  private static final int PROD = 20;


     private static final String AUTHORITY =                   
    "michelle.glucose.contentprovider.MyProfileContentProvider";

   private static final String BASE_PATH = "pros";
     public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
  + "/" + BASE_PATH);

  public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
  + "/pros";
 public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
  + "/pro";

  private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
 static {
  sURIMatcher.addURI(AUTHORITY, BASE_PATH, PRO);
   sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", PROD);
  }

 @Override
public boolean onCreate() {
   database = new ProfileDatabaseHelper(getContext());
return false;
   }

  @Override
  public Cursor query(Uri uri, String[] projection, String selection,
  String[] selectionArgs, String sortOrder) {

// Uisng SQLiteQueryBuilder instead of query() method
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();

// Check if the caller has requested a column which does not exists
checkColumns(projection);

// Set the table
queryBuilder.setTables(ProTable.TABLE_PRO);

int uriType = sURIMatcher.match(uri);
switch (uriType) {
case PRO:
  break;
case PROD:
  // Adding the ID to the original query
  queryBuilder.appendWhere(ProTable.COLUMN_ID + "="
      + uri.getLastPathSegment());
  break;
default:
  throw new IllegalArgumentException("Unknown URI: " + uri);
}

SQLiteDatabase db = database.getWritableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection,
    selectionArgs, null, null, sortOrder);
// Make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(), uri);

return cursor;
   }

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

    @Override
  public Uri insert(Uri uri, ContentValues values) {
  int uriType = sURIMatcher.match(uri);
  SQLiteDatabase sqlDB = database.getWritableDatabase();
   int rowsDeleted = 0;
   long id = 0;
  switch (uriType) {
   case PRO:
    id = sqlDB.insert(ProTable.TABLE_PRO, null, values);
    break;
default:
  throw new IllegalArgumentException("Unknown URI: " + uri);
   }
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH + "/" + id);
  }

    @Override
 public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsDeleted = 0;
switch (uriType) {
case PRO:
  rowsDeleted = sqlDB.delete(ProTable.TABLE_PRO, selection,
      selectionArgs);
  break;
case PROD:
  String id = uri.getLastPathSegment();
  if (TextUtils.isEmpty(selection)) {
    rowsDeleted = sqlDB.delete(ProTable.TABLE_PRO,
        ProTable.COLUMN_ID + "=" + id, 
        null);
  } else {
    rowsDeleted = sqlDB.delete(ProTable.TABLE_PRO,
        ProTable.COLUMN_ID + "=" + id 
        + " and " + selection,
        selectionArgs);
  }
  break;
default:
  throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
 }

  @Override
  public int update(Uri uri, ContentValues values, String selection,
  String[] selectionArgs) {

int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsUpdated = 0;
switch (uriType) {
case PRO:
  rowsUpdated = sqlDB.update(ProTable.TABLE_PRO, 
      values, 
      selection,
      selectionArgs);
  break;
case PROD:
  String id = uri.getLastPathSegment();
  if (TextUtils.isEmpty(selection)) {
    rowsUpdated = sqlDB.update(ProTable.TABLE_PRO, 
        values,
        ProTable.COLUMN_ID + "=" + id, 
        null);
  } else {
    rowsUpdated = sqlDB.update(ProTable.TABLE_PRO, 
        values,
        ProTable.COLUMN_ID + "=" + id 
        + " and " 
        + selection,
        selectionArgs);
  }
  break;
default:
  throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
  }

     private void checkColumns(String[] projection) {
       String[] available = {ProTable.COLUMN_NAME,ProTable.COLUMN_DOB,
       ProTable.COLUMN_GENDER,ProTable.COLUMN_TYPE,ProTable.COLUMN_MIN,                          

        ProTable.COLUMN_MAX,ProTable.COLUMN_UNIT,

      ProTable.COLUMN_NUMBER,
                    ProTable.COLUMN_EMAIL,
    ProTable.COLUMN_ID };
     if (projection != null) {
    HashSet<String> requestedColumns = new HashSet<String>(Arrays.asList(projection));
    HashSet<String> availableColumns = new HashSet<String>(Arrays.asList(available));
    // Check if all columns which are requested are available
       if (!availableColumns.containsAll(requestedColumns)) {
    throw new IllegalArgumentException("Unknown columns in projection");
       }
    }
     }

    } 

配置文件表

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

 public class ProTable {
 private static final String DATABASE_NAME = "protable.db";                               
  private static final int DATABASE_VERSION = 1;
private ProfileDatabaseHelper psqLiteHelper;
private SQLiteDatabase pdb; 
private Context context;
   // Database table
 public static final String TABLE_PRO = "pro";
 public static final String COLUMN_ID = "_id";
  public static final String COLUMN_NAME = "name";
  public static final String COLUMN_DOB = "dob";
 public static final String COLUMN_GENDER = "gender";
 public static final String COLUMN_TYPE = "type";
 public static final String COLUMN_GLU = "glu";
 public static final String COLUMN_MIN = "min";
 public static final String COLUMN_MAX = "max";
 public static final String COLUMN_EMAIL = "email";
 public static final String COLUMN_UNIT = "unit";
 public static final String COLUMN_NUMBER = "number";

 // Database creation SQL statement
  private static final




   String DATABASE_CREATE = "create table " 
  + TABLE_PRO
  + "(" 
  + COLUMN_ID + " integer primary key autoincrement, " 
  + COLUMN_NAME + " text not null, " 
  + COLUMN_DOB + " text not null," 
  + COLUMN_GENDER + " text not null,"
  + COLUMN_TYPE + " text not null,"
  + COLUMN_MIN + " text not null,"
  + COLUMN_MAX + " text not null,"
  + "COLUMN_UNIT" + "text not null,"
   + COLUMN_EMAIL + " text not null,"
  + COLUMN_NUMBER + " text not null"
   + ");";




   public ProTable(Context ctx) {
    this.context = ctx;
    psqLiteHelper = new ProfileDatabaseHelper(context);
}

public ProTable openToRead() throws android.database.SQLException {
        psqLiteHelper = new ProfileDatabaseHelper(context, DATABASE_NAME, null,
                DATABASE_VERSION);
        pdb = psqLiteHelper.getReadableDatabase();
        return this; }

  public Cursor getEmail (String email) throws android.database.SQLException{
        Cursor mCursor 
      = pdb.query(TABLE_PRO, new String[] {COLUMN_ID,   COLUMN_EMAIL },                    

      COLUMN_EMAIL + "=" + email ,  null, null, null, null, null);
  if (mCursor != null ){
      mCursor.moveToFirst();
  }
   return mCursor;

  }


  public String getSMS () throws android.database.SQLException{
      Cursor mCursor 
      = pdb.query(TABLE_PRO, new String[] {COLUMN_ID,   COLUMN_NUMBER }, 

      COLUMN_NUMBER + "=" + COLUMN_NUMBER,  null, null, null, null, null);
  if (mCursor != null ){
      mCursor.moveToFirst();

  }String number =mCursor.getString(mCursor.getColumnIndexOrThrow(COLUMN_NUMBER));

 return number;

  } 







 public static void onCreate(SQLiteDatabase database) {
   database.execSQL(DATABASE_CREATE);
  }

  public static void onUpgrade(SQLiteDatabase database, int oldVersion,
  int newVersion) {
   Log.w(ProTable.class.getName(), "Upgrading database from version "
    + oldVersion + " to " + newVersion
    + ", which will destroy all old data");
   database.execSQL("DROP TABLE IF EXISTS " + TABLE_PRO);
    onCreate(database);
   }
   }

数据库助手类

   import android.content.Context;
   import android.database.sqlite.SQLiteDatabase;
   import android.database.sqlite.SQLiteDatabase.CursorFactory;
   import android.database.sqlite.SQLiteOpenHelper;

   public class ProfileDatabaseHelper extends SQLiteOpenHelper {

     private static final String DATABASE_NAME = "protable.db";
    private static final int DATABASE_VERSION = 1;

   public ProfileDatabaseHelper(Context context) {
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
      }

    public ProfileDatabaseHelper(Context context, String databaseName,
      CursorFactory factory, int databaseVersion) {
  super(context, databaseName , factory, databaseVersion);
      }

     public ProfileDatabaseHelper(Context context, String databaseName,
    Object factory, int databaseVersion) {
super(context, DATABASE_NAME, null,  DATABASE_VERSION);
      }

     // Method is called during creation of the database
      @Override
     public void onCreate(SQLiteDatabase database) {
       ProTable.onCreate(database);
      }

    // Method is called during an upgrade of the database,
    // e.g. if you increase the database version
     @Override
   public void onUpgrade(SQLiteDatabase database, int oldVersion,
     int newVersion) {
    ProTable.onUpgrade(database, oldVersion, newVersion);
    }
   } 

LOGCAT

 E/AndroidRuntime(3797):FATAL EXCEPTION: main
 E/AndroidRuntime(3797): java.lang.NullPointerException
  E/AndroidRuntime(3797):at                       michelle.glucose.ProfileDetailActivity$1.onClick(ProfileDetailActivity.java:90)
        E/AndroidRuntime(3797):at android.view.View.performClick(View.java:4204)
 E/AndroidRuntime(3797):at android.view.View$PerformClick.run(View.java:17355)
 E/AndroidRuntime(3797):at android.os.Handler.handleCallback(Handler.java:725)
 E/AndroidRuntime(3797): at android.os.Handler.dispatchMessage(Handler.java:92)
 E/AndroidRuntime(3797): at android.os.Looper.loop(Looper.java:137)
E/AndroidRuntime(3797): at android.app.ActivityThread.main(ActivityThread.java:5041)
 E/AndroidRuntime(3797): at java.lang.reflect.Method.invokeNative(Native Method)
 E/AndroidRuntime(3797): at java.lang.reflect.Method.invoke(Method.java:511)
 E/AndroidRuntime(3797): at
 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
E/AndroidRuntime(3797): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
E/AndroidRuntime(3797): at dalvik.system.NativeStart.main(Native Method)
4

1 回答 1

0

老实说,nullpointerexception 是更容易解决的错误之一,而且它几乎总是您自己代码中的错误。转到引发 nullpointerexception 的代码行并考虑可能导致这种情况的原因。我不知道您的源代码中的第 90 行是什么,但例如,如果它是以下代码行:

DOB.getText().toString()

那么要么 DOB 为空,要么 DOB.getText() 为空。如果您无法确定哪个,则打印出该代码行之前的值。然后考虑什么可能导致空指针,或者通过代码回溯到 DOB 被(未)初始化或它的“文本”属性被(未)设置的位置。

于 2013-04-24T00:22:15.067 回答