locked
Xamarin Android SmsManager SendMultimediaMessage MMS RRS feed

  • Question

  • User394194 posted

    So, I’ve been grappling with this for the past week or so in between schooling my kids. I’m trying to get a new Xamarin Android app out the door that handles SMS. Since Google changed their policies on the play store requiring any app that does this to be the default SMS app, I have to implement the full functionality of SMS to make this work and that includes sending MMS messages directly from my app.

    Per EVERYTHING I’ve read thus far, SmsManager.SendMultimediaMessage is the method for doing that. Has anyone here successfully implemented sending MMS messages using Xamarin/Android via that method? As far as I can tell after many hours, I’ve implemented it as closely as I know how and either:

    1) I’m missing one or two small details 2) Or the PDU isn’t being packaged correctly by the PduManagement

    Any help from someone who has done this successfully would be greatly appreciated. Here’s what I’ve done along with code. Please excuse sloppy code. I will re-factor and button it up once I’ve got a POC of it actually working:

    Firstly, I’ve been able to successfully get my app to load as the default SMS messenger. Secondly I’ve got an android dependency service I created with some methods to handle sending the MMS

    First, I’m using the PduManagement NuGet by Yasmani Llanes to create a PDU request, but I’m unsure if it’s working correctly and I should try one from someone else or try building my own. Here's the pertinent code:

                    SendReq sendReqPdu = new SendReq();
                    // Set the recipient number of our MMS
                    sendReqPdu.AddTo(new EncodedStringValue(phone));
                    // Instantiate the body of our MMS
                    PduBody pduBody = new PduBody();
    
                    // Add any text message data
                    if (!string.IsNullOrEmpty(txtMessage))
                    {
                        PduPart txtPart = new PduPart();
                        txtPart.SetData(Encoding.ASCII.GetBytes(txtMessage));
                        txtPart.SetContentType(new EncodedStringValue("text/plain").GetTextString());
                        txtPart.SetName(new EncodedStringValue("Message").GetTextString());
                        pduBody.AddPart(txtPart);
                    }
    
                    // add any image data
                    if (!string.IsNullOrEmpty(imgFilePath))
                    {
                        PduPart imgPart = new PduPart();
    
                        byte[] sampleImageData = GetFileBytes(imgFilePath);
    
                        imgPart.SetData(sampleImageData);
                        imgPart.SetContentType(new EncodedStringValue("image/png").GetTextString());
                        imgPart.SetFilename(new EncodedStringValue(System.IO.Path.GetFileName(imgFilePath)).GetTextString());
                        pduBody.AddPart(imgPart);
                    }
    
                    // Set the body of our MMS
                    sendReqPdu.Body = pduBody;
                    // Finally, generate the byte array to send to the MMS provider
                    PduComposer composer = new PduComposer(sendReqPdu);
                    pduData = composer.Make();
    

    The second part of the code takes the PDU data request byte array and saves the bytes to a file in the cache directory, then calls SendMultimediaMessage to send the request.

               try
            {
                Context ctx = AndroidGlobals.MainActivity.ApplicationContext;
    
                // write the pdu to a temp cache file
                string cacheFilePath = System.IO.Path.Combine(ctx.CacheDir.AbsolutePath, "send." + rnd.Next().ToString() + ".dat");
                File.WriteAllBytes(cacheFilePath, pduData);
    
                if (File.Exists(cacheFilePath))
                {
    
                    // create the contentUri
                    Android.Net.Uri contentUri = (new Android.Net.Uri.Builder())
                       .Authority(ctx.PackageName + ".fileprovider")
                       .Path(cacheFilePath)
                       .Scheme(ContentResolver.SchemeContent)
                       .Build();
    
                    // Send pduData to service provider
                    sm.SendMultimediaMessage(ctx, contentUri, null, null, null);
    
                }
            }
            catch (Exception ex)
            {
                MobileGlobals.AddNewException(ex);
                MobileGlobals.WriteExceptionLog();
    
                return false;
            }
    

    In the code, not that after checking that the file actually exists, I use Uri.Builder to build a contentUri. I've tried it both with sending a PendingIntent as well as no PendingIntent (not exactly sure which PendingIntent filter message I should use).

    I call the SmsManager.SendMultimediaMessage method passing the main activity application main activity context and the contentUri. I have a try catch here and it never throws an error.

    As I debug through this, everything except the actual SendMultimediaMessage appears to be working as expected. The PDU is built, the phone gets encoded, the cache file is created, and SendMultimediaMessage executes without throwing an error… just no MMS message is ever sent, neither when I send it to my own phone number nor to any other phone I send it to. Again, the app loads and successfully is able to prompt the user to set it to the default Sms app (if that is required to use this method).

    I understand that part of building the contentUri is providing a FileProvider authority that the SendMultimediaMessage method can use to get the cached file to extract the info and data it needs to send. I already have one and it looks like this:

    AndroidManifest.xml file:

    <application android:label="Xpios Mobile FREE">
            <provider android:name="android.support.v4.content.FileProvider" 
                  android:authorities="${applicationId}.fileprovider" 
                  android:grantUriPermissions="true" 
                  android:exported="false">
            android:name="android.support.FILE_PROVIDER_PATHS" 
            android:resource="@xml/file_paths" />
            </provider>
    </application>
    

    I have a file_paths.xml file in my Android projects Resources/xml folder and it looks like this:

    <?xml version="1.0" encoding="utf-8"?>
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
      <external-path
        name="external"
        path="." />
      <external-files-path
        name="external_files"
        path="." />
      <cache-path
        name="cache"
        path="." />
      <external-cache-path
        name="external_cache"
        path="." />
      <files-path
          name="files"
          path="." />
      <root-path 
        name="root" 
        path="." />
    </paths>
    

    I know in general that the FileProvider is working because it works for other tasks where I have to serve a file up… so I don’t think that is the problem. For example, I can create an intent that allows a user to select an app on the phone to view a text file. Works like a charm. I’ve also confirmed that there isn’t any permissions issue. To be super sure of that, I tried placing the PDU request cache file into a directory I know the FileProvider is already able to get files from and still no luck. The MMS never sends and it never throws and error.

    So what am I missing? Any suggestions are welcome and very much appreciated as they may give me a clue. Thanks!

    Sunday, April 26, 2020 4:55 PM

Answers

  • User256966 posted

    I've tried the MMS sending with github.com/ceakins001/AndoidMobileAppTesting and the MMS code in SmsMessageProvider it is working just fine for me.

    The only thing I know I changed was the Android.Net.Uri.Builder(), which I switched to AndroidX.Core.Content.FileProvider.GetUriForFile().

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, August 26, 2020 8:01 AM

All replies

  • User377758 posted

    Maybe uploading the demo is a better way for us to find problems. :)

    Besides, what device did you used to test?

    Monday, April 27, 2020 10:09 AM
  • User394194 posted

    Thanks for responding. Im using a Samsung Galaxy S8 running Android 9. There is no demo I can upload. This is additional code being added to a full featured app. If you see anything missing or wrong in the code or configuration supplied above, please let me know.

    Monday, April 27, 2020 3:36 PM
  • User394194 posted

    I'm trying to get a scaled down demo project ready by this afternoon. Is there a place to upload it here or do I just make a git and link to it?

    Tuesday, April 28, 2020 3:18 PM
  • User371688 posted

    Yes, you can upload your demo to github and share the link here.

    Tuesday, April 28, 2020 8:41 PM
  • User394194 posted

    Here's a stripped down (good enough) demo project you can test with.

    https://github.com/ceakins001/AndoidMobileAppTesting/tree/master/AndroidTest

    Wednesday, April 29, 2020 4:18 PM
  • User394194 posted

    Any updates jezh?

    Here's the link again but to the page with the download button:

    https://github.com/ceakins001/AndoidMobileAppTesting/tree/efea37ef2fac430def8c2790f50f577017c80bdb

    Tuesday, May 5, 2020 3:16 PM
  • User394194 posted

    bump... anyone from the Xamarin team around?

    Friday, May 8, 2020 3:37 PM
  • User394194 posted

    Bump. Is anyone sending MMS in Android using Xamarin?

    Wednesday, May 13, 2020 12:13 AM
  • User395724 posted

    @Chris001 did you complete your MMS sending in Android using Xamarin? I need urgent help for the same. I am working on MMS sending functionality from long time but still no luck. Can you please help?

    Monday, July 13, 2020 8:16 AM
  • User394194 posted

    @kalyanipwr said: @Chris001 did you complete your MMS sending in Android using Xamarin? I need urgent help for the same. I am working on MMS sending functionality from long time but still no luck. Can you please help?

    No. Sorry. It appears nobody knows and the Xamarin team doesn't care to help.

    Monday, July 13, 2020 3:38 PM
  • User394194 posted

    @Chris001 said:

    @kalyanipwr said: @Chris001 did you complete your MMS sending in Android using Xamarin? I need urgent help for the same. I am working on MMS sending functionality from long time but still no luck. Can you please help?

    No. Sorry. It appears nobody knows and the Xamarin team doesn't care to help.

    I think Xamarin may be dying, which is has changed my opinion about investing further in it.

    Monday, July 13, 2020 3:39 PM
  • User395724 posted

    @Chris001 said:

    @Chris001 said:

    @kalyanipwr said: @Chris001 did you complete your MMS sending in Android using Xamarin? I need urgent help for the same. I am working on MMS sending functionality from long time but still no luck. Can you please help?

    No. Sorry. It appears nobody knows and the Xamarin team doesn't care to help.

    I think Xamarin may be dying, which is has changed my opinion about investing further in it.

    yeah, i too have approached for help for MMS feature but no positive response yet. it won't be possible?

    Monday, July 13, 2020 3:48 PM
  • User394194 posted

    @kalyanipwr said:

    @Chris001 said:

    @Chris001 said:

    @kalyanipwr said: @Chris001 did you complete your MMS sending in Android using Xamarin? I need urgent help for the same. I am working on MMS sending functionality from long time but still no luck. Can you please help?

    No. Sorry. It appears nobody knows and the Xamarin team doesn't care to help.

    I think Xamarin may be dying, which is has changed my opinion about investing further in it.

    yeah, i too have approached for help for MMS feature but no positive response yet. it won't be possible?

    It appears they no longer care.

    Monday, July 13, 2020 8:21 PM
  • User256966 posted

    I've tried the MMS sending with github.com/ceakins001/AndoidMobileAppTesting and the MMS code in SmsMessageProvider it is working just fine for me.

    The only thing I know I changed was the Android.Net.Uri.Builder(), which I switched to AndroidX.Core.Content.FileProvider.GetUriForFile().

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, August 26, 2020 8:01 AM
  • User394194 posted

    @emilsteen said: I've tried the MMS sending with github.com/ceakins001/AndoidMobileAppTesting and the MMS code in SmsMessageProvider it is working just fine for me.

    The only thing I know I changed was the Android.Net.Uri.Builder(), which I switched to AndroidX.Core.Content.FileProvider.GetUriForFile().

    Thanks. I will try again that way.

    What device and OS were you using to test? I'm using a Samsung Galaxy S8.

    Wednesday, August 26, 2020 3:05 PM
  • User256966 posted

    I've tested it on Samsung S7 and Zebra TC57.

    FileProvider.GetUriForFile() gives: {content://com.companyname.xamarinmailandsms.fileprovider/app_cache/send.1792335469.dat}

    Uri.Builder() gives: {content://com.companyname.xamarinmailandsms.fileprovider/data/user/0/com.companyname.xamarinmailandsms/cache/send.1792335469.dat}

    Wednesday, August 26, 2020 3:36 PM
  • User394194 posted

    @Chris001 said:

    @emilsteen said: I've tried the MMS sending with github.com/ceakins001/AndoidMobileAppTesting and the MMS code in SmsMessageProvider it is working just fine for me.

    The only thing I know I changed was the Android.Net.Uri.Builder(), which I switched to AndroidX.Core.Content.FileProvider.GetUriForFile().

    Thanks. I will try again that way... though unsure why two Uri builders would return diff addresses.

    What device and OS were you using to test? I'm using a Samsung Galaxy S8.

    Seems like that did the trick. I guess the File provider was necessary in the first place to build the initial uri.

    Wednesday, August 26, 2020 3:59 PM
  • User394194 posted

    Actually... unfortunately looks like this only improved the results marginally. Previously, when I sent messages to myself, I wouldn't get any response. Now, I get the images I've sent to myself as messages. However, when I send the same small image to another phone, the image never comes through. Any ideas?

    Thursday, August 27, 2020 2:36 AM
  • User394194 posted

    Fixed... a little debugging revealed the phone address had a text character in it that was throwing things off. So, just make sure you normalize all the addresses to numeric chars only.

    Thursday, August 27, 2020 3:45 PM
  • User296700 posted

    I have questions if anyone is still monitoring this thread...

    Is the assumption here that this is an Android native MMS text message, or a web service? I tried the code, but although everything compiles and runs, it does not appear to be sending an MMS text message with the native Android text messenger... I need to "auto respond" to received SMS text messages in an application... I don't need a robust service, I only need this as a minor addon... thoughts or comments?

    Monday, March 1, 2021 1:06 AM
  • User393260 posted

    @Chris001

    So I am working on creating an app that uses MMS to send an audio file. I am currently going through your example because it appears to be the most complete example on the net (much thanks BTW. You might have just saved my bacon). The only other mostly complete example that I found was for java and it got messy.

    Anyways, I just want to check if your example was updated with the fixes that you talked about in the thread? Please let me know!

    If it is not already updated, would you be able to update it? I think that the community can greatly benefit if there was a functional example of how to implement MMS messaging programmatically (none of that sharing intent stuff. Does not count!!!!!).

    Friday, March 12, 2021 4:28 PM
  • User394194 posted

    Sorry I haven't updated my code on here. However, you can follow the thread above to make the changes in the appropriate places.

    The other thing I still have not figured out how to do is once I receive an MMS message, the proper way to store it in the local Android db so that its available to other apps than my own. In order to become the primary/default MMS provider on the phone you need to be able to intercept all the appropriate events as well store those in the db for others. Unfortunately, I haven't found any good documentation for how to do this in Xamarin.

    Saturday, March 13, 2021 6:31 PM
  • User393260 posted

    @Chris001

    Well reading through the thread it appears that the only thing that was changed was the FileProvider.GetURIFromFile()

    For me, I am only concerned about sending MMS and not receiving them.

    Sunday, March 14, 2021 10:52 PM
  • User393260 posted

    @Chris001

    Hello Chris, I am having an issue with the Fileprovider class. I am getting a null pointer exception error. I create a post on the MS QA site:

    https://docs.microsoft.com/en-us/answers/questions/317066/xamarin-droid-using-fileprovidergeturiforfile.html?childToView=319235#answer-319235

    Would you be able to take a quick look to see if I am missing anything obvious?

    Wednesday, March 17, 2021 6:52 PM
  • User393260 posted

    @emilsteen

    Do have a copy of the source that you got working? I have been trying to use the GetUriForFile function and I am constantly running into an Unable to get provider androidx.core.content.FileProvider error.

    Monday, March 22, 2021 5:33 PM
  • User256966 posted

    @Philm001

    Legacy code, sorry.

    But by only looking at your code at docs.microsoft.com, the only difference I can find is that I am using "MainActivity" as the first parameter to GetUriForFile().

    Wednesday, March 24, 2021 8:29 AM
  • User393260 posted

    @emilsteen
    I see, ok, thank you, I will give that a shot! But everything else looks the same correct?

    Wednesday, March 24, 2021 1:05 PM
  • User393260 posted

    Do you remember what the line of code was? I am trying to run use this line:

    Android.Net.Uri contentURI = AndroidX.Core.Content.FileProvider.GetUriForFile(MainActivity.this, CTX.PackageName + ".fileprovider", testFile);

    But it is giving me errors. I think it has to do with the MainActivity.this.

    Wednesday, March 24, 2021 2:38 PM