Android Question [SOLVED] Problem with sharing files in a non-B4XPages environment that yields shared app details

JackKirk

Well-Known Member
Licensed User
Longtime User
As alluded to in:
https://www.b4x.com/android/forum/t...s-my-app-shares-files-with.128681/post-808993

Attached is an example of how to share files with other apps in a non-B4XPages environment that yields the shared app's details.

This works but there is a problem - it only works repeatedly if you never stop the service.

I will show each module so I can explain the problem...

Main activity
B4X:
#Region  Activity Attributes
    #FullScreen: False
    #IncludeTitle: True
#End Region

Sub Process_Globals

    Public Gen_intent As Intent

End Sub

Sub Globals

End Sub

Sub Activity_Create(FirstTime As Boolean)

End Sub

Sub Activity_Resume
    
'    StopService(Sharing_Service)
    
    Log("Activity_Resume")
    
    Gen_intent.Initialize(Gen_intent.ACTION_SEND, "")
    Gen_intent.PutExtra("android.intent.extra.TEXT", "testing...")
    Gen_intent.SetType("text/plain")
    
    StartService(Sharing_Service)

End Sub

Private Sub Activity_Pause(UserClosed As Boolean)
    
    Log("Activity_Pause")
    
End Sub

Sharing_Service
B4X:
#Region  Service Attributes
    #StartAtBoot: False
    #ExcludeFromLibrary: True
#End Region

Private Sub Process_Globals

End Sub

Private Sub Service_Create

End Sub

Private Sub Service_Start (StartingIntent As Intent)

    'Fire up Sharing_Class
    Private wrk_sharingclass As Sharing_Class
    wrk_sharingclass.Initialize
    
    wrk_sharingclass.SendIntent(Main.Gen_intent)
    
End Sub

Public Sub Service_Destroy
    
    StopService(Me)
    
End Sub

Sharing_Class
B4X:
Sub Class_Globals

End Sub

Public Sub Initialize
  
End Sub

Public Sub SendIntent (in As Intent)
    Dim jo As JavaObject
    jo.InitializeNewInstance(Application.PackageName & ".sharing_class$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
    
'    CallSubDelayed(Sharing_Service, "Service_Destroy")
'    StopService(Sharing_Service)
    
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

I believe, for the sake of good housekeeping if nothing else, that the Sharing_Service should be stopped each time you are finished with it.

But it doesn't seem to matter where you attempt to do this:
o [StopService(Sharing_Service)] at start of Main.Activity_Resume
o [CallSubDelayed(Sharing_Service, "Service_Destroy")] or [StopService(Sharing_Service)] at end of Sharing_Class.ContentChooser_Receive

The result is the same - Sharing_Class.ContentChooser_Receive is never called again during subsequent shares - even though the Android sharesheet is raised and used.

Can anyone help with this - otherwise I believe I have a very unstable solution...
 

Attachments

  • Sharing.zip
    9.5 KB · Views: 245
Last edited:

JackKirk

Well-Known Member
Licensed User
Longtime User
Erel, can I get you to look over this - I have conducted some major surgery on your java code - and I don't know java.

I have found a solution - I think - that causes Sharing_Class.ContentChooser_Receive to be called every time even when the Sharing_Service is stopped after every share.

Erel's original java:
B4X:
#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
My modified java:
B4X:
#if Java
import android.content.*;
import android.app.*;
public static class MyBroadcastReceiver extends BroadcastReceiver
{
    private BA ba;
    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());
        ba.context.registerReceiver(this, new IntentFilter(shareAction));
        return share;
    }
    @Override public void onReceive(Context context, Intent intent) {
        ba.raiseEventFromUI(null, "contentchooser_receive", intent);
        ba.context.unregisterReceiver(this);
    }
}

#End If

The differences are:
(1) removal of any code to do with the flag "registered"
(2) addition of the statement "ba.context.unregisterReceiver(this);"

As I have only the scantiest idea what I'm doing I would appreciate any java boffins going over this for any idiot mistakes...

Attached is a running example.
 

Attachments

  • Sharing2.zip
    9.5 KB · Views: 216
Upvote 0
Top