Android Question [SOLVED] Get details of the apps my app shares files with

JackKirk

Well-Known Member
Licensed User
Longtime User

JackKirk

Well-Known Member
Licensed User
Longtime User
The only way to do it is by finding the possible target apps with PackageManager.Query..., show them in your app and let the user choose the target app.
Erel,

https://developer.android.com/training/sharing/send#why-to-use-system-sharesheet

seems to be saying this is not a good approach.

Looking at:

https://developer.android.com/training/sharing/send#share-interaction-data

this seems to be getting what I am after via Intent.EXTRA_CHOSEN_COMPONENT and ComponentName

I could not find any hits searching the forum with "Intent.EXTRA_CHOSEN_COMPONENT"

This is the relevant part of my current code (I think):
B4X:
Private wrk_intent As Intent
...
'Copy downloaded video to shared folder
File.Copy(File.DirRootExternal & "/" & Gen_photovideo_album, wrk_hit.Tag_video & ".mp4", Starter.FileProvid_er.Shared_Folder, wrk_hit.Tag_video & ".mp4")

'Set up intent to share downloaded video with other apps
wrk_intent.Initialize(wrk_intent.ACTION_SEND, "")
wrk_intent.SetType("video/mp4")
              
wrk_intent.PutExtra("android.intent.extra.STREAM", Starter.FileProvid_er.GetFileUri(wrk_hit.Tag_video & ".mp4"))

'Flag 1 is FLAG_GRANT_READ_URI_PERMISSION, see:
'https://developer.android.com/reference/android/content/Intent.html#setFlags(int)
wrk_intent.Flags = 1

'WrapAsIntentChooser required, see:
'https://www.b4x.com/android/forum/threads/fileprovider-is-forcing-recipient-apps-to-become-default-apps.127775/#post-800506
wrk_intent.WrapAsIntentChooser("Share with")
StartActivity(wrk_intent)

Any help greatly appreciated...
 
Last edited:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
This will work in Android 5.1 (API 22)+:
B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
End Sub

Public Sub Initialize
   
End Sub

Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
End Sub


Private Sub Button1_Click
    Dim in As Intent
    in.Initialize(in.ACTION_SEND, "")
    in.PutExtra("android.intent.extra.TEXT", "testing...")
    in.SetType("text/plain")
    SendIntent(in)
End Sub

Private Sub SendIntent (in As Intent)
    Dim jo As JavaObject
    jo.InitializeNewInstance(Application.PackageName & ".b4xmainpage$MyBroadcastReceiver", Array(Me))
    StartActivity(jo.RunMethod("SendIntent", Array(in)))
End Sub

Private Sub ContentChooser_Receive (intent As Object)
    Dim in As Intent = intent
    If in.HasExtra("android.intent.extra.CHOSEN_COMPONENT") Then
        Dim jo As JavaObject = in
        jo = jo.RunMethod("getParcelableExtra", Array("android.intent.extra.CHOSEN_COMPONENT"))
        Log(jo.RunMethod("getClassName", Null))
        Log(jo.RunMethod("getPackageName", Null))
    End If
End Sub

#if Java
import android.content.*;
import android.app.*;
public static class MyBroadcastReceiver extends BroadcastReceiver
{
    private BA ba;
    private static boolean registered;
    public MyBroadcastReceiver(B4AClass target) {
        ba = target.getBA();
    }
    public Intent SendIntent (Intent share) {
        String shareAction = "content_chooser_result_13";
        Intent receiver = new Intent(shareAction);
        PendingIntent pi = PendingIntent.getBroadcast(ba.context, 0, receiver, PendingIntent.FLAG_UPDATE_CURRENT);
        share = Intent.createChooser(share, null, pi.getIntentSender());
        if (registered == false) {
            ba.context.registerReceiver(this, new IntentFilter(shareAction));
            registered = true;
        }
        return share;
    }
    @Override public void onReceive(Context context, Intent intent) {
          ba.raiseEventFromUI(null, "contentchooser_receive", intent);
  }
}

#End If

The code should be in a class. Tested with B4XPages.
 
Upvote 0

JackKirk

