Android Question Force app to use gmail

marcick

Well-Known Member
Licensed User
Longtime User
Hi all.
I have this piece of code to send email:

B4X:
        Dim mailc As Email
        mailc.Subject = ("subject")
        mailc.Body="body"
        mailc.Attachments.add(File.Combine(File.DirDefaultExternal,  Export_FileName &".txt"))
        StartActivity(mailc.GetIntent)

It works fine if the user use Gmail, but some user have as predefined action, different app to manage email. And in most cases the above code fails to add the attachment (looks like the attachment is visibile in the page where the user has to declare the desination email and click "send", but the attachment does not arrive to destination).
How to solve ?
Is that possible to force the App to use Gmail regardless of the predefined options ?
 

MarkusR

Well-Known Member
Licensed User
Longtime User
above code fails to add the attachment
i guess if you make a file exists before if will answer no because permissions?

this is my try. see also PackageManager object/class
B4X:
Sub MailOut2_Click

    Dim p As Email
    p.Body="Body"
    p.Subject="Subject"
    p.To.Add("[email protected]")

    Dim i As Intent
    i = p.GetHtmlIntent
    i.Setcomponent("com.google.android.gm")
    i.SetType("message/rfc822")

    StartActivity(i)
 
End Sub
 
Upvote 0

marcick

Well-Known Member
Licensed User
Longtime User
i guess if you make a file exists before if will answer no because permissions?

this is my try. see also PackageManager object/class
B4X:
Sub MailOut2_Click

    Dim p As Email
    p.Body="Body"
    p.Subject="Subject"
    p.To.Add("[email protected]")

    Dim i As Intent
    i = p.GetHtmlIntent
    i.Setcomponent("com.google.android.gm")
    i.SetType("message/rfc822")

    StartActivity(i)
 
End Sub

Not very clear your answer, but with your code the attachment never arrive to destination (tested bot Android Email and Gmail)
With my code at least I have success if I choose Gmail
 
Upvote 0

BillMeyer

Well-Known Member
Licensed User
Longtime User
Take a look here https://www.b4x.com/android/forum/threads/b4x-sending-emails-with-gmail-rest-api.81736/ - This could help
or check post #2 here https://www.b4x.com/android/forum/threads/sending-email-attachments.8291/

I had a similar problem and after much searching found out that SDK >23 will give you problems with attached files in email espcially if you intend to use intents to send the email.

Here is some untested code that you might like to look through (various sources on this forum - not all my work). Basically you create a shared safe space in your starter service, and then place the attached file there (only one at a time) and allow your desired email intent to load it from there for sending (my clue - you say that it looks like it is sending it but the attachment does not arrive) - you need to make sure that your runtime permissions etc are all in order.

Here's the code - REMEMBER - It's untested and could have errors in it but is intended for educational purposes only.
B4X:
' Starter Service Code
Sub Process_Globals
    Public shared As String
    Public rp As RuntimePermissions

End Sub

Sub Service_Create
    DisableStrictMode
    shared = rp.GetSafeDirDefaultExternal("shared")

End Sub

Sub DisableStrictMode
    Dim jo As JavaObject
    jo.InitializeStatic("android.os.Build.VERSION")
    If jo.GetField("SDK_INT") > 9 Then
        Dim policy As JavaObject
        policy = policy.InitializeNewInstance("android.os.StrictMode.ThreadPolicy.Builder", Null)
        policy = policy.RunMethodJO("permitAll", Null).RunMethodJO("build", Null)
        Dim sm As JavaObject
        sm.InitializeStatic("android.os.StrictMode").RunMethod("setThreadPolicy", Array(policy))
    End If
End Sub

And here is the code to start the intent and send the email (includes a Dialog Screen for the user to choose their desired email)

B4X:
Sub Globals
    Dim email As Email

End Sub

Sub CreateFileProviderUri (Dir As String, FileName As String) As Object
    Dim FileProvider As JavaObject
    Dim context As JavaObject
    context.InitializeContext
    FileProvider.InitializeStatic("android.support.v4.content.FileProvider")
    Dim f As JavaObject
    f.InitializeNewInstance("java.io.File", Array(Dir, FileName))
    Return FileProvider.RunMethod("getUriForFile", Array(context, Application.PackageName & ".provider", f))
End Sub

Sub ForceMediaScan(dir As String, filename As String)
    Dim Phone As Phone
    Dim i As Intent
    i.Initialize("android.intent.action.MEDIA_SCANNER_SCAN_FILE", "content://" & File.Combine(dir, filename))
    Phone.SendBroadcastIntent(i)
    
End Sub

Sub SendNewMail
    File.Copy(Path1, GlobFileName, Starter.shared, GlobFileName) 'Put the file in a shared space ready for attaching
    Dim SendTo As String = Starter.kvs.Get("FaveMail")
    Dim SendBody As String = "Please prepare this script and contact me once it is complete and ready for delivery or collection."&CRLF&CRLF&"I do understand that I can only receive my medication on presentation of the original script"
    Dim SendSub As String = "New Script for: "&Starter.kvs.get("UserName")&" - "&Starter.kvs.get("IdNumber")
    SendEmail (SendTo, SendBody, SendSub, File.Combine(Starter.shared, GlobFileName ))

End Sub

