我正在使用内容观察员content://sms.我正在将所有消息写入SD卡中的文本文件.但是onChange()内容观察器中的方法被多次调用,并且相同的消息被多次写入文本文件.怎么避免这个?另外我想知道内容观察者是否会放慢手机的速度.
我真的不明白为什么内容观察者会听取与联系信息无关的更改.
我只是注册了我想听的变化的URI:
getContentResolver().registerContentObserver(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, true, contactsObserver);
Run Code Online (Sandbox Code Playgroud)
但是在给某人打电话或发短信后,它会在ContentObserver中触发并调用onChange方法.所以我需要将所有联系人列表与我的应用程序重新同步,尽管我不需要这样做.
只有我感兴趣的领域:
我应该实现哪些更改来监听此数据库项目的更改?
我知道你很想把它标记为重复但等等,让我再次通过我的详细(但失败)尝试再次讨论这个问题.
策略1:算法: 答案
第一次触发onChange时,更新行的id
下次再次触发onChange时,会更新行的id
匹配id
忽略相同的id
这种方法的问题在于它很容易受到竞争条件的影响.如果在获得更新行的id时,onChange 第二次触发,则此算法失败.这源于我在慢速机器或以峰值容量工作的机器上进行测试时的个人经验.
策略2:算法:答案
覆盖deliverSelfNotifications()以返回true.
这看起来很有希望,但没有奏效.我用来参考的代码:
在主要活动:OnCreate方法我注册:
getContentResolver().registerContentObserver(Uri.parse("content://sms"), true, new CtObserver(new Handler()));
Run Code Online (Sandbox Code Playgroud)
然后在一个单独的类中:
package com.example.testproject;
import android.database.ContentObserver;
import android.os.Handler;
import android.util.Log;
/**
* @author Time Traveller
*/
public class CtObserver extends ContentObserver {
public CtObserver(Handler handler) {
super(handler);
}
public boolean deliverSelfNotifications(){
return true;
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Log.e("onChange","Fired");
}
}
Run Code Online (Sandbox Code Playgroud)
为什么您应该为此答案做出贡献:
Quering SMS content Provider是非默认应用程序捕获已发送SMS事件的唯一方法.但到目前为止,我还没有找到任何令人信服的完整功能的答案.所以我们真的需要对此有所了解!! …
sms android onchange android-contentprovider contentobserver
我正在开发一个Android应用程序,并第一次与内容观察者合作.所以我阅读了很多教程并得到了为什么提供它以及如何使用它的概念.
现在我已经在博客上阅读了这些内容
别忘了取消注册内容观察者
所以,我无法理解我是否要注册ContentObserver然后我必须取消注册的情况.
如果观察者的目的得到满足,那么它可以取消注册.但我必须观察直到用户卸载应用程序,然后我将取消注册观察者.
这是该博客的网址
http://www.grokkingandroid.com/use-contentobserver-to-listen-to-changes/
我要求跟踪在设备上创建的.jpg类型的新图像文件.我一直在使用这样做ContentObserver在MediaStore使用下面的类MediaStoreObserver,并且注册了相同的我的服务之一.
我注意到,onChange()为单个文件创建多次调用该方法.我知道创建的媒体文件会在许多表中更新,MediaStore因此onChange()会被多次调用.
我的问题:如何注册MediaStore仅用于图像文件创建/编辑操作?
- 提前谢谢,Manju
private class MediaStoreObserver extends ContentObserver {
public MediaStoreObserver() {
super(null);
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
//check image file changes in MediaStore
readFromMediaStore(_context,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
}
//register for external media changes for image files
if(mediaStoreObserver!=null){
_context.getContentResolver().registerContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
false,mediaStoreObserver);
Run Code Online (Sandbox Code Playgroud) 我有问题,FIleObserver和ContentObserver都无法在Android Marshmallow中运行.我正在使用这个东西来检测文件夹内发生的变化.我为marshmallow设置了运行时权限.但在那之后它也没有显示任何事件.它在其他版本中完美运行.请帮我解决这个问题.
首先,我尝试在Service中使用Content Resolver来检测后台文件夹的更改.
public class TestService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
initial();
return START_STICKY;
}
public void initial(){
getContentResolver().registerContentObserver(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
true,
new ContentObserver(new Handler()) {
@Override
public boolean deliverSelfNotifications() {
Log.d("hai", "deliverSelfNotifications");
return super.deliverSelfNotifications();
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
}
@Override
public void onChange(boolean selfChange, Uri uri) {
if (uri.toString().matches(MediaStore.Images.Media.EXTERNAL_CONTENT_URI.toString() + "/[0-9]+")) {
Cursor cursor = null; …Run Code Online (Sandbox Code Playgroud) android contentobserver fileobserver android-permissions android-6.0-marshmallow
我正在尝试创建一个应用程序来计算来自手机的外发短信的数量.目前我有以下代码:
private void listenForSMS(){
Log.v("SMSTEST", "STARTED LISTENING FOR SMS OUTGOING");
Handler handle = new Handler(){};
SMSObserver myObserver = new SMSObserver(handle);
ContentResolver contentResolver = getContentResolver();
contentResolver.registerContentObserver(Uri.parse("content://sms"),true, myObserver);
}
private class SMSObserver extends ContentObserver{
int count = 0;
String lastMessage = null;
public SMSObserver(Handler handler) {
super(handler);
}
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Log.v("SMSTEST", "HIT ON CHANGE");
Uri uriSMSURI = Uri.parse("content://sms");
Cursor cur = getContentResolver().query(uriSMSURI, null, null,
null, null);
cur.moveToNext();
String protocol = cur.getString(cur.getColumnIndex("protocol"));
if(protocol == null){
count++;
Log.v("SMSTEST", "SMS SENT: …Run Code Online (Sandbox Code Playgroud) 我知道这个问题已被多次询问,但没有人能够从我所看到的那里得到一个有效的答案.
我正在开发一个应用程序拦截短信,并根据发送#,弹出一个自定义提醒.我让它与广播接收器完美配合,但是如果用户安装了goSms,那么onReceive()方法永远不会被调用,因为goSms在它到达我的应用程序之前就会中止它.
为了解决这个问题,我尝试了一个关于content://sms/
它的内容观察者工作得很好,但是它onChange()被调用两次,具有完全相同的参数.我试过检查时间戳,但它们是相同的,就像我设置的类型和其他所有参数一样.
从我所看到的情况来看,这是一个常见的问题,但不是我见过的任何一个问题.
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
querySMS();
}
protected void querySMS() {
Cursor cur = getContentResolver().query(u, null, null, null, null);
cur.moveToNext(); // this will make it point to the first record, which is the last SMS sent
String type = cur.getString(cur.getColumnIndex("type"));
String body = cur.getString(cur.getColumnIndex("body")); //content of sms
String add = cur.getString(cur.getColumnIndex("address")); //phone num
if (type.equals("1")) {
if (add.equals(Test.SENDER)) {
String[] bodys = body.split(" ", 7);
if (bodys[0].equals("test")) { …Run Code Online (Sandbox Code Playgroud) ContentObserver的文档对我来说并不清楚.在哪个线程上调用ContentObserver的onChange?
我检查过,它不是你创建观察者的线程.看起来它是发送通知的线程,但我没有找到有关它的文档.
我知道这个问题被问了太多次,但我认为我试图针对的问题有点不同,可能更复杂.
我将开发一个使用RESTful Web服务的应用程序,并且需要满足以下要求:
应用程序应该在列表和详细信息中显示一些书籍,作者和编辑
该应用程序还应该允许搜索一本书
书籍,作者和编辑器是从RESTful Web服务中获取的
每个实体都必须被缓存,这样当我打开一个Activity时,我首先看到旧数据(如果有的话),而新的数据从网络更新.
每次实体更新时,都应通知相关方(ContentObserver?定期Listener实施?)
如果一个呼叫已经在执行(说到api/books/1337或来api/editors),应该通知呼叫者它正在加载数据,并且应该给它一个旧的(如果它存在),就像它是原始呼叫者一样.
一些数据(只有书籍和作者)应每N分钟更新一次(由用户决定),并应通知观察员(SyncAdapter?)
问题:
在观看和研究Virgil Dobjanschi在Google I/O 2010上提出的所有组件之后,我对此表示怀疑:
如何透明地为任何呼叫者处理" 实体更新 "概念?我应该使用ContentObserver在ContentProvider我将要实施?
如果我使用a,ContentObserver我可以轻松地为单个实体设置状态标志(如Dobjanschi所建议的),例如UPDATING,INSERTING依此类推.但是我该如何处理清单呢?说我想要一本书清单,我应该把状态标志放在哪里?我应该将它放在状态表中仅列表吗?如果是这样,我应该观察两个Cursors,一个用于状态,一个用于实际列表(即表/内容URI).如果我要求的实体(尚未存在)或REST调用返回一个404怎么办?我该如何处理回调?
如果我将所有REST方法都放在一个中**SyncAdapter**,我可以"强制" SyncAdapter从网络更新实体/实体列表(并因此将其放入正确的表中)吗?这样,状态标志将是有用的.
可以SyncAdapter在多个实体上工作(实际上,实体列表,因为我想偶尔更新书籍和编辑器),因为它只有一个performSync方法?
如果SyncAdapter用户在设备设置中禁用了我的实现,它将不会更新任何内容(这没关系).但是,如果用户单击"活动"中的"更新书籍"按钮,我仍然可以调用该performSync方法,还是也会被禁用?
rest android android-contentprovider android-syncadapter contentobserver