android SqlLite 报错 SQLiteOpenHelper.getDatabaseLocked - SQLiteOpenHelper.getReadableDatabase

文章标签: android
2014-12-11 16:17:09     人阅读    

今天在android中操作数据库报错,我的logcat 错误日志如下,空指针异常
java.lang.NullPointerException
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224);
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:188);
at package.SQLiteAdapter.openToRead(SQLiteAdapter.java:52);
at package.SMSStateReceiver.cercaNumeroSQLite(SMSStateReceiver.java:99);



我调试了好长时间,知道错误的原因是构造函数中 上线文 context为空,我android开发经验太少了,试验过好多次,用过好多方法,就是不能解决这个问题。

我的SQLiteAdapter 如下,包含了 content1 和 phone_number 两个字符串变量

public class SQLiteAdapter {

 public static final String MYDATABASE_NAME = "MY_DATABASE";
 
 public static final String MYDATABASE_TABLE = "MY_TABLE";
 
 public static final int MYDATABASE_VERSION = 1;
 
 public static final String KEY_ID = "_id";
 
 public static final String KEY_CONTENT1 = "Content1";
 
 public static final String KEY_CONTENT2 = "Content2";



 private String[] STUDENT_TABLE_COLUMNS = { KEY_ID, KEY_CONTENT1, KEY_CONTENT2 };



 //create table MY_DATABASE (ID integer primary key, Content text not null);
 
 private static final String SCRIPT_CREATE_DATABASE =
 
  "create table " + MYDATABASE_TABLE + " ("
 
  + KEY_ID + " integer primary key autoincrement, "
 
  + KEY_CONTENT1 + " text not null, "
 
  + KEY_CONTENT2 + " text not null);";



 private SQLiteHelper sqLiteHelper;
 
 private SQLiteDatabase sqLiteDatabase;



 private Context context;



 private SMSStateReceiver sms;



 public SQLiteAdapter(Context c){
 
  context = c;
 
 }




public SQLiteAdapter(SMSStateReceiver smsStateReceiver) {
 
}




public SQLiteAdapter openToRead() throws android.database.SQLException {
 
  sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null, MYDATABASE_VERSION);
 
  sqLiteDatabase = sqLiteHelper.getReadableDatabase();
 
  return this;
 
 }



 public SQLiteAdapter openToWrite() throws android.database.SQLException {
 
  sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null, MYDATABASE_VERSION);
 
  sqLiteDatabase = sqLiteHelper.getWritableDatabase();
 
  return this;
 
 }



 public void close(){
 
  sqLiteHelper.close();
 
 }



 public long insert(String content1, String content2){



  ContentValues contentValues = new ContentValues();
 
  contentValues.put(KEY_CONTENT1, content1);
 
  contentValues.put(KEY_CONTENT2, content2);
 
  return sqLiteDatabase.insert(MYDATABASE_TABLE, null, contentValues);
 
 }



 public int deleteAll(){
 
  return sqLiteDatabase.delete(MYDATABASE_TABLE, null, null);
 
 }



 public void delete_byID(int id){
 
  sqLiteDatabase.delete(MYDATABASE_TABLE, KEY_ID+"="+id, null);
 
 }



 public void update_byID(int id, String v1, String v2){
 
  ContentValues values = new ContentValues();
 
  values.put(KEY_CONTENT1, v1);
 
  values.put(KEY_CONTENT2, v2);
 
  sqLiteDatabase.update(MYDATABASE_TABLE, values, KEY_ID+"="+id, null);
 
 }



 public Cursor queueAll(){
 
  String[] columns = new String[]{KEY_ID, KEY_CONTENT1, KEY_CONTENT2};
 
  Cursor cursor = sqLiteDatabase.query(MYDATABASE_TABLE, columns,
 
    null, null, null, null, null);



  return cursor;
 
 }




    public List getAllNumeri() {
 
        List students = new ArrayList();



        Cursor cursor = sqLiteDatabase.query(MYDATABASE_TABLE, STUDENT_TABLE_COLUMNS, null, null, null, null, null);



        cursor.moveToFirst();
 
        while (!cursor.isAfterLast()) {
 
            Persona student = parseStudent(cursor);
 
            students.add(student);
 
            cursor.moveToNext();
 
        }



        cursor.close();
 
        return students;
 
    }
 
    private Persona parseStudent(Cursor cursor) {
 
        Persona student = new Persona();
 
        student.setName(cursor.getString(2));
 
        return student;
 
    }   



 public class SQLiteHelper extends SQLiteOpenHelper {



  public SQLiteHelper(Context context, String name,
 
    CursorFactory factory, int version) {
 
   super(context, name, factory, version);
 
  }



  @Override
 
  public void onCreate(SQLiteDatabase db) {
 
   // TODO Auto-generated method stub
 
   db.execSQL(SCRIPT_CREATE_DATABASE);
 
  }



  @Override
 
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
 
   // TODO Auto-generated method stub



  }



    public List getAllStudents() {
 
        List students = new ArrayList();



        Cursor cursor = sqLiteDatabase.query(MYDATABASE_TABLE, STUDENT_TABLE_COLUMNS, null, null, null, null, null);



        cursor.moveToFirst();
 
        while (!cursor.isAfterLast()) {
 
            Persona student = parseStudent(cursor);
 
            students.add(student);
 
            cursor.moveToNext();
 
        }



        cursor.close();
 
        return students;
 
    }



    private Persona parseStudent(Cursor cursor) {
 
        Persona student = new Persona();
 
        student.setId((cursor.getInt(0)));
 
        student.setName(cursor.getString(1));
 
        return student;
 
    }    



 }



}
}


