how to read mms from android device after particular date? - android

I am able to read mms image from device using query "content://mms/part" and sending those mmsimages to server , but my requirement is in my application i will read all the mms images from device and backup to server from the second time when app is opened i need to backup only latest mms to the server , for this requirment i need to read the mms from the device after particular date given by me . is it possible?
Cursor curPart = getContentResolver (). query (Uri.parse ("content://mms/part"), null, null, null, null);
while(curPart.moveToNext())
{
coloumns = curPart.getColumnNames();
for(int i=0;i<coloumns.length;i++)
{
Log.e("coloumns",coloumns[i]);
}
if(values == null)
values = new String[coloumns.length];
for(int i=0; i< curPart.getColumnCount(); i++)
{
values[i] = curPart.getString(i);
}
if(values[3].equals("image/jpeg"))
{
mms_image.add(GetMmsAttachment(values[0],values[12],values[4]));
}
}
private String GetMmsAttachment(String _id, String _data,String fileName )
{
Uri partURI = Uri.parse("content://mms/part/" + _id );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = null;
try {
is = getContentResolver().openInputStream(partURI);
convertBitmapToFile(bitmap);
byte[] buffer = new byte[256];
int len = is.read(buffer);
while (len >= 0) {
baos.write(buffer, 0, len);
len = is.read(buffer);
}
}
catch (IOException e)
{
e.printStackTrace();
//throw new MmsException(e);
}
finally
{
if (is != null)
{
try
{
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
//writeToFile(bais,"data/",fileName);
is.close();
bais.close();
}
catch (IOException e)
{`enter code here`
e.printStackTrace();
}
}
}
return strMyImagePath;
}

This is the code I was talking about in my comment (from How to Read MMS Data in Android?):
String selection = "_id = "+_id;
Uri uri = Uri.parse("content://mms");
Cursor cursor = contentResolver.query(uri, null, selection, null, null);
String phone = cursor.getString(cursor.getColumnIndex("address"));
int type = cursor.getInt(cursor.getColumnIndex("type"));// 2 = sent, etc.
String date = cursor.getString(cursor.getColumnIndex("date"));
String body = cursor.getString(cursor.getColumnIndex("body"));
You can then compare the date against your given date to determine whether or not you want to upload data corresponding to the current _id.

Related

The size of the contact picture is changed when inserting and updating

I have a problem inserting or updating a contact picture.
It seems that Android compressed the picture.
For testing, I created a PNG with 200 x 200 px and saved it in the internal app storage.
The size of the byte[] is 52490.
But the size of the contact picture (high res) is always 6767 bytes.
Tested on a HTC U11 (Android 9) and Sony Xperia (Android 8)
Reading the image from internal storage:
byte[] readPicture(String filename) {
FileInputStream in = null;
byte[] result = null;
try {
in = context.openFileInput(filename);
result = new byte[in.available()];
int read = in.read(result);
Log.d("FileUtil", read + " bytes read from " + filename);
} catch (Exception e) {
e.printStackTrace();
} finally {
closeStream(in);
}
return result;
}
Insert the picture to a specific contact:
picture = readPicture(filename);
ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
builder.withYieldAllowed(true);
builder.withValue(ContactsContract.Data.CONTACT_ID, contactId);
builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
builder.withValue(ContactsContract.Data.IS_SUPER_PRIMARY, 1);
builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO, picture);
ops.add(builder.build());
Load the full-size contact picture:
// contact.getContactId() == ContactsContract.Data.CONTACT_ID
// contact.getLookup() == ContactsContract.Data.LOOKUP_KEY
ContactsContract.Contacts.getLookupUri(Long.parseLong(contact.getContactId()), contact.getLookup());
InputStream is = ContactsContract.Contacts.openContactPhotoInputStream(cr, uri, true);
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] result = null;
if (is != null) {
byte[] buffer = new byte[4096];
int length;
try {
while ((length = is.read(buffer)) != -1) {
os.write(buffer, 0, length);
}
result = os.toByteArray();
} catch (Exception ignored) {
return null;
} finally {
FileUtil.closeStream(is);
FileUtil.closeStream(os);
}
}
return result;
I think I'm doing something wrong, but I have no idea what.
Don't you need to loop the read, in following code:
while(in.available()>0){
result = new byte[in.available()];
int read = in.read(result);
//or better make a loop until in.read(readBytes[])!=-1
Log.d("FileUtil", read + " bytes read from " + filename);
}

Android contact book overwrites EXIF image data

