在android数据库中插入呼叫日志

在android数据库中插入呼叫日志,android,logging,contentobserver,Android,Logging,Contentobserver,我想实现一个程序,在每次通话或发送短信时在数据库中插入详细信息。我应该使用广播接收器、内容观察者或服务吗?什么是合适的?我是android新手,急需这方面的帮助 我现在已经完成了以下代码正常运行。问题是当代码第一次运行时,例如调用日志有8条记录,所以这8条记录被插入数据库。然后,若在调用日志中进行了任何更改(例如,我进行了另一次调用),则数据库中将显示17条记录,而不是9条记录。请帮帮我,我哪里做错了 package com.calllogdb; import java.text.Da

我想实现一个程序,在每次通话或发送短信时在数据库中插入详细信息。我应该使用广播接收器、内容观察者或服务吗?什么是合适的?我是android新手,急需这方面的帮助

我现在已经完成了以下代码正常运行。问题是当代码第一次运行时,例如调用日志有8条记录,所以这8条记录被插入数据库。然后,若在调用日志中进行了任何更改(例如,我进行了另一次调用),则数据库中将显示17条记录,而不是9条记录。请帮帮我,我哪里做错了

    package com.calllogdb;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;




import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.ContentValues;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;

//import static android.provider.BaseColumns._ID;
import static com.calllogdb.Constants.KEY_ContactNum ;
import static com.calllogdb.Constants.KEY_ContactName;
import static com.calllogdb.Constants.KEY_Duration;
import static com.calllogdb.Constants.KEY_Date ;
import static com.calllogdb.Constants.KEY_NumType ;
import static com.calllogdb.Constants.KEY_CurrTime ;
import static com.calllogdb.Constants.TABLE_NAME;

public class MainActivity extends Activity {

    private Helper helper = new Helper(this);

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
          this.getApplicationContext()
            .getContentResolver()
            .registerContentObserver(
                    android.provider.CallLog.Calls.CONTENT_URI, true,
                    new CallLogObserver(new Handler())); 



