2016-04-26 9 views
0

Ich habe eine Android-App, die eine eingehende und ausgehende Anruf Methoden hat.NullPointerException auf Datenbank einfügen

Wenn ich die folgende Methode in PhonecallReceiver laufen:

db.insert("CALLINCOME", null, messageValues); 

Ich erhalte eine Ausnahme (siehe unten). Ich habe überprüft, dass die Erstellung erfolgreich ist. Warum stürzt es beim Einfügen ab? Anmerkung: Datenbank erstellt erfolgreich

Caused by: java.lang.NullPointerException 
at com.example.phamngochieu.recievercall.PhonecallReceiver.onIncomingCallStarted(PhonecallReceiver.java:59) 
at com.example.phamngochieu.recievercall.PhonecallReceiver.onCallStateChanged(PhonecallReceiver.java:90) 
at com.example.phamngochieu.recievercall.PhonecallReceiver.onReceive(PhonecallReceiver.java:48) 
at android.app.ActivityThread.handleReceiver(ActivityThread.java:2392) 

Im Folgenden sind die Codes:

public class PhonecallReceiver extends BroadcastReceiver { 
//The receiver will be recreated whenever android feels like it. We need a static variable to remember data between instantiations 
private static int lastState = TelephonyManager.CALL_STATE_IDLE; 
private static Date callStartTime; 
private static boolean isIncoming; 
private static String savedNumber; //because the passed incoming is only valid in ringing 
public static SQLiteDatabase db; 

@Override 
public void onReceive(Context context, Intent intent) { 

    //We listen to two intents. The new outgoing call only tells us of an outgoing call. We use it to get the number. 
    if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) { 
     savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER"); 
    } 
    else{ 
     String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE); 
     String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER); 
     int state = 0; 
     if(stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)){ 
      state = TelephonyManager.CALL_STATE_IDLE; 
     } 
     else if(stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){ 
      state = TelephonyManager.CALL_STATE_OFFHOOK; 
     } 
     else if(stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)){ 
      state = TelephonyManager.CALL_STATE_RINGING; 
     } 


     onCallStateChanged(context, state, number); 
    } 
} 

//Derived classes should override these to respond to specific events of interest 
protected void onIncomingCallStarted(Context ctx, String number, Date start) 
{ 
    ContentValues messageValues = new ContentValues(); 
    messageValues.put("PHONENUMBER",number); 
    messageValues.put("TIME",start.toString()); 
    Log.e(number, start.toString()); 
    db.insert("CALLINCOME", null, messageValues); 
    Log.e("gọi đến","*******"); 

} 
protected void onOutgoingCallStarted(Context ctx, String number, Date start) 
{ 
    ContentValues messageValues = new ContentValues(); 
    messageValues.put("PHONENUMBER",number); 
    messageValues.put("TIME", start.toString()); 
    Log.e(number, start.toString()); 
    db.insert("CALLOUTCOME", null, messageValues); 
    Log.e("gọi đi", "*******"); 
} 
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end){} 
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end){} 
protected void onMissedCall(Context ctx, String number, Date start){} 

//Deals with actual events 

//Incoming call- goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up 
//Outgoing call- goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up 
public void onCallStateChanged(Context context, int state, String number) { 
    if(lastState == state){ 
     //No change, debounce extras 
     return; 
    } 
    switch (state) { 
     case TelephonyManager.CALL_STATE_RINGING: 
      isIncoming = true; 
      callStartTime = new Date(); 
      savedNumber = number; 
      onIncomingCallStarted(context, number, callStartTime); 
      break; 
     case TelephonyManager.CALL_STATE_OFFHOOK: 
      //Transition of ringing->offhook are pickups of incoming calls. Nothing done on them 
      if(lastState != TelephonyManager.CALL_STATE_RINGING){ 
       isIncoming = false; 
       callStartTime = new Date(); 
       onOutgoingCallStarted(context, savedNumber, callStartTime); 
      } 
      break; 
     case TelephonyManager.CALL_STATE_IDLE: 
      //Went to idle- this is the end of a call. What type depends on previous state(s) 
      if(lastState == TelephonyManager.CALL_STATE_RINGING){ 
       //Ring but no pickup- a miss 
       onMissedCall(context, savedNumber, callStartTime); 
      } 
      else if(isIncoming){ 
       onIncomingCallEnded(context, savedNumber, callStartTime, new Date()); 
      } 
      else{ 
       onOutgoingCallEnded(context, savedNumber, callStartTime, new Date()); 
      } 
      break; 
    } 
    lastState = state; 
} 

}

und Klasse DatabaseHelper

unten
public class DatabaseHelper extends SQLiteOpenHelper { 
// tên của CSDL 
private static final String DB_NAME = "message"; 
// Version của database 
private static final int DB_VERSON =2; 
public static SQLiteDatabase db; 
public DatabaseHelper(Context context) { 
    super(context, DB_NAME, null, DB_VERSON); 
} 
public static long count; 

@Override 
public void onCreate(SQLiteDatabase db) { 
    // bảng này dùng để lưu tin nhắn đến và đi 
    this.db = db; 

    // bảng này dùng để lưu cuộc gọi đến 
    db.execSQL("CREATE TABLE CALLINCOME (" 
      + "_id INTEGER PRIMARY KEY AUTOINCREMENT, " 
      + "PHONENUMBER TEXT, " 
      + "TIME TEXT);"); 
    // bảng này lưu thông tin cuộc gọi đi 
    db.execSQL("CREATE TABLE CALLOUTCOME (" 
      + "_id INTEGER PRIMARY KEY AUTOINCREMENT, " 
      + "PHONENUMBER TEXT, " 
      + "TIME TEXT);"); 
} 

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

} 

und Manifestfile unten

<receiver 
android:name=".PhonecallReceiver" 
android:enabled="true" 
android:exported="true"> 
<intent-filter> 
    <action android:name="android.intent.action.BOOT_COMPLETED"/> 
    <action android:name="android.intent.action.QUICKBOOT_POWERON" /> 
    <action android:name="android.intent.action.PHONE_STATE" /> 
    <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> 
</intent-filter> 

+0

dort Hallo, sollten Sie Ihren Titel anders formulieren, die alles bedeuten kann! –

+0

Können Sie Ihr Protokoll posten? – vanloc

+0

Können Sie mir helfen? –

Antwort

2

Ihr db hat überall in Ihrem Code so zunächst nicht zugeordnet Sie getWriteableDatabase() eine neue DatabaseHelper Instanz zu ihm und den Anruf Punkt müssen in der Lage, die Datenbankinhalte über insert() zu ändern.

Wechsel:

db.insert("CALLINCOME", null, messageValues); 

An:

db = new DatabaseHelper(getContext()).getWriteableDatabase(); 
db.insert("CALLINCOME", null, messageValues); 
+0

vielen Dank –