我同样有一个 SMSStateReceiver 类,在该类中会通过数据库对比接受的sms数字

public class SMSStateReceiver extends BroadcastReceiver 
{
{



     private SQLiteAdapter mySQLiteAdapter;
 
     Cursor c;
 
     CallFilterService cfs;



    public void onReceive(Context context, Intent intent) 
 
    { 
 
        String MSG_TYPE=intent.getAction();




         if(MSG_TYPE.equals("android.provider.Telephony.SMS_RECEIVED"))
 
        {
 
             Toast toast;
 
             Toast toast = Toast.makeText(context,"SMS Received: "+MSG_TYPE , Toast.LENGTH_LONG);
 
             toast.show();



            Bundle bundle = intent.getExtras();
 
            Object messages[] = (Object[]) bundle.get("pdus");
 
            SmsMessage smsMessage[] = new SmsMessage[messages.length];
 
            for (int n = 0; n < messages.length; n++) 
 
            {
 
                smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
 
            }



              final SharedPreferences mpref=context.getSharedPreferences("BLOCK",context.MODE_PRIVATE);
 
              String str=mpref.getString("phonesms","Phone");
 
              Log.e("phone no==",""+smsMessage[0].getOriginatingAddress());



              boolean value = cercaNumeroSQLite(smsMessage[0].getOriginatingAddress().toString());



              if(str.contains("Phone") && (value == true))    
 
              {
 
                    toast = Toast.makeText(context,"BLOCKED Received SMS from: " +smsMessage[0].getOriginatingAddress(), 5000);
 
                    toast.show();
 
                    abortBroadcast();
 
              }




        }
 
        else if(MSG_TYPE.equals("android.provider.Telephony.SEND_SMS"))
 
        {



        }
 
        else
 
        {



            Toast toast = Toast.makeText(context,"SIN ELSE: "+MSG_TYPE , Toast.LENGTH_LONG);
 
            toast.show();
 
            abortBroadcast();
 
            for(int i=0;i<8;i++)
 
            {
 
                System.out.println("Blocking SMS **********************");
 
            }



        }



    }



    public boolean cercaNumeroSQLite(String phone) {
 
        mySQLiteAdapter = new SQLiteAdapter(this);
 
        mySQLiteAdapter.openToRead();



        System.out.println("num tel - " + phone);



        List numeri = mySQLiteAdapter.getAllNumeri();
 
        String num = numeri.toString();



        boolean trovato = false;



        if(numeri.size() >= 1) {
 
            List<String> numeriTel = new ArrayList<String>();  
 
            numeriTel = mySQLiteAdapter.getAllNumeri();
 
            for (int i = 0; i < numeri.size(); i++) {
 
                Persona numero = (Persona) numeri.get(i);
 
                if(PhoneNumberUtils.compare(numero.toString(), phone)){
 
                     trovato = true;
 
                     mySQLiteAdapter.close();
 
                } else {



                }
 
            }
 
        } else {
 
            mySQLiteAdapter.close();
 
        }



            return trovato;
 
        }



 }


现在一直是空指针异常

处理方法

之所以出现空指针异常,是因为你的SQLiteAdapter  中上线文 context变量没有初始化的原因,你有2个构造函数,但是只有其中一个初始化了那个变量。另外一个没有初始化

你传递了一个空 Context到 SQLiteOpenHelper 的构造函数引发了这个问题,当 e.g. getWritableDatabase(). 调用的时候就会报错

public SQLiteAdapter(SMSStateReceiver smsStateReceiver) {
 
    // TODO Auto-generated constructor stub
}
}


这里改变
mySQLiteAdapter = new SQLiteAdapter(this);


改成这样
mySQLiteAdapter = new SQLiteAdapter(context);

 


原文地址:http://www.itmmd.com/201412/302.html
该文章由 萌萌的IT人 整理发布,转载须标明出处。

ActionBar 在特定的Fragment区域中显示数据(ActionBar display a item in an specific Fragment?)   上一篇
下一篇  如何在捕获用户滚动viewpager滚动条的事件
精彩回复
我要追加问题,请求站长解决!
姓名:       

《程序员app》专门为程序员量身定做!