        try {

            addLog();
        }
    finally {

        helper.close();
    } 
    }

    private void addLog() {


        // TODO Auto-generated method stub
        SQLiteDatabase db;

         Cursor cursor = getContentResolver().query(
                    android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
                    android.provider.CallLog.Calls.DATE + " DESC ");

    db = helper.getWritableDatabase();


    startManagingCursor(cursor);
    int numberColumnId = cursor.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
    int durationId = cursor.getColumnIndex(android.provider.CallLog.Calls.DURATION);
    int contactNameId = cursor.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME);
    int dateId = cursor.getColumnIndex(android.provider.CallLog.Calls.DATE);
   int numTypeId = cursor.getColumnIndex(android.provider.CallLog.Calls.CACHED_NUMBER_TYPE);

    Date dt = new Date();
    int hours = dt.getHours();
    int minutes = dt.getMinutes();
    int seconds = dt.getSeconds();
    String currTime = hours + ":" + minutes + ":" + seconds;



    ArrayList<String> callList = new ArrayList<String>();
    if (cursor.moveToFirst()) {
        do {
            String contactNumber = cursor.getString(numberColumnId);
            String contactName = cursor.getString(contactNameId);
            String duration = cursor.getString(durationId);
            String callDate = DateFormat.getDateInstance().format(dateId);
           String numType = cursor.getString(numTypeId);

            ContentValues values = new ContentValues();
            values.put(KEY_ContactName, contactName);
       values.put(KEY_NumType, numType);
            values.put(KEY_ContactNum, contactNumber);
            values.put(KEY_Duration, duration);
            values.put(KEY_Date, callDate);
            values.put(KEY_CurrTime, currTime);

            db.insert(TABLE_NAME, null, values);


            callList.add("Contact Number: " + contactNumber
                    + "\nContact Name: " + contactName + "\nDuration: "
                    + duration + "\nDate: " + callDate);


        } while (cursor.moveToNext());
}
    Toast.makeText(getBaseContext(), "Inserted!", Toast.LENGTH_LONG).show();


    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }




    public class CallLogObserver extends ContentObserver
    {



        public CallLogObserver(Handler handler) {
            super(handler);
            // TODO Auto-generated constructor stub
        }


          @Override
            public boolean deliverSelfNotifications() {
                return true;
            }

            @Override
            public void onChange(boolean selfChange) {
                Log.d("LOG_TAG", "MyContentObserver.onChange( " + selfChange
                        + ")");
                super.onChange(selfChange);
                addLog();

            }





    }
}
package com.calllogdb;
导入java.text.DateFormat;
导入java.util.ArrayList;
导入java.util.Date;
导入android.os.Bundle;
导入android.os.Handler;
导入android.app.Activity;
导入android.content.ContentValues;
导入android.database.ContentObserver;
导入android.database.Cursor;
导入android.database.sqlite.SQLiteDatabase;
导入android.util.Log;
导入android.view.Menu;
导入android.widget.Toast;
//导入静态android.provider.BaseColumns.\u ID;
导入静态com.calllogdb.Constants.KEY\u ContactNum;
导入静态com.calllogdb.Constants.KEY\u ContactName;
导入静态com.calllogdb.Constants.KEY_Duration;
导入静态com.calllogdb.Constants.KEY\u日期;
导入静态com.calllogdb.Constants.KEY\u NumType;
导入静态com.calllogdb.Constants.KEY\u CurrTime;
导入静态com.calllogdb.Constants.TABLE_NAME;
公共类MainActivity扩展了活动{
私人帮手=新帮手(此);
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
此文件名为.getApplicationContext()
.getContentResolver()
.registerContentObserver(
android.provider.CallLog.Calls.CONTENT_URI,true,
新的CallLogObserver(newhandler());
试一试{
addLog();
}
最后{
helper.close();
} 
}
私有void addLog(){
//TODO自动生成的方法存根
sqlitedb数据库;
Cursor Cursor=getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI,null,null,null,
android.provider.CallLog.Calls.DATE+“DESC”);
db=helper.getWritableDatabase();
开始管理游标(游标);
int numberColumnId=cursor.getColumnIndex(android.provider.CallLog.Calls.NUMBER);
int durationId=cursor.getColumnIndex(android.provider.CallLog.Calls.DURATION);
int contactNameId=cursor.getColumnIndex(android.provider.CallLog.Calls.CACHED\u NAME);
int dateId=cursor.getColumnIndex(android.provider.CallLog.Calls.DATE);
int numTypeId=cursor.getColumnIndex(android.provider.CallLog.Calls.CACHED\u NUMBER\u TYPE);
日期dt=新日期();
int hours=dt.getHours();
int minutes=dt.getMinutes();
int seconds=dt.getSeconds();
字符串currTime=hours+“:”+minutes+“:”+seconds;
ArrayList callList=新的ArrayList();
if(cursor.moveToFirst()){
做{
String contactNumber=cursor.getString(numberColumnId);
String contactName=cursor.getString(contactNameId);
String duration=cursor.getString(durationId);
字符串callDate=DateFormat.getDateInstance().format(日期ID);
String numType=cursor.getString(numTypeId);
ContentValues=新的ContentValues();
值。输入(键\u ContactName,ContactName);
value.put(KEY\u NumType,NumType);
值。输入(键\u ContactNum,contactNumber);
值。put(键持续时间,持续时间);
value.put(KEY_Date,callDate);
value.put(KEY\u CurrTime,CurrTime);
db.insert(表名称,空,值);
添加(“联系人号码:”+联系人号码
+\n联系人名称:“+contactName+”\n联系人:
+持续时间+“\n日期:”+callDate);
}while(cursor.moveToNext());
}
Toast.makeText(getBaseContext(),“Inserted!”,Toast.LENGTH_LONG.show();
}
@凌驾
公共布尔onCreateOptions菜单(菜单){
//为菜单充气;这会将项目添加到操作栏(如果存在)。
getMenuInflater().充气(R.menu.activity\u主菜单);
返回true;
}
公共类CallLogoObserver扩展了ContentObserver
{
公共CallLogObserver(处理程序){
超级(处理器);
//TODO自动生成的构造函数存根
}
@凌驾
公共布尔传递函数deliverSelfNotifications(){
返回true;
}
@凌驾
公共void onChange(布尔自更改){
Log.d(“Log_标记”、“MyContentObserver.onChange”(“+selfChange
+ ")");
super.onChange(selfChange);
addLog();
}
}
}
无论何时我打电话,它都会收到通知并插入整套记录,而不是只插入最新的记录。我应该如何防止这种情况?
谢谢

您可能再次将整个通话记录插入数据库。您可以使用content observer或广播侦听器来了解是否进行了呼叫,但您需要保留上次读取完整的呼叫日志数据库的时间,并且只插入在该时间之后进行的呼叫

如果使用contentobserver,则该观察者需要位于服务中。在onCreate()中注册观察者。您将在contentObserver的onChange中使用contentProvider。您需要在上次使用共享首选项读取数据库时保持时间。注意在共享首选项中存储的时间之后条目的更改。现在将共享首选项的时间更新为当前时间。同时在onDestroy()中注销content observer。

您能给出