locked
How to get sharing PDF file's path and open that in our Xamarin App ? RRS feed

  • Question

  • User383275 posted

    There is a problem I couldn't solve for a long time. I want to get a PDF file's path with the share button from another application to my application which I created with xamarin. I have tried somethings and those solved my problem but that wasn't like I wanted. That was; I downloaded the pdf to my phone storage. So there was a lot of pdf on my phone. After that, I can share those pdf with my app and I can see them in there. But that wasn't exactly what I want. Let's say there is an ABC application which has a lot of pdf. I want to open those pdf and share with my Xamarin App directly without storage them. I can explain this with an example: You have a PDF which you want to share with your friends. You open that Pdf and click the Share button. After that, you'll select which application you want to use like Whatsapp, E-Mail, Skype, Discord, etc. So, at last, you can send your pdf directly to another App without store.

    My code behind in main activity:

    protected override void OnCreate(Bundle savedInstanceState)
            {
                TabLayoutResource = Resource.Layout.Tabbar;
                ToolbarResource = Resource.Layout.Toolbar;
    
                base.OnCreate(savedInstanceState);
                ZXing.Net.Mobile.Forms.Android.Platform.Init();
                global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
                LoadApplication(new App());
    
                Intent intent = new Intent(Application.Context, typeof(MainActivity));
    
    
    
                var action = Intent.Action;
                var type = Intent.Type;
    
                if (Android.Content.Intent.ActionSend.Equals(action) &&
                    (type?.Equals("text/plain") ?? false))
                {
                    var path = Intent.GetStringExtra(Android.Content.Intent.ExtraText);
                    Console.WriteLine(path);
                }
    
    
                if (Android.Content.Intent.ActionSend.Equals(action) && (type?.Equals("application/pdf") ?? false))
                {
                    var uri = (Android.Net.Uri)Intent.GetParcelableExtra(Android.Content.Intent.ExtraStream);
                    Context context = Android.App.Application.Context;
                    var fullPath = GetFilePath(uri);               
                    Navigate(fullPath);
    
                }
            }
    

    What can I do about that? Thanks.

    Wednesday, July 3, 2019 12:19 PM

Answers

  • User383275 posted

    I have changed my code-behind like this :

    if (Android.Content.Intent.ActionSend.Equals(action) && (type?.Equals("application/pdf") ?? false))
                {
                    // This is just an example of the data stored in the extras 
                    var uriFromExtras = Intent.GetParcelableExtra(Intent.ExtraStream) as Android.Net.Uri;
                    var subject = Intent.GetStringExtra(Intent.ExtraSubject);
    
                    // Get the info from ClipData 
                    var pdf = Intent.ClipData.GetItemAt(0);
    
                    // Open a stream from the URI 
                    var pdfStream = ContentResolver.OpenInputStream(pdf.Uri);
    
                    // Save it over 
                    var memOfPdf = new System.IO.MemoryStream();
                    pdfStream.CopyTo(memOfPdf);
                    var docsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                    var filePath = System.IO.Path.Combine(docsPath, "temp.pdf");
    
                    System.IO.File.WriteAllBytes(filePath, memOfPdf.ToArray());
    
                    Navigate(filePath);
    
                }
    

    and it works. Hope it helps someone.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Tuesday, July 9, 2019 9:04 AM

All replies

  • User371688 posted

    Could you please share a basic demo so that we can test with it?

    Thursday, July 4, 2019 9:58 AM
  • User383275 posted

    This is my OnCreate method in MainActivity:

                [IntentFilter(new[] { Intent.ActionSend }, Categories = new[] { Intent.CategoryDefault }, DataMimeType = @"application/pdf")]    
    
                Intent intent = new Intent(Application.Context, typeof(MainActivity));
    
    
                var action = Intent.Action;
                var type = Intent.Type;
    
        if (Android.Content.Intent.ActionSend.Equals(action) && (type?.Equals("application/pdf") ?? false))
                        {
                            var uri = (Android.Net.Uri)Intent.GetParcelableExtra(Android.Content.Intent.ExtraStream);
                            var fullPath = GetFilePath(uri);
                            Navigate(fullPath);
                        }
    

    GetFilePath method in MainActivity:

            private string GetFilePath(Android.Net.Uri uri)
                {            
                        string[] proj = { MediaStore.Images.ImageColumns.Data };
                        var cursor = ContentResolver.Query(uri, proj, null, null, null);
                        var colIndex = cursor.GetColumnIndex(MediaStore.Images.ImageColumns.Data);
                        cursor.MoveToFirst();
                        return cursor.GetString(colIndex);       //I got this error in this line: java.Lang.IllegalStateException: Couldn't read row 0, col -1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.   
                }
    

    and AndroidManifest.xml:

        <activity android:name=".main">
          <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="text/plain" />
          </intent-filter>
          <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="image/*"/>
          </intent-filter>
          <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="application/pdf" />
          </intent-filter>
          <intent-filter>
            <action android:name="android.intent.action.SEND" />
            <category android:name="android.intent.category.DEFAULT" />
            <data android:mimeType="application/x-pdf" />
          </intent-filter>
        </activity>
    
    Thursday, July 4, 2019 12:50 PM
  • User383275 posted

    I have changed my code-behind like this :

    if (Android.Content.Intent.ActionSend.Equals(action) && (type?.Equals("application/pdf") ?? false))
                {
                    // This is just an example of the data stored in the extras 
                    var uriFromExtras = Intent.GetParcelableExtra(Intent.ExtraStream) as Android.Net.Uri;
                    var subject = Intent.GetStringExtra(Intent.ExtraSubject);
    
                    // Get the info from ClipData 
                    var pdf = Intent.ClipData.GetItemAt(0);
    
                    // Open a stream from the URI 
                    var pdfStream = ContentResolver.OpenInputStream(pdf.Uri);
    
                    // Save it over 
                    var memOfPdf = new System.IO.MemoryStream();
                    pdfStream.CopyTo(memOfPdf);
                    var docsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                    var filePath = System.IO.Path.Combine(docsPath, "temp.pdf");
    
                    System.IO.File.WriteAllBytes(filePath, memOfPdf.ToArray());
    
                    Navigate(filePath);
    
                }
    

    and it works. Hope it helps someone.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Tuesday, July 9, 2019 9:04 AM