Android Question Get file from email attachment

Javier Alonso

Member
Licensed User
Hi,

I'm trying to open an email attachment from my App, I have managed to create an intent listener and open an activity. The intent content is:

Action: android.intent.action.VIEW
GetData: content://gmail-ls/javier@gmail.com/messages/2672/attachments/0.1/BEST/false
GetExtra: null
ExtraStr: no extras

I have no idea how to "copy" the attached file into my app folder. The GetPathFromContentResult routine I found in these help pages either don't work for the attachment or maybe I'm using it the wrong way.

Help, please
Javier
 

Javier Alonso

Member
Licensed User
It is possible. I finally got it. My app opens when the user clics on email attachments of a predefined mimetype (mine ends in ".mb8") and copy the attached file to a local directory. First, we have to assigne the mimetype to our app in the manifest file, adding these lines:

B4X:
AddActivityText(myActivity,
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <action android:name="android.intent.action.EDIT" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data
       android:mimeType="application/octet-stream"
       android:host="*" 
       android:pathPattern=".*\\.xxx"
    />
</intent-filter>
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <action android:name="android.intent.action.EDIT" />
    <category android:name="android.intent.category.DEFAULT" />
    <data
       android:mimeType="application/xxx"
       android:host="*"
       android:pathPattern=".*\\.xxx"
    />
</intent-filter>)
Where xxx is the type chosen and myActivity is the activity that opens when the user clics on the attachment. Then, in the activity, we just write:

B4X:
    Dim Intent1 As Intent
    Intent1 = Activity.GetStartingIntent

    If Intent1.Action = "android.intent.action.VIEW" Then    ' The activity has been called from outside the app
       
        Dim jo As JavaObject
        Dim cd As String = jo.InitializeStatic("anywheresoftware.b4a.objects.streams.File").GetField("ContentDir")
        Dim UriString As String = intent1.GetData

        Dim Inp As InputStream  = File.OpenInput(cd , UriString)
        Dim Out As OutputStream = File.OpenOutput(myFolder, myFile, False)

        File.copy2(Inp, Out)
        Inp.Close
        Out.Close
    End if
What we cannot do, of course, is modifying the original attachment, but it can be copied elsewhere.
 

rtek1000

Active Member
Licensed User
It is possible. I finally got it. My app opens when the user clics on email attachments of a predefined mimetype (mine ends in ".mb8") and copy the attached file to a local directory. First, we have to assigne the mimetype to our app in the manifest file, adding these lines:

B4X:
AddActivityText(myActivity,
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <action android:name="android.intent.action.EDIT" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data
       android:mimeType="application/octet-stream"
       android:host="*"
       android:pathPattern=".*\\.xxx"
    />
</intent-filter>
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <action android:name="android.intent.action.EDIT" />
    <category android:name="android.intent.category.DEFAULT" />
    <data
       android:mimeType="application/xxx"
       android:host="*"
       android:pathPattern=".*\\.xxx"
    />
</intent-filter>)
Where xxx is the type chosen and myActivity is the activity that opens when the user clics on the attachment. Then, in the activity, we just write:

B4X:
    Dim Intent1 As Intent
    Intent1 = Activity.GetStartingIntent

    If Intent1.Action = "android.intent.action.VIEW" Then    ' The activity has been called from outside the app
      
        Dim jo As JavaObject
        Dim cd As String = jo.InitializeStatic("anywheresoftware.b4a.objects.streams.File").GetField("ContentDir")
        Dim UriString As String = intent1.GetData

        Dim Inp As InputStream  = File.OpenInput(cd , UriString)
        Dim Out As OutputStream = File.OpenOutput(myFolder, myFile, False)

        File.copy2(Inp, Out)
        Inp.Close
        Out.Close
    End if
What we cannot do, of course, is modifying the original attachment, but it can be copied elsewhere.
Hello,

I would like to get a attached file (apk) to update my app.

There is a way to do this with your code?

Thank you.
 

rtek1000

Active Member
Licensed User
It is possible. I finally got it. My app opens when the user clics on email attachments of a predefined mimetype (mine ends in ".mb8") and copy the attached file to a local directory. First, we have to assigne the mimetype to our app in the manifest file, adding these lines:

B4X:
AddActivityText(myActivity,
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <action android:name="android.intent.action.EDIT" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <data
       android:mimeType="application/octet-stream"
       android:host="*"
       android:pathPattern=".*\\.xxx"
    />
</intent-filter>
<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <action android:name="android.intent.action.EDIT" />
    <category android:name="android.intent.category.DEFAULT" />
    <data
       android:mimeType="application/xxx"
       android:host="*"
       android:pathPattern=".*\\.xxx"
    />
</intent-filter>)
Where xxx is the type chosen and myActivity is the activity that opens when the user clics on the attachment. Then, in the activity, we just write:

B4X:
    Dim Intent1 As Intent
    Intent1 = Activity.GetStartingIntent

    If Intent1.Action = "android.intent.action.VIEW" Then    ' The activity has been called from outside the app
      
        Dim jo As JavaObject
        Dim cd As String = jo.InitializeStatic("anywheresoftware.b4a.objects.streams.File").GetField("ContentDir")
        Dim UriString As String = intent1.GetData

        Dim Inp As InputStream  = File.OpenInput(cd , UriString)
        Dim Out As OutputStream = File.OpenOutput(myFolder, myFile, False)

        File.copy2(Inp, Out)
        Inp.Close
        Out.Close
    End if
What we cannot do, of course, is modifying the original attachment, but it can be copied elsewhere.
"Where xxx is the type chosen" what I have to type specifically, name of official email reader?

Thank you again.
 

Javier Alonso

Member
Licensed User
If it's an apk, the mimetype would normally be "application/octet-stream". If your app's intent opens when an apk attachment or file is clicked, android will open the installer and install the apk.

But getting the intent is not so straightforward as my previous post said, there is a lot of misinformation on intents. Look at this post, the last reply is valid and is probably the best working solution to open an email attachment from your app. The only thing missed in the post is to note that Gmail changes the mimetype of some attachments to "application/octet-stream".
 

Gearcam

Active Member
Licensed User
is there a specific part of the manifest this "AddActivityText(myActivity, ........"
Has to go in the application section ?
 
Top