Developing android messages and contacts backup/restore app without root? - android

I am working on android application (as a final year project in my university) which backup and restores contacts, messages, calendar, call logs etc. I started working on it yesterday and until now I am able to get the message conversations through ContentResolver like this:
private void MsgBackup(){
try {
Uri uri = Uri.parse("content://sms");
//Uri uri = Uri.parse("content://mms-sms/conversations/");
ContentResolver contentResolver = getContentResolver();
final String[] projection = new String[]{"*"};
Cursor SMSL = contentResolver.query(uri, projection, null, null, null);
int msgscount = SMSL.getCount();
msgs = new String[SMSL.getCount()][2];
int i = 0;
while (SMSL.moveToNext()) {
address = SMSL.getString(SMSL.getColumnIndex("address"));
body = SMSL.getString(SMSL.getColumnIndex("body"));
msgs[i][0] = address;
msgs[i][1] = body;
i++;
}
SMSL.close();
//will do something here to backups msgs array
}catch (Exception e){
e.printStackTrace();
Toast.makeText(getApplicationContext(),"Error Fetching messages, check permissions!",Toast.LENGTH_LONG).show();
}
}
What I am worried about is "Restoring them". I read somewhere that it is not possible to restore messages without root access. If so, then how come the applications in the market do this job without root access?

Related

How to list all pdf files on android 10?

Since the changes related to the authorizations of access to the shared storage, it does not seem any more possible to search all the documents of the type pdf by this approach (with requestLegacyExternalStorage = "false"):
ContentResolver cr = context.getContentResolver();
Uri uri = MediaStore.Files.getContentUri("external");
String[] projection = null;
String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_NONE;
String[] selectionArgs = null;
String sortOrder = null;
Cursor allNonMediaFiles = cr.query(uri, projection, selection, selectionArgs, sortOrder);
Check this link : Media data restrictions
The only solution I see is to scan in a recurcive way all the tree of the shared storage with SAF, which seems to me very expensive in resources and ridiculous.
Does anyone have another idea?
The basic idea of scoped storage is exactly to avoid this kind of behavior, you can't know if there are or not some files somewhere in the user phone. You can just ask for permission to access to the storage tree and scan everything as you said. Even in this case the user could select a folder different from the root so your app will be limited to that folder. The idea could be perform a scan and then update your database keeping in sync using a job (job service) scheduled on the modification of tree URI and descendants.
if your project targeted to Sdk level 29 you should add to your AndroidManifest.xml the flag android:requestLegacyExternalStorage="true" under your <application> tag.
public List<String> queryFilesFromDevice(Uri uri, String[] projection, String selection, final Context context) {
final List<String> tempList = new ArrayList<>();
Cursor c = context.getContentResolver().query(uri, projection,
selection,
null,
null);
if (c != null) {
while (c.moveToNext()) {
String path = c.getString(0);
long size = c.getLong(1);
// your code logic should be here
}
c.close();
}
tempList.add(path);
return tempList;
}
you need to call the function like this:
String pdfExt = "_data LIKE '%.pdf'";
Uri ducumentsUri = MediaStore.Files.getContentUri("external");
String[] docsProjection ={MediaStore.Files.FileColumns.DATA,MediaStore.Images.Media.SIZE,MediaStore.Files.FileColumns.MIME_TYPE,};
queryFilesFromDevice(ducumentsUri, docsProjection, pdfExt, this);

Deleting all text/mms messages programmatically. but some are leftover

I found two answers on Stackoverflow on how to delete SMS messages programmatically. I'm running this on an app which is set to be the default messaging app.
I have tried these two codes
This one which is supposed to delete everything. It deleted most, but about 4-5 did not get deleted.
this.getApplicationContext().getContentResolver().delete(Uri.parse("content://sms/"), null, null);
and this one, which removed less then the code above
Uri inboxUri = Uri.parse("content://sms/inbox");
int count = 0;
Cursor c = context.getContentResolver().query(inboxUri , null, null, null, null);
while (c.moveToNext()) {
try {
// Delete the SMS
String pid = c.getString(0); // Get id;
String uri = "content://sms/" + pid;
count = context.getContentResolver().delete(Uri.parse(uri),
null, null);
} catch (Exception e) {
}
}
Any idea why a few messages are not being deleted? Any other way to delete all the SMS/MMS messages on the phone?

Android content provider query not retrieving updated information