Well-Known Member
Licensed User
Longtime User
Erel, thanks for this but I have a problem trying to insert it in my pre-B4XPages app.

I have created a class Intenthdlr:
B4X:
Sub Class_Globals

End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
   
End Sub

Public Sub SendIntent (in As Intent)
    Dim jo As JavaObject
    jo.InitializeNewInstance(Application.PackageName & ".intenthdlr$MyBroadcastReceiver", Array(Me))
    StartActivity(jo.RunMethod("SendIntent", Array(in)))
End Sub                                                      '<<<<<<<<<<<<<<<<<<<<<<<<<<<<breakpoint here

Private Sub ContentChooser_Receive (intent As Object)
    Dim in As Intent = intent
    If in.HasExtra("android.intent.extra.CHOSEN_COMPONENT") Then
        Dim jo As JavaObject = in
        jo = jo.RunMethod("getParcelableExtra", Array("android.intent.extra.CHOSEN_COMPONENT"))
        Log(jo.RunMethod("getClassName", Null))
        Log(jo.RunMethod("getPackageName", Null))
    End If
End Sub

#if Java
import android.content.*;
import android.app.*;
public static class MyBroadcastReceiver extends BroadcastReceiver
{
    private BA ba;
    private static boolean registered;
    public MyBroadcastReceiver(B4AClass target) {
        ba = target.getBA();
    }
    public Intent SendIntent (Intent share) {
        String shareAction = "content_chooser_result_13";
        Intent receiver = new Intent(shareAction);
        PendingIntent pi = PendingIntent.getBroadcast(ba.context, 0, receiver, PendingIntent.FLAG_UPDATE_CURRENT);
        share = Intent.createChooser(share, null, pi.getIntentSender());
        if (registered == false) {
            ba.context.registerReceiver(this, new IntentFilter(shareAction));
            registered = true;
        }
        return share;
    }
    @Override public void onReceive(Context context, Intent intent) {
          ba.raiseEventFromUI(null, "contentchooser_receive", intent);
  }
}

#End If
and fire it with code like this in my main code:
B4X:
'Copy downloaded photo to shared folder
File.Copy(File.DirRootExternal & "/" & Gen_photovideo_album, wrk_hit.Tag_photo & ".jpg", Starter.FileProvid_er.Shared_Folder, wrk_hit.Tag_photo & ".jpg")

'Set up intent to share downloaded photo with other apps
wrk_intent.Initialize(wrk_intent.ACTION_SEND, "")
wrk_intent.SetType("image/jpeg")
               
wrk_intent.PutExtra("android.intent.extra.STREAM", Starter.FileProvid_er.GetFileUri(wrk_hit.Tag_photo & ".jpg"))

'Flag 1 is FLAG_GRANT_READ_URI_PERMISSION, see:
'https://developer.android.com/reference/android/content/Intent.html#setFlags(int)
wrk_intent.Flags = 1

Private wrk_intenthdlr As Intenthdlr
wrk_intenthdlr.Initialize
wrk_intenthdlr.SendIntent(wrk_intent)

If I run this in either Debug or Release I get a log message:

Ignoring event: contentchooser_receive

If I put a breakpoint on the End Sub statement of the Intnthdlr/SendIntent Public Sub I can make the ContentChooser_Receive sub fire under certain circumstances and generate the appropriate info I am after.

I have tried various Wait For strategies without success and am now out of ideas...
 
Upvote 0

JackKirk

Well-Known Member
Licensed User
Longtime User
Ignoring event: contentchooser_receive
After a lot of mucking around I managed to get Erel's code running in a non-B4XPages environment.

The problem in the previous post occurs because:
o intenthdlr/SendIntent runs and launches standard Android sharesheet which
o causes Main activity to lose focus (fires Main/Activity_Pause) which
o cans intenthdlr which
o means intenthdlr/ContentChooser_Receive never fires (and generates the "Ignoring event: contentchooser_receive" message)

The solution is to run intenthdlr via a service which is unaffected by the Main activity losing focus.

However this solution has thrown up another problem which I have put in a new thread:
https://www.b4x.com/android/forum/t...onment-that-yields-shared-app-details.128935/
 
Last edited:
Upvote 0
Top