In my app I'm trying to add an EXIF attribute to a contact photo when I add it to either a new or existing contact. This is so I can later check to see if it was My_App that changed the photo. I add the EXIF data like this:
private void addPhotoToExistingContact(long rawContactId, byte[] photoByteArray) {
if (photoByteArray != null) {
try {
photoByteArray = addExifDataToContactPhoto(photoByteArray);
} catch (IOException e) {
e.printStackTrace();
}
ContentValues values = new ContentValues();
values.put(ContactsContract.Data.RAW_CONTACT_ID, rawContactId);
values.put(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
values.put(ContactsContract.CommonDataKinds.Photo.PHOTO, photoByteArray);
context.getContentResolver().insert(
ContactsContract.Data.CONTENT_URI,
values);
}
}
private byte[] addExifDataToContactPhoto(byte[] photoByteArray) throws IOException {
// Convert to temp file
File file = new File(context.getCacheDir(), "contact_photo_exif_temp_file.jpg");
if (file.exists()) {
file.delete();
}
FileOutputStream fos = new FileOutputStream(file.getAbsoluteFile());
fos.write(photoByteArray);
fos.close();
// Add EXIF data
ExifInterface exif = new ExifInterface(file.getAbsolutePath());
exif.setAttribute(MY_EXIF_TAG, MY_EXIF_VALUE);
exif.saveAttributes();
// Convert back to byte[]
byte[] photoByteArrayWithExifData = FileUtils.readFileToByteArray(file);
// Delete temp file
file.delete();
return photoByteArrayWithExifData;
}
My check for EXIF data (done at a later time) is as follows:
private boolean shouldReplaceContactPhoto(long contactId) {
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(
ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.MIMETYPE + " = ? AND " + ContactsContract.CommonDataKinds.StructuredName.CONTACT_ID + " = ?",
new String[] { ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE, String.valueOf(contactId) },
null);
if (cursor != null) {
if (cursor.moveToFirst()) {
long photoId = cursor.getLong(cursor.getColumnIndex(ContactsContract.Data.PHOTO_ID));
if (photoId == 0) {
cursor.close();
return true;
}
else {
// Read EXIF data to check if photo is a My_App photo
File contactPhotoTempFile = getExistingContactImageFile(contactId);
if (contactPhotoTempFile != null) {
try {
ExifInterface exif = new ExifInterface(contactPhotoTempFile.getAbsolutePath());
String swopTag = exif.getAttribute(MY_EXIF_TAG);
// Temporary image, so delete it when we're done reading EXIF data
contactPhotoTempFile.delete();
cursor.close();
// If tag is null, the photo came from a different source - return 'true'
// so it is not replaced.
return myTag != null;
} catch (IOException e) {
e.printStackTrace();
// Temporary image, so delete it when we're done reading EXIF data
contactPhotoTempFile.delete();
}
}
cursor.close();
return true;
}
}
cursor.close();
}
return true;
}
private File getExistingContactImageFile(long contactId) {
Uri contactUri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);
Uri displayPhotoUri = Uri.withAppendedPath(contactUri, ContactsContract.Contacts.Photo.DISPLAY_PHOTO);
byte[] imageBytes;
try {
AssetFileDescriptor fd = context.getContentResolver().openAssetFileDescriptor(displayPhotoUri, "r");
InputStream inputStream = fd.createInputStream();
imageBytes = IOUtils.toByteArray(inputStream);
} catch (IOException e) {
return null;
}
if (imageBytes == null) {
return null;
}
File file = new File(context.getCacheDir(), "contact_photo_temp_file.jpg");
if (file.exists()) {
file.delete();
}
try {
FileOutputStream fos = new FileOutputStream(file.getPath());
fos.write(imageBytes);
fos.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
return file;
}
I've added break points and log statements and I'm almost 100% positive that the attribute is being written, but when I read the data, the property is missing. I also noticed that the orientation attribute is changed from 1 to 0 as well, which leads me to believe that Android is overwriting the EXIF data.
Is this the case, or am I doing something incorrectly? Any help at all is extremely appreciated!

Not able to get file path when using GoogleDrive in android version 4.4.2

In my android application, i have used google drive to pick images and files to my application, it works perfectly in all API version except 4.4.2, whenever i tried to pick image or file i can get the file name but not able to get file path, it always returns empty path
My code :
// Get real path from Google Drive
public String getPathfromGoogleDrive(Intent data, Uri contentURI) {
if (contentURI == null) {
return null;
}
String[] filePathColumn = { MediaStore.Images.Media.DATA };
String mCurrentPhotoPath = new String();
Cursor cursor = null;
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
LogUtil.d("currentapiVersion" + currentapiVersion);
if (currentapiVersion == 19) {
String wholeID = DocumentsContract.getDocumentId(contentURI);
// Split at colon, use second item in the array
String id = wholeID.split(";")[0];
// where id is equal to
String sel = MediaStore.Images.Media._ID + "=?";
cursor = getActivity().getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
filePathColumn, sel, new String[] { id }, null);
LogUtil.d("Cursor Count" + cursor.getCount());
if (cursor.getCount() > 0 && cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
mCurrentPhotoPath = cursor.getString(columnIndex);
cursor.close();
}
}
My Intent :
int currentapiVersion = android.os.Build.VERSION.SDK_INT;
if (currentapiVersion == 19) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
String strType = "*/*";
intent.setDataAndType(null, strType);
startActivityForResult(intent, Gallery);
} else {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setPackage("com.google.android.apps.docs");
String strType = "*/*";
intent.setDataAndType(null, strType);
startActivityForResult(intent, Gallery);
}
Please correct me if i have did any mistake
Thanks in advance
Instead of getting file real path, we can use input stream as like below
Bitmap bitmap = null;
InputStream input = null;
try {
input = getActivity().getContentResolver().openInputStream(selectedImageURI);
bitmap = BitmapFactory.decodeStream(input);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
To Get File from drive and write that into locale(sd card)
sourceuri - your cnontent uri
destination - path where you want to save in sd card
public boolean savefile(String name, Uri sourceuri, String destination)
throws IOException {
// String sourceFilename = sourceuri.getPath();
int originalsize = 0;
InputStream input = null;
try {
input = getContentResolver().openInputStream(sourceuri);
Log.Logger().finest("input in profileview Activity" + input);
} catch (FileNotFoundException e) {
e.printStackTrace();
filenotfoundexecption = true;
}
try {
originalsize = input.available();
Log.Logger().finest(
"Profile view activity originalsize" + originalsize);
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(input);
bos = new BufferedOutputStream(new FileOutputStream(
destination, false));
byte[] buf = new byte[originalsize];
bis.read(buf);
do {
bos.write(buf);
} while (bis.read(buf) != -1);
} catch (IOException e) {
Mint.logException(e);
filenotfoundexecption = true;
return false;
}
} catch (NullPointerException e1) {
Mint.logException(e1);
filenotfoundexecption = true;
}
/*
* String[] cmd = new String[] { "logcat", "-f", GridViewDemo_LOGPATH,
* "-v", "time", "ActivityManager:W", "myapp:D" };
*
* Runtime.getRuntime().exec(cmd);
*/
return true;
}

