Android ContentObserver从未停止过
我实现了一个 ContentObserver,它工作得很好。但现在每次 ContentObserver 收到有关 CallLog.Calls 内容提供程序中的某些更改的通知时,它都会不间断地运行 onChange() 方法。
我希望我的观察者为内容提供者中已更改的每个项目运行一次。因此,如果已将 5 个新项目添加到 CallLog.Calls 内容提供程序中,则必须通知观察者 5 次,并且对于每次通知观察者,都必须对 onChange() 方法进行新的调用。
这是我的代码。
public class RatedCalls extends ListActivity {
private static final String LOG_TAG = "RATEDCALLSOBSERVER";
private Handler handler = new Handler();
private RatedCallsContentObserver callsObserver = null;
private SQLiteDatabase db;
private Cursor cursor;
StringBuilder sb = new StringBuilder();
OpenHelper openHelper = new OpenHelper(RatedCalls.this);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getApplicationContext()
.getContentResolver()
.registerContentObserver(
android.provider.CallLog.Calls.CONTENT_URI, true,
new RatedCallsContentObserver(handler));
Log.d("FILLLIST", "calling from onCreate()");
}
class RatedCallsContentObserver extends ContentObserver {
public RatedCallsContentObserver(Handler h) {
super(h);
}
@Override
public boolean deliverSelfNotifications() {
return true;
}
@Override
public void onChange(boolean selfChange) {
Log.d(LOG_TAG, "RatedCallsContentObserver.onChange( " + selfChange
+ ")");
super.onChange(selfChange);
fillList();
}
}
private void fillList() {
cursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
android.provider.CallLog.Calls.DATE + " DESC ");
Log.d("FILLLIST", "Calling from filllist");
db = openHelper.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>();
cursor.moveToFirst();
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("contact_id", 1);
values.put("contact_name", contactName);
values.put("number_type", numType);
values.put("contact_number", contactNumber);
values.put("duration", duration);
values.put("date", callDate);
values.put("current_time", currTime);
values.put("cont", 1);
getBaseContext().getContentResolver().notifyChange(
android.provider.CallLog.Calls.CONTENT_URI,
new RatedCallsContentObserver(handler));
db.insert(CallDataHelper.TABLE_NAME, null, values);
Toast.makeText(getBaseContext(), "Inserted!", Toast.LENGTH_LONG);
callList.add("Contact Number: " + contactNumber + "\nContact Name: "
+ contactName + "\nDuration: " + duration + "\nDate: "
+ callDate);
setListAdapter(new ArrayAdapter<String>(this, R.layout.listitem,
callList));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}
});
}
}
I implemented a ContentObserver and it worked fine. But now everytime the ContentObserver is notified for some changes in the CallLog.Calls content provider, it runs the onChange() method without stopping.
I'd like that my observer runs once for each item that has changed in the content provider. So, if 5 new items have been added to the CallLog.Calls content provider, the observer must be notified 5 times, and for each notify to the observer, a new call to the onChange() method must happen.
Here is my code.
public class RatedCalls extends ListActivity {
private static final String LOG_TAG = "RATEDCALLSOBSERVER";
private Handler handler = new Handler();
private RatedCallsContentObserver callsObserver = null;
private SQLiteDatabase db;
private Cursor cursor;
StringBuilder sb = new StringBuilder();
OpenHelper openHelper = new OpenHelper(RatedCalls.this);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.getApplicationContext()
.getContentResolver()
.registerContentObserver(
android.provider.CallLog.Calls.CONTENT_URI, true,
new RatedCallsContentObserver(handler));
Log.d("FILLLIST", "calling from onCreate()");
}
class RatedCallsContentObserver extends ContentObserver {
public RatedCallsContentObserver(Handler h) {
super(h);
}
@Override
public boolean deliverSelfNotifications() {
return true;
}
@Override
public void onChange(boolean selfChange) {
Log.d(LOG_TAG, "RatedCallsContentObserver.onChange( " + selfChange
+ ")");
super.onChange(selfChange);
fillList();
}
}
private void fillList() {
cursor = getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI, null, null, null,
android.provider.CallLog.Calls.DATE + " DESC ");
Log.d("FILLLIST", "Calling from filllist");
db = openHelper.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>();
cursor.moveToFirst();
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("contact_id", 1);
values.put("contact_name", contactName);
values.put("number_type", numType);
values.put("contact_number", contactNumber);
values.put("duration", duration);
values.put("date", callDate);
values.put("current_time", currTime);
values.put("cont", 1);
getBaseContext().getContentResolver().notifyChange(
android.provider.CallLog.Calls.CONTENT_URI,
new RatedCallsContentObserver(handler));
db.insert(CallDataHelper.TABLE_NAME, null, values);
Toast.makeText(getBaseContext(), "Inserted!", Toast.LENGTH_LONG);
callList.add("Contact Number: " + contactNumber + "\nContact Name: "
+ contactName + "\nDuration: " + duration + "\nDate: "
+ callDate);
setListAdapter(new ArrayAdapter<String>(this, R.layout.listitem,
callList));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Toast.makeText(getApplicationContext(),
((TextView) view).getText(), Toast.LENGTH_SHORT).show();
}
});
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您更改了
fillList()
内部的数据库内容,因此一次又一次调用RatedCallsContentObserver.onChange()
...You change DB content inside of the
fillList()
, soRatedCallsContentObserver.onChange()
is called again and again...在此查询中包含日期检查.. android.provider.CallLog.Calls.DATE >最后一次约会
希望这对你有帮助
include a date check in this query.. android.provider.CallLog.Calls.DATE > last date
hope this will help you