So I've written a query to extract the WhatsApp contacts of a phone. My initial query goes like this:
Cursor c = con.getContentResolver().query(
ContactsContract.RawContacts.CONTENT_URI,
new String[]{ContactsContract.RawContacts.CONTACT_ID, ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY},
ContactsContract.RawContacts.ACCOUNT_TYPE + "= ?",
new String[]{"com.whatsapp"},
null
);
ArrayList<String> myWhatsappContacts = new ArrayList<String>();
int contactNameColumn = c.getColumnIndex(ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY);
while (c.moveToNext()) {
// You can also read RawContacts.CONTACT_ID to read the
// ContactsContract.Contacts table or any of the other related ones.
myWhatsappContacts.add(c.getString(contactNameColumn));
}
The purpose of this is to find out how many WhatsApp contacts the phone has at any one time. When I do:
Log.i("WhatsApp contacts found:", Integer.toString(myWhatsappContacts.size());
It should print out how many WhatsApp contacts there were into LogCat. And this works - up to a point.
Let's say for example that the number of WhatsApp contacts I have now is 101. The next phase of this little project is to delete away ALL contacts if there are more than 100 of them. In which case, we go:
if (myWhatsappContacts.size() > 100) {
//Delete all contacts code here
}
I've tested the delete contacts code, it works. I check the contacts directory of the phone via the contacts app, and it says 0. But now when I do the query again (refer to code above), it still shows 101! What's going on?
If it helps, my DeleteContacts method is as follows:
private void deleteContact(Context ctx, String phone, String name) {
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phone));
Cursor cur = ctx.getContentResolver().query(contactUri, null, null, null, null);
try {
if (cur.moveToFirst()) {
do {
if (cur.getString(cur.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME)).equalsIgnoreCase(name)) {
String lookupKey = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey);
ctx.getContentResolver().delete(uri, null, null);
return;
}
} while (cur.moveToNext());
}
} catch (Exception e) {
System.out.println(e.getStackTrace());
} finally {
cur.close();
}
return;
}
What am I doing wrong? Is my DeleteContacts code faulty? Or is the query itself faulty?

How to know if their is change in call log using contentOberser.

I am new to android development.
I want to monitor the changes occurred in the call log.My code is fetching all the call history until the last recent call log.when I run my app it again fetches all the logs including the newest one but I want only the latest changes. Please guide me how can I achieve this with contentOberser ? Please help. this is my code
private void conatctDetails()
{
StringBuffer sb = new StringBuffer();
Cursor c1 = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.Contacts.DISPLAY_NAME);
sb.append("Contact details:");
try
{
while(c1.moveToNext())
{
String id = c1.getString(c1.getColumnIndex(ContactsContract.Contacts._ID));
String name =c1.getString(c1.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String timesContacted =c1.getString(c1.getColumnIndex(ContactsContract.Contacts.TIMES_CONTACTED));
String lastTimeContacted =c1.getString(c1.getColumnIndex(ContactsContract.Contacts.LAST_TIME_CONTACTED));
String number="";
// String number =c1.getString(c1.getColumnIndex(CommonDataKinds.Phone.NUMBER));
if(id==null||name==null)
continue;
Cursor cur = getContentResolver().query(CommonDataKinds.Phone.CONTENT_URI, null, CommonDataKinds.Phone.CONTACT_ID +" = ?", new String[]{id}, null);
if(cur==null)
continue;
number = "";
while(cur.moveToNext())
{
number = cur.getString(cur.getColumnIndex(CommonDataKinds.Phone.NUMBER));
sb.append("\n Contact Number:--"+number);
}
sb.append("\n Contact Name:--"+name+"\n Contact ID:--"+id+"\n Last Time Contacted:--"+lastTimeContacted+"\n Total Time Contacted:--"+timesContacted);
sb.append("\n----------------------------");
}
//c1.close();
contact.setText(sb);
}
catch(Exception e)
{
}
finally
{
c1.close();
}
}
If there is an Intent that is fired on an incoming call you could get your app to respond by using a BroadcastReceiver and create an IntentFilter in your manifest.
Or just query the provider when your app launches...
ACTION_PHONE_STATE_CHANGED is a TelephonyManager intent you can listen for and check if it is TelephonyManager.CALL_STATE_RINGING.

lock sms using sms content provider [Edit sms content provider]

I am working on an sms app.By using sms content provider I got all the fields.
Uri uriSms = Uri.parse("content://sms/inbox");
Cursor c = context.getContentResolver().query(uriSms, null,null,null,null);
_id
thread_id
address
person
date
read
status
type
subject
body
locked
I could able to do all basic operations using the above fields.Now I want to make a sms locked state. How can I do that?.From status field I am always getting -1.What that means.I checked with both inbox and outbox.Please help me friends
Sms.CONTENT_URI= Uri.parse("content://sms");
Mms.CONTENT_URI = Uri.parse("content://mms");
private void lockMessage(MessageItem msgItem, boolean locked) {
Uri uri;
if ("sms".equals(msgItem.mType)) {
uri = Sms.CONTENT_URI;
} else {
uri = Mms.CONTENT_URI;
}
final Uri lockUri = ContentUris.withAppendedId(uri, msgItem.mMsgId);
final ContentValues values = new ContentValues(1);
values.put("locked", locked ? 1 : 0);
new Thread(new Runnable() {
public void run() {
getContentResolver().update(lockUri,
values, null, null);
}
}).start();
}
Just reminder, everything above is not include in SDK so carefull in usage.

Categories

Resources