Android add MMS to database
Asked Answered
U

1

11

I want to add some MMS messages into my device database.

I've the following code but it doesn't work at all. No entry are added into the native app...

public static Uri insert(Context context, String[] to, String subject, Uri messageUri)
{
    try
    {
        Uri destUri = Uri.parse("content://mms/sent");

        // Get thread id
        Set<String> recipients = new HashSet<String>();
        recipients.addAll(Arrays.asList(to));
        long thread_id = getOrCreateThreadId(context, recipients);
        Log.e(">>>>>>>", "Thread ID is " + thread_id);

        // Create a dummy sms
        ContentValues dummyValues = new ContentValues();
        dummyValues.put("thread_id", thread_id);
        dummyValues.put("body", "Dummy SMS body.");
        Uri dummySms = context.getContentResolver().insert(Uri.parse("content://sms/sent"), dummyValues);

        // Create a new message entry
        ContentValues mmsValues = new ContentValues();
        mmsValues.put("thread_id", thread_id);
        mmsValues.put("date", System.currentTimeMillis()/1000);
        mmsValues.put("ct_t", "application/vnd.wap.multipart.related");
        mmsValues.put("read", "1");
        mmsValues.put("sub", subject);

        // Create part
        long dummyId = System.currentTimeMillis();
        createPart(context, dummyId, imageBytes);

        // Insert message
        Uri res = context.getContentResolver().insert(destUri, mmsValues);
        String messageId = res.getLastPathSegment().trim();
        Log.e(">>>>>>>", "Message saved as " + res);

        // Update part
        ContentValues updateValues = new ContentValues();
        updateValues.put("mid", messageId);
        Uri updateUri = Uri.parse("content://mms/" + dummyId + "/part");
        int mmsPartRows = context.getContentResolver().update(updateUri, updateValues, null, null);
        Log.e(">>>>>>>", "Part rows " + mmsPartRows);

        // Create addresses
        for (String addr : to)
        {
            ContentValues addrValues = new ContentValues();
            addrValues.put("address", addr);
            addrValues.put("charset", "106");
            addrValues.put("type", 151); // TO
            Uri addrUri = Uri.parse("content://mms/"+ messageId +"/addr");
            Uri mmsAddrUri = context.getContentResolver().insert(addrUri, addrValues);
            Log.e(">>>>>>>", "Addr uri is " + mmsAddrUri.toString());
        }

        res = Uri.parse(destUri + "/" + messageId);

        // Delete dummy sms
        context.getContentResolver().delete(dummySms, null, null);

        return res;
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

    return null;
}

private static Uri createPart(Context context, long id, byte[] imageBytes) throws Exception
{
    ContentValues mmsPartValue = new ContentValues();
    mmsPartValue.put("ct", "image/png");
    Uri partUri = Uri.parse("content://mms/" + id + "/part");
    Uri res = context.getContentResolver().insert(partUri, mmsPartValue);
    Log.e(">>>>>>>", "Part uri is " + res.toString());

    // Add data to part
    OutputStream os = context.getContentResolver().openOutputStream(res);
    ByteArrayInputStream is = new ByteArrayInputStream(imageBytes);
    byte[] buffer = new byte[256];
    for (int len=0; (len=is.read(buffer)) != -1;)
    {
        os.write(buffer, 0, len);
    }
    os.close();
    is.close();

    return res;
}

private static long getOrCreateThreadId(Context context, String[] numbers)
{
    HashSet<String> recipients = new HashSet<String>();
    recipients.addAll(Arrays.asList(numbers));
    return Telephony.Threads.getOrCreateThreadId(context, recipients);
}
  • context is my view context
  • to is a string array containing the addresses (eg. new String[] {"0612345678", "0623456789"})
  • subject is my MMS subject such as "Sent via MyApp"
  • messageUri is an Uri pointing to the image I want to send on my SD card.

Am I doing it wrong ?

Undone answered 27/2, 2013 at 14:43 Comment(0)
U
10

Finally I found how to do the job ! Here is the code I made.

Tell me if you got some troubles with this.

public static Uri insert(Context context, String[] to, String subject, byte[] imageBytes)
{
    try
    {           
        Uri destUri = Uri.parse("content://mms");

        // Get thread id
        Set<String> recipients = new HashSet<String>();
        recipients.addAll(Arrays.asList(to));
        long thread_id = getOrCreateThreadId(context, recipients);
        Log.e(">>>>>>>", "Thread ID is " + thread_id);

        // Create a dummy sms
        ContentValues dummyValues = new ContentValues();
        dummyValues.put("thread_id", thread_id);
        dummyValues.put("body", "Dummy SMS body.");
        Uri dummySms = context.getContentResolver().insert(Uri.parse("content://sms/sent"), dummyValues);

        // Create a new message entry
        long now = System.currentTimeMillis();
        ContentValues mmsValues = new ContentValues();
        mmsValues.put("thread_id", thread_id);
        mmsValues.put("date", now/1000L);
        mmsValues.put("msg_box", MESSAGE_TYPE_OUTBOX);
        //mmsValues.put("m_id", System.currentTimeMillis());
        mmsValues.put("read", 1);
        mmsValues.put("sub", subject);
        mmsValues.put("sub_cs", 106);
        mmsValues.put("ct_t", "application/vnd.wap.multipart.related");
        mmsValues.put("exp", imageBytes.length);
        mmsValues.put("m_cls", "personal");
        mmsValues.put("m_type", 128); // 132 (RETRIEVE CONF) 130 (NOTIF IND) 128 (SEND REQ)
        mmsValues.put("v", 19);
        mmsValues.put("pri", 129);
        mmsValues.put("tr_id", "T"+ Long.toHexString(now));
        mmsValues.put("resp_st", 128);

        // Insert message
        Uri res = context.getContentResolver().insert(destUri, mmsValues);
        String messageId = res.getLastPathSegment().trim();
        Log.e(">>>>>>>", "Message saved as " + res);

        // Create part
        createPart(context, messageId, imageBytes);

        // Create addresses
        for (String addr : to)
        {
            createAddr(context, messageId, addr);
        }

        //res = Uri.parse(destUri + "/" + messageId);

        // Delete dummy sms
        context.getContentResolver().delete(dummySms, null, null);

        return res;
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }

    return null;
}

private static Uri createPart(Context context, String id, byte[] imageBytes) throws Exception
{
    ContentValues mmsPartValue = new ContentValues();
    mmsPartValue.put("mid", id);
    mmsPartValue.put("ct", "image/png");
    mmsPartValue.put("cid", "<" + System.currentTimeMillis() + ">");
    Uri partUri = Uri.parse("content://mms/" + id + "/part");
    Uri res = context.getContentResolver().insert(partUri, mmsPartValue);
    Log.e(">>>>>>>", "Part uri is " + res.toString());

    // Add data to part
    OutputStream os = context.getContentResolver().openOutputStream(res);
    ByteArrayInputStream is = new ByteArrayInputStream(imageBytes);
    byte[] buffer = new byte[256];
    for (int len=0; (len=is.read(buffer)) != -1;)
    {
        os.write(buffer, 0, len);
    }
    os.close();
    is.close();

    return res;
}

private static Uri createAddr(Context context, String id, String addr) throws Exception
{
    ContentValues addrValues = new ContentValues();
    addrValues.put("address", addr);
    addrValues.put("charset", "106");
    addrValues.put("type", 151); // TO
    Uri addrUri = Uri.parse("content://mms/"+ id +"/addr");
    Uri res = context.getContentResolver().insert(addrUri, addrValues);
    Log.e(">>>>>>>", "Addr uri is " + res.toString());

    return res;
}
Undone answered 5/3, 2013 at 13:13 Comment(12)
getOrCreateThreadId(context, recipients) where is this method ?Demotic
why you are sending Uri dummySms = context.getContentResolver().insert(Uri.parse("content://sms/sent"), dummyValues);Demotic
Apparently, on some devices (running 2.2-), if there is not discussion with the given contact yet, you need to insert a dummy SMS into DB, then insert your MMS and finally delete the dummy sms.Undone
Thanks Vodemki and have you work on send mms programatically.. if you have then I need some help from you.Demotic
I have a semi working MMS lib that sends MMS programmatically. For the moment it works perfectly in France, but not in all countries. For example, it UK it works once on 10... I'm still working on it. Check my profile for email addressUndone
vodemki(.at.)gmail(.dot.)comUndone
Can anybody help me about the method... getOrCreateThreadId(context, recipients) where is this method ?Tull
Right here: my.fit.edu/~vkepuska/ece5570/adt-bundle-windows-x86_64/sdk/…Undone
@manitoba: Hi tried this solution its giving me error in KITKAT 4.4, inside createPart() method // Add data to part OutputStream os = context.getContentResolver().openOutputStream(res); its giving me exception java.io.FileNotFoundException: App op not allowedDeclarative
Does anyone know how to delete the MMS and corresponding database entries programmatically?Chaiken
I've been implementing your code with success, but as I'm trying to insert some file quite big (I mean not too small), when I try to show them after by quering the database, theses image files seems to be corrupted, at least truncated, have you heard of a restriction one the size of the file you're storing? Have you ever met this behaviour?Sheila
Hello tchoum, i've taken a look at your issue. The method takes the following parameter byte[] imageBytes which must be a weakness if you try to push a far too big photo (or whatever type the MMS format allows). I would suggest to improve the code to handle every kind of sizes. I've written a quick gist to show you a way to achieve that: gist.github.com/anonymous/10bc611f89f2544e354eUndone

© 2022 - 2024 — McMap. All rights reserved.