Fetching images from MMS gives wrong MMS

My app is trying to fetch SMS and MMS from the device and store it in a database. I have tried this code: How to Read MMS Data in Android? This is working fine, but the problem is getting the wrong MMS image. This happens in the scenario when I send a new MMS , while backing up the MMS.
Here is my code:
// To get text content from mms..
public ArrayList<String> getMmsTextContent(String mmsId) {
String body = null;
ArrayList<String> arlMMS = new ArrayList<String>();
String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cursor = getContentResolver().query(uri, null, selectionPart,
null, null);
if (cursor.moveToFirst()) {
do {
String partId = cursor.getString(cursor.getColumnIndex("_id"));
String type = cursor.getString(cursor.getColumnIndex("ct"));
if ("text/plain".equals(type)) {
String data = cursor.getString(cursor
.getColumnIndex("_data"));
if (data != null) {
// implementation of this method below
body = getMmsText(partId);
arlMMS.add(body);
} else {
body = cursor.getString(cursor.getColumnIndex("text"));
arlMMS.add(body);
}
}
} while (cursor.moveToNext());
return arlMMS;
}
return null;
}
// To get the text
private String getMmsText(String id) {
Uri partURI = Uri.parse("content://mms/part/" + id);
InputStream is = null;
StringBuilder sb = new StringBuilder();
try {
is = getContentResolver().openInputStream(partURI);
if (is != null) {
InputStreamReader isr = new InputStreamReader(is, "UTF-8");
BufferedReader reader = new BufferedReader(isr);
String temp = reader.readLine();
while (temp != null) {
sb.append(temp);
temp = reader.readLine();
}
}
} catch (IOException e) {
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
}
return sb.toString();
}
// To get the mms..
public ArrayList<Bitmap> getMms(String mmsId) {
Bitmap bitmap = null;
ArrayList<Bitmap> arlBitmap = new ArrayList<Bitmap>();
String selectionPart = "mid=" + mmsId;
Uri uri = Uri.parse("content://mms/part");
Cursor cPart = getContentResolver().query(uri, null, selectionPart,
null, null);
if (cPart.moveToFirst()) {
do {
String partId = cPart.getString(cPart.getColumnIndex("_id"));
String type = cPart.getString(cPart.getColumnIndex("ct"));
if ("image/jpeg".equals(type) || "image/bmp".equals(type)
|| "image/gif".equals(type) || "image/jpg".equals(type)
|| "image/png".equals(type)) {
bitmap = getMmsImage(partId);
arlBitmap.add(bitmap);
}
} while (cPart.moveToNext());
return arlBitmap;
}
return arlBitmap;
}
// To get bitmap from mms
private Bitmap getMmsImage(String _id) {
Uri partURI = Uri.parse("content://mms/part/" + _id);
InputStream is = null;
Bitmap bitmap = null;
try {
is = getContentResolver().openInputStream(partURI);
bitmap = BitmapFactory.decodeStream(is);
} catch (IOException e) {
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
}
}
}
return bitmap;
}
}
Please help me.
Running two threads at a time one is Backup images and second one is retrieving images from sqlite . Change two folders different can eliminate this problem