Sub SendEmail (SendTo As String, SendBody As String, SendSub As String, SendAtt As String)
    Dim FinalEmailIntent As Intent, sPackageName As String
    LogColor("Send Att: "&SendAtt,Colors.Magenta)

    If SendAtt = "" Then ' Use new method - will not work with attachments
        File.Copy(Path1, GlobFileName, Starter.shared, GlobFileName)
        Log("11111")
        FinalEmailIntent.Initialize("android.intent.action.SENDTO", "mailto:" & SendTo)
        FinalEmailIntent.putExtra("android.intent.extra.SUBJECT", SendSub)
        FinalEmailIntent.putExtra("android.intent.extra.TEXT", SendBody)
        FinalEmailIntent.PutExtra("android.intent.category.DEFAULT",  CreateFileProviderUri(Starter.shared, GlobFileName))
        FinalEmailIntent.Flags = 1
        FinalEmailIntent.WrapAsIntentChooser("Send E-mail")
    Else ' Make our own list of email apps
        Log("22222")
    sPackageName = GetEmailPackage
    If sPackageName = "/cancel/" Then Return
    If sPackageName = "" Then
        Msgbox ("Unable to send email.", "")
        Return
    End If
       Log("33333")     
    Dim MyEmail As Email
    MyEmail.To.Add (SendTo)
    MyEmail.Body = SendBody
    MyEmail.Subject = SendSub
    MyEmail.Attachments.Add(SendAtt)
    FinalEmailIntent = MyEmail.GetIntent
    FinalEmailIntent.SetComponent (sPackageName)
    End If

    StartActivity (FinalEmailIntent)

End Sub

Sub GetEmailPackage As String
    Dim PM As PackageManager, DummyIntent As Intent, DummyIntent2 As Intent
    Dim EmailActivities As List, EmailAppNames As List, iPackage As Int, x As Int, tempString As String
    EmailActivities.Initialize: EmailAppNames.Initialize
    
    DummyIntent.Initialize("android.intent.action.SENDTO", "mailto:[email protected]")
    EmailActivities = PM.QueryIntentActivities (DummyIntent)

    If EmailActivities.Size = 0 Then
        DummyIntent2.Initialize("android.intent.action.SENDMULTIPLE", "")
        DummyIntent2.SetType ("message/rfc822")
        EmailActivities = PM.QueryIntentActivities (DummyIntent2)
    End If

    If EmailActivities.Size = 0 Then Return ""

    ' Get app labels & icons
    For x = 0 To EmailActivities.Size - 1
        Dim imgIcon As BitmapDrawable
        Dim sPackageName As String = EmailActivities.Get(x)
        sPackageName = sPackageName.SubString2 (0, sPackageName.IndexOf ("/"))
        tempString = PM.GetApplicationLabel(sPackageName)
        imgIcon = PM.GetApplicationIcon(sPackageName) 'App icon if desired
        EmailAppNames.Add (tempString)
    Next

    iPackage = InputList (EmailAppNames,"Send email using",-1)
    If iPackage = DialogResponse.CANCEL Then Return "/cancel/"

    Return EmailActivities.Get (iPackage)

End Sub

I hope this points you in the right direction.

Enjoy !!
 
Upvote 0

MarkusR

Well-Known Member
Licensed User
Longtime User
the attachment never arrive
with this source i have success and see the attachment arrived at pc.
B4X:
Sub MailOut2_Click

    Dim rp As RuntimePermissions

    Dim p As Email
    p.Body="Inhalt"
    p.Subject="Betreff"
    p.To.Add("[email protected]")
    Dim Att As List
    Att.Initialize
    Dim File1 As String
    
    Log(rp.GetSafeDirDefaultExternal(""))
    
    File.WriteString(rp.GetSafeDirDefaultExternal(""),"test.txt","Hallo")

    If File.Exists(rp.GetSafeDirDefaultExternal(""),"test.txt") =False Then
        ToastMessageShow("attachment file not found",False)
    End If

    File1=File.Combine(rp.GetSafeDirDefaultExternal(""),"test.txt")
    
    Att.Add(File1)
    p.Attachments = Att

    Dim i As Intent
    i = p.GetHtmlIntent
    i.Setcomponent("com.google.android.gm")
    i.SetType("message/rfc822")

    StartActivity(i)
    
End Sub

B4X:
AddManifestText(<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
)
 
Upvote 0

BillMeyer

Well-Known Member
Licensed User
Longtime User
with this source i have success and see the attachment arrived at pc.
B4X:
Sub MailOut2_Click

    Dim rp As RuntimePermissions

    Dim p As Email
    p.Body="Inhalt"
    p.Subject="Betreff"
    p.To.Add("[email protected]")
    Dim Att As List
    Att.Initialize
    Dim File1 As String
   
    Log(rp.GetSafeDirDefaultExternal(""))
   
    File.WriteString(rp.GetSafeDirDefaultExternal(""),"test.txt","Hallo")

    If File.Exists(rp.GetSafeDirDefaultExternal(""),"test.txt") =False Then
        ToastMessageShow("attachment file not found",False)
    End If

    File1=File.Combine(rp.GetSafeDirDefaultExternal(""),"test.txt")
   
    Att.Add(File1)
    p.Attachments = Att

    Dim i As Intent
    i = p.GetHtmlIntent
    i.Setcomponent("com.google.android.gm")
    i.SetType("message/rfc822")

    StartActivity(i)
   
End Sub

B4X:
AddManifestText(<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
)

Your code is much less complicated than mine - Thank you - I will refer to it rather in the future.
 
Upvote 0
Top