I register SMS ContentObserver in my app. I want to update my ArrayList onChange with MessageID. This is my ObServer code..
public class SmsObserver extends ContentObserver {
private Context mContext;
private String contactId = "", contactName = "";
private String smsBodyStr = "", phoneNoStr = "";
private long smsDatTime = System.currentTimeMillis();
static final Uri SMS_STATUS_URI = Uri.parse("content://sms");
public SmsObserver(Handler handler, Context ctx) {
super(handler);
mContext = ctx;
}
public boolean deliverSelfNotifications() {
return true;
}
public void onChange(boolean selfChange) {
try{
Cursor sms_sent_cursor = mContext.getContentResolver().query(SMS_STATUS_URI, null, null, null, null);
if (sms_sent_cursor != null) {
if (sms_sent_cursor.moveToFirst()) {
String protocol = sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("protocol"));
if(protocol == null){
int type = sms_sent_cursor.getInt(sms_sent_cursor.getColumnIndex ("type"));
if(type == 2){
smsBodyStr = sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("body")).trim();
phoneNoStr = sms_sent_cursor.getString(sms_sent_cursor.getColumnIndex("address")).trim();
smsDatTime = sms_sent_cursor.getLong(sms_sent_cursor.getColumnIndex("date"));
}
}
}
} else {
Log.e("Info","Send Cursor is Empty");
}
} catch(Exception sggh) {
Log.e("Error", "Error on onChange : "+sggh.toString());
}
super.onChange(selfChange);
}
}
But, I am sending two messages. The first one is the phone closed. The second is the phone open. The first update is the latter. The second update is the first I sent the phone opens. With this ObServer I can access only the most recent post. Showing only the most recent data. How can I get the new updated data?
Related
I am trying to make a launcher which automatically cancels the notifications of some specific apps (whose package name is stored in variable label) registered in the SQLite database.
I have retrieved data from database in the NotificationListenerService onCreate() Method and cancelled the notification as soon as the are posted.
I have granted permissions to my NotificationListenerService to access notification content. But still when a new notification comes it doesn't gets logged.
My NotificationListenerService class looks like this:
public class AppsNotificationListenerService extends NotificationListenerService {
AppsDbHelper appsDbHelper;
SQLiteDatabase db;
ArrayList<AppItem> apps;
#Override
public IBinder onBind(Intent intent) {
return super.onBind(intent);
}
#Override
public void onCreate() {
super.onCreate();
appsDbHelper = new AppsDbHelper(this);
db = appsDbHelper.getReadableDatabase();
apps = new ArrayList<AppItem>();
Cursor cursor = db.query(Constants.AppsEntry.TABLE_NAME,null, null,
null, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
if (cursor.moveToFirst()) {
do {
AppItem app = new AppItem();
app.label = cursor.getString(2);
app.name = cursor.getString(1);
int use = cursor.getInt(3);
if(use == 1){
app.isUseful=true;
}else{
app.isUseful=false;
}
if(!app.isUseful){
apps.add(app);
}
} while (cursor.moveToNext());
}
cursor.close();
}
}
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
super.onNotificationPosted(sbn);
Log.i("NotifListenerService", "Notification Posted");
Log.i("NotifListenerService", sbn.getId()+" "+sbn.getKey()+" "+sbn.getPackageName());
String packageName = sbn.getPackageName();
for(AppItem app : apps){
if(packageName.equals(app.label)){
cancelNotification(sbn.getKey());
}
}
}
}
What am I doing wrong?
I am using a content observer to know that there is a change made to contact phonebook of the device but I am not getting the exact task done like whether the contact has been added, deleted or updated and what is the value of the modified contact.
// Service running in background which always run and check to know that content has been changed
public class ContactChange extends Service {
ContactObserver observer;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
observer = new ContactObserver(new Handler(),getApplicationContext());
// TODO Auto-generated method stub
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, false, observer);
super.onCreate();
}
#Override
public void onDestroy() {
super.onDestroy();
getContentResolver().unregisterContentObserver(observer);
}
}
//Content observer where we get to know that changes has made to the contact phonebook
public class ContactObserver extends ContentObserver {
private Context mContext;
DataBaseCurdOperation dataBaseCurdOperation;
ApiInterface apiInterface;
MyPrefs myPrefs;
ArrayList<InviteList> inviteArrayList;
public ContactObserver(Handler handler, Context context) {
super(handler);
this.mContext = context;
dataBaseCurdOperation = new DataBaseCurdOperation(mContext);
myPrefs = new MyPrefs(mContext);
apiInterface = ServiceGenerator.createService(ApiInterface.class, Config.BASE_URL_1);
inviteArrayList = new ArrayList<InviteList>();
}
#Override
public void onChange(boolean selfChange) {
this.onChange(selfChange, null);
}
#Override
public void onChange(boolean selfChange, Uri uri) {
Logger.LogError("URI", uri.toString());
boolean hasContactPermission = (ContextCompat.checkSelfPermission(mContext,
android.Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED);
if (hasContactPermission) {
SavingContactsActivity savingContactsActivity = new SavingContactsActivity(mContext);
savingContactsActivity.execute();
new InviteApiCall().execute();
}
}
Taking this approach and it is giving the contact whether it is added or updated not got the solution for deleted but surely will post the answer of deleted soon....
And I worked on the database after that
public class ContactSyncObserver extends ContentObserver {
Context mContext;
DataBaseCurdOperation dataBaseCurdOperation;
MyPrefs myPrefs;
public ContactSyncObserver(Handler handler, Context mContext) {
super(handler);
this.mContext = mContext;
dataBaseCurdOperation = new DataBaseCurdOperation(mContext);
myPrefs = new MyPrefs(mContext);
}
#Override
public boolean deliverSelfNotifications() {
return true;
}
#Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
boolean hasContactPermission = (ContextCompat.checkSelfPermission(mContext,
Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED);
if (hasContactPermission) {
try {
Cursor cursor = mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.Contacts.CONTACT_LAST_UPDATED_TIMESTAMP + " Desc");
if (cursor.moveToNext()) {
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
Logger.LogError("contactId", myPrefs.getContactId());
String name = cursor.getString(
cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String rawContactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.NAME_RAW_CONTACT_ID));
String phoneNumber = null;
String hasPhoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
if (Integer.parseInt(hasPhoneNumber) > 0) {
Cursor phones = mContext.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = " + id, null, null);
while (phones.moveToNext()) {
phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
Log.e("Number", phoneNumber);
}
phones.close();
}
if (phoneNumber != null) {
phoneNumber = phoneNumber.replaceAll(" ", "");
}
if (dataBaseCurdOperation.checkIsContactIdExist(id)) {
if (!myPrefs.getContactId().equals(id)) {
dataBaseCurdOperation.updateNewNumber(id, phoneNumber, name, "updated");
UtilHandler.TriggerRefresh();
} else {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
myPrefs.setContactId("0");
}
}, 3000);
}
} else {
dataBaseCurdOperation.insertServerContact(id, name, phoneNumber, "inserted", "newNumber", "newName");
UtilHandler.TriggerRefresh(); // triggering my sync adapter here...
}
myPrefs.setContactId(id);
}
} catch (Exception e) {
Logger.LogError("Contact Exception", "occured");
}
}
}
}
I know this kind of questions are maybe too old, but I got stock with this silly thing.
I have an AsyncTask class which is a subclass of an activity class, and right now I want to call it from another class: following codes shows what I mean:
public class STA extends Activity {
public class ListSpdFiles extends AsyncTask<Void, Void, String[]> {
private static final String TAG = "ListSpdFiles: ";
/**
* Status code returned by the SPD on operation success.
*/
private static final int SUCCESS = 4;
private String initiator;
private String path;
private SecureApp pcas;
private boolean isConnected = false; // connected to PCAS service?
private PcasConnection pcasConnection = new PcasConnection() {
#Override
public void onPcasServiceConnected() {
Log.d(TAG, "pcasServiceConnected");
latch.countDown();
}
#Override
public void onPcasServiceDisconnected() {
Log.d(TAG, "pcasServiceDisconnected");
}
};
private CountDownLatch latch = new CountDownLatch(1);
public ListSpdFiles(String initiator, String path) {
this.initiator = initiator;
this.path = path;
}
private void init() {
Log.d(TAG, "starting task");
pcas = new AndroidNode(getApplicationContext(), pcasConnection);
isConnected = pcas.connect();
}
private void term() {
Log.d(TAG, "terminating task");
if (pcas != null) {
pcas.disconnect();
pcas = null;
isConnected = false;
}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
init();
}
#Override
protected String[] doInBackground(Void... params) {
// check if connected to PCAS Service
if (!isConnected) {
Log.v(TAG, "not connected, terminating task");
return null;
}
// wait until connection with SPD is up
try {
if (!latch.await(20, TimeUnit.SECONDS)) {
Log.v(TAG, "unable to connected within allotted time, terminating task");
return null;
}
} catch (InterruptedException e) {
Log.v(TAG, "interrupted while waiting for connection in lsdir task");
return null;
}
// perform operation (this is where the actual operation is called)
try {
return lsdir();
} catch (DeadServiceException e) {
Log.i(TAG, "service boom", e);
return null;
} catch (DeadDeviceException e) {
Log.i(TAG, "device boom", e);
return null;
}
}
#Override
protected void onPostExecute(String[] listOfFiles) {
super.onPostExecute(listOfFiles);
if (listOfFiles == null) {
Log.i(TAG, "task concluded with null list of files");
// tv.setText("task concluded with a null list of files");
} else {
Log.i(TAG, "task concluded with the following list of files: "
+ Arrays.toString(listOfFiles));
//tv.setText("List of files received is:\n" + Arrays.toString(listOfFiles));
}
term();
}
#Override
protected void onCancelled(String[] listOfFiles) {
super.onCancelled(listOfFiles);
Log.i(TAG, "lsdir was canceled");
term();
}
/**
* Returns an array of strings containing the files available at the given path, or
* {#code null} on failure.
*/
private String[] lsdir() throws DeadDeviceException, DeadServiceException {
Result<List<String>> result = pcas.lsdir(initiator, path); // the lsdir call to the
final Global globalVariable = (Global) getApplicationContext();
if (globalVariable.getPasswordButt() == false) {
// Calling Application class (see application tag in AndroidManifest.xml)
// Get name and email from global/application context
final boolean isusername = globalVariable.getIsUsername();
if (isusername == true) {
String username = "/" + getLastAccessedBrowserPage() + ".username" + ".txt";
//String password = "/" + CurrentURL + "password" + ".txt";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
pcas.readFile(initiator, username, baos);
Log.i(TAG, "OutputStreampassword: "
+ new String(baos.toByteArray()));
String name = new String(baos.toByteArray());
if (!name.equalsIgnoreCase("")) {
globalVariable.setUsername(name);
// getCurrentInputConnection().setComposingText(name, 1);
// updateCandidates();
}
globalVariable.setIsUsername(false);
} else if (isusername == false)
Log.i(TAG, "Wrong Input Type For Username.");
// globalVariable.setUsernameButt(false);
} else if (globalVariable.getPasswordButt() == true) {
// Calling Application class (see application tag in AndroidManifest.xml)
// final Global globalVariable = (Global) getApplicationContext();
// Get name and email from global/application context
final boolean ispassword = globalVariable.getIsPassword();
if (ispassword == true) {
// String username = "/" + CurrentURL + "username" + ".txt";
String password = "/" + getLastAccessedBrowserPage() + ".password" + ".txt";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
pcas.readFile(initiator, password, baos);
Log.i(TAG, "OutputStreampassword: "
+ new String(baos.toByteArray()));
String name = new String(baos.toByteArray());
if (!name.equalsIgnoreCase("")) {
globalVariable.setPassword(name);
//getCurrentInputConnection().setComposingText(name, 1);
// updateCandidates();
}
globalVariable.setIsPassword(false);
} else if (ispassword == false)
Log.i(TAG, "Wrong Input Type For Password.");
globalVariable.setPasswordButt(false);
// boolpassword=false;
}
//}
if (result.getState() != SUCCESS) {
Log.v(TAG, "operation failed");
return null;
}
if (result.getValue() == null) {
Log.v(TAG, "operation succeeded but operation returned null list");
return null;
}
return result.getValue().toArray(new String[0]);
}
}
public String getLastAccessedBrowserPage() {
String Domain = null;
Cursor webLinksCursor = getContentResolver().query(Browser.BOOKMARKS_URI, Browser.HISTORY_PROJECTION, null, null, Browser.BookmarkColumns.DATE + " DESC");
int row_count = webLinksCursor.getCount();
int title_column_index = webLinksCursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE);
int url_column_index = webLinksCursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL);
if ((title_column_index > -1) && (url_column_index > -1) && (row_count > 0)) {
webLinksCursor.moveToFirst();
while (webLinksCursor.isAfterLast() == false) {
if (webLinksCursor.getInt(Browser.HISTORY_PROJECTION_BOOKMARK_INDEX) != 1) {
if (!webLinksCursor.isNull(url_column_index)) {
Log.i("History", "Last page browsed " + webLinksCursor.getString(url_column_index));
try {
Domain = getDomainName(webLinksCursor.getString(url_column_index));
Log.i("Domain", "Last page browsed " + Domain);
return Domain;
} catch (URISyntaxException e) {
e.printStackTrace();
}
break;
}
}
webLinksCursor.moveToNext();
}
}
webLinksCursor.close();
return null;
}
public String getDomainName(String url) throws URISyntaxException {
URI uri = new URI(url);
String domain = uri.getHost();
return domain.startsWith("www.") ? domain.substring(4) : domain;
}}
Would you please tell me what should I do to fix this code?
Looking over the code I did not see anywhere you referenced anything from the Activity itself besides the application context so you can move the ListSpdFiles class to its own java file and pass it a context into the constructor when you make a new instance of it.
Put this class in a ListSpdFiles.java file so it is no longer an inner class.
public class ListSpdFiles extends AsyncTask<Void, Void, String[]> {
Context applicationContext;
public ListSpdFiles(Context context, String initiator, String path) {
this.initiator = initiator;
this.path = path;
applicationContext = context.getApplicationContext();
}
// The rest of your code still goes here. Replace other calls to
// getApplicationContext() with the new applicationContext field
}
You can now use this class anywhere a Context is available. You create a new instance by doing:
ListSpdFiles listSpdFilesTask = new ListSpdFiles(context, "someInitiator", "somePath");
listSpdFilesTask.execute();
I am developing an application in which i am working on Android Contacts and not able to move ahead. In app the need of application is that the contact which is updated should send to server or the contact which is deleted should send to server for sync.
I am using the contact service as:
public class ContactService extends Service {
private int mContactCount;
Cursor cursor = null;
static ContentResolver mContentResolver = null;
// Content provider authority
public static final String AUTHORITY = "com.android.contacts";
// Account typek
public static final String ACCOUNT_TYPE = "com.example.myapp.account";
// Account
public static final String ACCOUNT = "myApp";
// Instance fields
Account mAccount;
Bundle settingsBundle;
#Override
public void onCreate() {
super.onCreate();
// Get contact count at start of service
mContactCount = getContactCount();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Get contact count at start of service
this.getContentResolver().registerContentObserver(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, true, mObserver);
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
private int getContactCount() {
try {
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if (cursor != null) {
return cursor.getCount();
} else {
cursor.close();
return 0;
}
} catch (Exception ignore) {
} finally {
cursor.close();
}
return 0;
}
private ContentObserver mObserver = new ContentObserver(new Handler()) {
#Override
public void onChange(boolean selfChange) {
this.onChange(selfChange, null);
}
#Override
public void onChange(boolean selfChange, Uri uri) {
new changeInContact().execute();
}
};
public class changeInContact extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... arg0) {
ArrayList<Integer> arrayListContactID = new ArrayList<Integer>();
int currentCount = getContactCount();
if (currentCount > mContactCount) {
// Contact Added
} else if (currentCount < mContactCount) {
// Delete Contact
} else if (currentCount == mContactCount) {
// Update Contact
}
mContactCount = currentCount;
return "";
}
#Override
protected void onPostExecute(String result) {
contactService = false;
} // End of post
}
}
The issues i am facing are as follows :
A: In the above code for getting the recently updated contact i need to check the Version of each contact from device with my database stored version of contacts. Which took much time for large amount of contacts.
B. For getting deleted contact i need to check that the data for the Raw id stored in my database is present in device or not. If not then the contact is deleted. It also take too much time to check whole contacts.
But the same thing contact refresh is done in whats app in very few seconds like 2 to three seconds...
EDIT :
In the above code in following module :
if (currentCount > mContactCount) {
// Contact Added
Log.d("In","Add");
} else if (currentCount < mContactCount) {
// Delete Contact
Log.d("In","Delete");
} else if (currentCount == mContactCount) {
// Update Contact
Log.d("In","Update");
}
I put the log. So the update module is called many times, and also when i do add or delete that time too...
Please guide me and suggest me what to do to reduce the timing for the above tasks...
use the below query to get all the deleted and updated contacts.
public static final String ACCOUNT_TYPE = "com.android.account.youraccounttype"
public static final String WHERE_MODIFIED = "( "+RawContacts.DELETED + "=1 OR "+
RawContacts.DIRTY + "=1 ) AND "+RawContacts.ACCOUNT_TYPE+" = '"+ ACCOUNT_TYPE+"'";
c = contentResolver.query(ContactsContract.RawContacts.CONTENT_URI,
null,
WHERE_MODIFIED,
null,
null);
I have created contact change observer, when a user any time change their contact need to know what change they did.
Step 1 :
public class ContactChangeObserver extends ContentObserver {
Context mContext;
public ContactChangeObserver(Handler handler, Context ctx) {
super(handler);
mContext = ctx;
}
#Override
public boolean deliverSelfNotifications() {
return super.deliverSelfNotifications();
}
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Log.e("Content Change", "Added New onChange selfChange");
}
#Override
public void onChange(boolean selfChange, Uri uri) {
Log.e("NoOf Content Change", "Contant Change Happen");
super.onChange(selfChange, uri);
if(mContext != null) {
Log.e("Content Change Name :", "start checking");
AppPreferences appPreferences = new AppPreferences(mContext);
String[] projection = {
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER
};
Cursor cursor = mContext.getContentResolver().query(uri, projection, null, null, null);
if (cursor.moveToFirst()) {
String sender = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String mobileno = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
String status = "phone";
MaraContactsManager.getInstance().updateContactDB(mContext, mobileno, sender, status, appPreferences.getCountryCode());
}
}
}
Step 2: have register this by calling at HomeActivity
contactChangeObserver = new ContactChangeObserver(new Handler(),getApplicationContext());
getApplicationContext().getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactChangeObserver);
Step 3: when i change any contact it goes to onChange Methode but I am not getting which contact changes done it says
java.lang.IllegalArgumentException: URI: content://com.android.contacts, calling user:
Please Help