Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] [Improve] #83

Closed
AndreiMisiukevich opened this issue Apr 13, 2018 · 5 comments
Closed

[Question] [Improve] #83

AndreiMisiukevich opened this issue Apr 13, 2018 · 5 comments
Labels

Comments

@AndreiMisiukevich
Copy link

AndreiMisiukevich commented Apr 13, 2018

Hi, thanks for you work

What do you think about providing ability to move files from external storage to internal one?
It can be achieved by adding a reciever class
something like this.. by the way, it would be better to make DownloadManager field as open for avoiding reflection =)

    public class DownloadFileReceiver : BroadcastReceiver
    {
        private const string RedundantFilePrefix = "file://";

        private DownloadManager _manager;
        private DownloadManager Manager => _manager ?? (_manager = typeof(DownloadManagerImplementation).GetTypeInfo().GetField("_downloadManager", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(CrossDownloadManager.Current) as DownloadManager);

        public string RealPath { get; set; } = Environment.GetFolderPath(Environment.SpecialFolder.Personal);

        public override void OnReceive(Context context, Intent intent)
        {
            var action = intent.Action;

            if (action == DownloadManager.ActionDownloadComplete)
            {
                var query = new DownloadManager.Query();
                query.SetFilterById(intent.GetLongExtra(DownloadManager.ExtraDownloadId, 0));

                var cursor = Manager.InvokeQuery(query);

                if (cursor.MoveToFirst())
                {
                    var status = cursor.GetInt(cursor.GetColumnIndex(DownloadManager.ColumnStatus));
                    if (status == (int)DownloadStatus.Successful)
                    {
                        var downloadedPath = cursor.GetString(cursor.GetColumnIndex(DownloadManager.ColumnLocalUri));
                        downloadedPath = downloadedPath.Replace(RedundantFilePrefix, string.Empty);
                        var fileName = downloadedPath.Split('/').Last();

                        var realPath = Path.Combine(RealPath, fileName);
                        File.Move(downloadedPath, realPath);
                    }
                }
            }
        }
    }

And another suggestion is adding FileName property to IDownloadFile interface.. it would be more comfortable to have it, when PathNameForDownloadedFile is calling

@SimonSimCity
Copy link
Owner

SimonSimCity commented Apr 14, 2018

Hi, Andrei

Just to answer your questions one-by-one:

Moving the file from internal to external storage

This should be covered by the readme already. Please read through the section https://github.com/SimonSimCity/Xamarin-CrossDownloadManager#recommended-option---custom-location and tell me what you're missing there.

it would be better to make DownloadManager field as open for avoiding reflection

Android, iOS and Windows Phone have quite different approaches here to inform you when a file has finished downloading. You are adding a BroadcastReceiver here which is Android specific - exactly what this library wants to cover for you.

It rather wants you to set up a property-changed-listener which will inform you when the file was downloaded successfully. Here's an example: https://github.com/SimonSimCity/Xamarin-CrossDownloadManager/blob/develop/Sample/Droid/MainActivity.cs#L102. You can find the libraries BroadcastReceiver here: https://github.com/SimonSimCity/Xamarin-CrossDownloadManager/blob/develop/DownloadManager/Plugin.DownloadManager.Android/DownloadCompletedBroadcastReceiver.cs

Even if you would copy my BroadcastReceiver, you would not need any reflections ...

And another suggestion is adding FileName property to IDownloadFile interface

What file name are we now talking about here? When you download the file, it has a URL, which could already be your desired file name. If this is the case, you could take the code from this sample: https://github.com/SimonSimCity/Xamarin-CrossDownloadManager/blob/develop/Sample/Droid/MainActivity.cs#L18-L23

If you want to get the file name provided in the HTTP request (like it was asked here: https://stackoverflow.com/questions/13307499/http-download-file-name) I don't know if there is an option to do this reliably on all platforms since I don't get hands on the response-headers of the request you're sending - specially not on Android. This would then have to wait until #34 is done.

Does this already answer the questions you have here?

@AndreiMisiukevich
Copy link
Author

@SimonSimCity Hi

As for the first point
You said "Moving the file from INTERNAL to EXTERNAL storage", but i meant from EXTERNAL to INTERNAL.

So, as you noticed Android's download manager can save files only at external storage, but if I want to store them in INTERNAL one, i will have to register BroadcastReceiver for moving them to INTERNAL, won't I ?

So, I suggested to add default BroadcastReceiver =)

@AndreiMisiukevich
Copy link
Author

As for the third
I don't want to use url as FileName, i want to pass desired file name before downloading.
Now, I can do it via headers.. but it's trick..

@SimonSimCity
Copy link
Owner

If you want to get it by headers, I hope your server supports HEAD requests 😅.

As the readme states, the download-manager of Android can't download to the internal storage, because the download-manager actually is a completely separate application, provided by the android system.

And because it's Android specific, I've left it up to you to implement it.

If you see anything you would like to change, I'd be more than happy to work out a solution together with you after you've sent me a prototype as pull-request.

@AndreiMisiukevich
Copy link
Author

Deal)
So, i think it can be closed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants