Questions » Recent Q&A » Xamarin.Android Email Attachment

Xamarin.Android Email Attachment

Posted Jul 02 2018, 7:35 PM
  • Are you able to create an email without an attachment?  I just want to verify if the issue is just with the attachment, creating a draft email or both.  Note that the attachment must be stored in the BlackBerry Dynamics secure file system before using the SendMail service.  Here's some sample code for using the SendMail service on Android...

     

    public class ConsumeSendEmail implements GDServiceClientListener

    {

        /* Constants for service request fixed parts.

         */

        private static String serviceId = "com.good.gfeservice.send-email";

        private static String serviceVersion = "1.0.0.0";

        private static String serviceMethod = "sendEmail";

     

        /** getProvider - Get the service provider native application identifier.

         * Call this function to retrieve the native application identifier of the

         * service provider application. The value is obtained by executing an

         * AppKinetics service discovery query.

         *

         * This function is called by the sendRequest function, and need not be 

         * called separately.

         *

         * \param transcript StringBuilder to which a transcript is to be appended.

         *                   If a non-null value is passed, a description of the 

         *                   processing that took place will be appended, including

         *                   any error conditions encountered.

         * \return String containing the native application identifier.

         */

        public String getProvider(StringBuilder transcript)

        {

            String provider = null;

            // Execute an AppKinetics service discovery query.

            Vector<GDAppDetail> provider_details = GDAndroid.getInstance()

                    .getApplicationDetailsForService(serviceId, serviceVersion);

            if (provider_details.size() > 0) {

                // Take the first provider on the returned list.

                provider = provider_details.firstElement().getAddress();

            }

            

            // Create transcript, if requested.

            if (transcript != null) {

                transcript.append(

                        "getApplicationDetailsForService(" + serviceId + "," +

                         serviceVersion + ") return count: " + 

                         provider_details.size() );

                for (int i=0; i<provider_details.size(); i++) {

                    GDAppDetail provideri = provider_details.elementAt(i);

                    transcript.append(

                            "\napplicationId \"" + provideri.getApplicationId() +

                            "\", name \"" + provideri.getName() + "\", address \"" +

                            provideri.getAddress() + "\", versionId \"" +

                            provideri.getVersionId() + "\"" );

                }

                transcript.append("\nUsing: \"" + provider + "\"\n");

            }

            return provider;

           

        }

        

        private String transcribe(GDServiceException e)

        {

            return "Code: " + e.errorCode() + " \"" + e.getMessage() + "\"";

        }

        /** Send a service request with no attachments.

         * Calling this function is equivalent to calling sendRequest() and

         * specifying null for attachments.

         */

        public String sendRequest(Object parameters, StringBuilder transcript)

        {

            return sendRequest(parameters, null, transcript);

        }

        /** sendRequest - Send a service request.

         * Call this function to send an AppKinetics service request. Service

         * request parameters and attachments are specified as parameters to this

         * function.

         *

         * This function executes an AppKinetics service discovery query to retrieve

         * the details of the service provider application.

         *

         * Parameter keys and attachments are as specified in the

         * com.good.gfeservice.send-email service definition. See

         * https://community.good.com/marketplace-service-details.jspa?serviceVersionId=855081&serviceId=855115&appSvcsContainerID=2003

         *

         * The DiagnosticSendEmail module contains an example call to this function

         * that illustrates usage of all parameter keys, and attachments.

         *

         * \param transcript StringBuilder to which a transcript is to be appended.

         *                   If a non-null value is passed, a description of the 

         *                   processing that took place will be appended, including

         *                   any error conditions encountered.

         * \param parameters Object containing the service request parameters.

         * \param attachments String array containing the service request file

         *                    attachments.

         * \returns String containing the service request identifier.

         */

        public String sendRequest(

                Object parameters, String attachments[], StringBuilder transcript)

        {

            String provider = getProvider(transcript);

            if (provider == null) {

                // No service provider found. Give up.

                return null;

            }

     

            try {

                GDServiceClient.setServiceClientListener(this);

            } catch (GDServiceException e) {

                if (transcript != null) {

                    transcript.append(

                            "Failed to set listener. " + transcribe(e) + "\n");

                }

            }

            String reqid = null;

            try {

                reqid = GDServiceClient.sendTo(provider,

                        serviceId, serviceVersion, serviceMethod,

                        parameters, attachments,

                        GDICCForegroundOptions.PreferPeerInForeground);

            } catch (GDServiceException e) {

                if (transcript != null) {

                    transcript.append( "Failed to submit request to \"" + provider 

                            + "\". " + transcribe(e) + "\n");

                }

            }

            if (reqid != null && transcript != null) {

                transcript.append("Request submitted OK. Request ID: \"" +

                        reqid + "\"\n" );

            }

            return reqid;

        }

        @Override

        public void onMessageSent(String arg0, String arg1, String[] arg2) {

            // TODO Auto-generated method stub

        }

        @Override

        public void onReceivingAttachments(String s, int i, String s1)

        {

        }

        @Override

        public void onReceivingAttachmentFile(String s, String s1, long l, String s2)

        {

        }

        @Override

        public void onReceiveMessage(String arg0, Object arg1, String[] arg2,

                String arg3) {

            // TODO Auto-generated method stub

        }

    }

    And then to use it...

     

    consumeSendEmail = new ConsumeSendEmail();

    consumeSendEmail.sendRequest(

            new ParameterMap()

                    .build("to", buildArrayList(

                            reportEmailAddress))

                    .build("subject", subject)

                    .build("body", description.getText())

                    .toMap(),

            null, transcript);

  • Yes, I can create an email without an attachment. My code still creates an email with my attachment code (so no error) but nothing is ever attached. Here's my email function.

     

            public void SendEmail(string[] ToEmails, string[] CCEmails, string[] BCCEmails, string subject, string body, string[] attachments = null)
            {
                HashMap map = new HashMap();

                map.Put("to", new ArrayList(ToEmails));
                map.Put("subject", subject);
                map.Put("body", body);

                try
                {
                    GDServiceClient.SendTo(
                                        "com.good.gcs",
                                        "com.good.gfeservice.send-email",
                                        "1.0.0.0",
                                        "sendEmail",
                                        map,
                                        BuildEmailAttachment(attachments),
                                        GDICCForegroundOptions.PreferPeerInForeground);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

  • You don't need to use GDFileSystem.GetAbsoluteEncryptedPath.  Just pass in the name of the file as a String array.  I used the code below to copy a .txt file from the assets folder of my app.  I could then pass a String array containing FILENAME as the attachmetn parameter in the GDServiceClient.SendTo.

    Note, the code below is not thread safe.  It's OK to call on the event thread for testing with small files.  But don't use it in production to copy large files.

    private void copyFile()
    {
        try
        {
            //Copy a video file and store it in the BD file system
            //TODO  Update the path below to point to a video on your device.
            BufferedReader reader = new BufferedReader(
                    new InputStreamReader(getAssets().open(FILENAME)));
            FileOutputStream out =
                    GDFileSystem.openFileOutput(FILENAME, Context.MODE_PRIVATE);

            String mLine;
            while ((mLine = reader.readLine()) != null)
            {
                //process line
                out.write(mLine.getBytes(), 0, mLine.length());
            }

            reader.close();
            out.close();

            Log.d("Attachment File:", "File copied");

        }
        catch(Exception e)
        {
            Log.d("Attachment File:", "Failed to copy:" + e.toString());
        }
    }

  • Thank you for this. I was able to use what you supplied and make it work in my app. Here's the final version of my function.

            private string[] BuildEmailAttachment(string[] attachments)
            {
                try
                {
                    Com.Good.GD.File.FileOutputStream outstream = GDFileSystem.OpenFileOutput("SecurePicture.PNG", GDFileSystem.ModePrivate);
                    byte[] decodedString = Android.Util.Base64.Decode(attachments[0], Android.Util.Base64Flags.Default);
                    outstream.Write(decodedString);
                    outstream.Close();

                    return new string[1] { "SecurePicture.PNG" };
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

Back