Inserting Sent MMS into sent box

I'm trying to insert a MMS into the sent database but alas I haven't been able to view it in the native android application.
my insertion code:
ContentValues values = new ContentValues();
values.put("thread_id", thread_id);
values.put("date", time);
values.put("read", true); //read status
values.put("sub", text); //mms subject
values.put("msg_box", 2); //message box. in this case outbox
Uri mmsUri = context.getContentResolver().
insert(Uri.parse("content://mms"), values);
Log.v("MMSProjectActivity", "Message saved at: " + mmsUri);
ContentValues mmsPartValue = new ContentValues();
mmsPartValue.put("ct", "image/jpeg"); //mime; for example image/jpeg
Uri picUri = picUris.get(0);
String [] fileNameSplit = picUri.toString().split("/");
String fileName = fileNameSplit[fileNameSplit.length-1] + ".jpg";
String messageId = mmsUri.getLastPathSegment().trim(); //id of MMS at content://mms
Uri partUri = Uri.parse("content://mms/" + messageId + "/part");
Uri mmsPartUri = context.getContentResolver().insert(partUri, mmsPartValue);
OutputStream os;
InputStream is;
try
{
os = context.getContentResolver().openOutputStream(mmsPartUri);
is = context.getContentResolver().openInputStream(picUris.get(0));
byte[] buffer = new byte[256];
for (int len = 0; (len = is.read(buffer)) != -1; ) {
os.write(buffer, 0, len);
}
} catch (FileNotFoundException e)
{
Log.v("MMSProjectActivity", "MMS not saved FileNotFoundException");
e.printStackTrace();
} catch (IOException e)
{
Log.v("MMSProjectActivity", "MMS not saved IOException");
e.printStackTrace();
}
Log.v("MMSProjectActivity", "MMS part value saved at: " + mmsPartUri);
anybody have any idea what am I doing wrong?
I think what you need is in this class of the source code .
Generally take a look at how they do it at google..
specifically take a look at this method
private static Uri createDraftMmsMessage(PduPersister persister, SendReq sendReq,
SlideshowModel slideshow) {
try {
PduBody pb = slideshow.toPduBody();
sendReq.setBody(pb);
Uri res = persister.persist(sendReq, Mms.Draft.CONTENT_URI);
slideshow.sync(pb);
return res;
} catch (MmsException e) {
return null;
}
}
And after creating the Draft (step one) then you update the draft to sent. by calling the other method
private static void updateDraftMmsMessage(Uri uri, PduPersister persister,
SlideshowModel slideshow, SendReq sendReq) {
if (Log.isLoggable(LogTag.APP, Log.VERBOSE)) {
LogTag.debug("updateDraftMmsMessage uri=%s", uri);
}
if (uri == null) {
Log.e(TAG, "updateDraftMmsMessage null uri");
return;
}
persister.updateHeaders(uri, sendReq);
final PduBody pb = slideshow.toPduBody();
try {
persister.updateParts(uri, pb);
} catch (MmsException e) {
Log.e(TAG, "updateDraftMmsMessage: cannot update message " + uri);
}
slideshow.sync(pb);
}
Now I know you cannot run this code from your app since you're not building in the source, or even if you are it may be a challenge to do so (even though I think that if you do build in the source if you code correctly the google code should handle the save stuff)
in any case you should be able to save mms message in the provider by following what they do in this class.
cheers...
and post your progress...

Categories

Resources