0

Until today I never thought in order to download file from Urls, one needs to implement the Interface Download Listener on his Activity class. I have a webview in Xamarin Android, and I can't seem to download files.. figured that's because i haven't implemented this interface Download Listener on my class..So i gave it a try but i cant seem to connect the Interface implementing method with the OnDwnloadStart method, i figure when i request a download from a web page then the IDownloadListener method does nothing coz it has no code....But the code that should handle a download request is in the OnDownloadStart method with url, ContentDisposition and mimetype parameters,Any hep making the interface call OnDownloadStart method will surely be appreciated..Here is the code that i used...

class Internet : AppCompatActivity,IDownloadListener
    {
       protected override void OnCreate(Bundle savedInstanceState)
        {

            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            SetContentView(Resource.Layout.Browser);
           //Webview definition
         webview = this.FindViewById<WebView>(Resource.Id.webview1);
           //webview properties
            webview.SetWebViewClient(new WebViewClient());
            WebSettings webSettings = webview.Settings;
            webSettings.SetSupportMultipleWindows(true);
            webSettings.SetEnableSmoothTransition(true);
            webSettings.JavaScriptEnabled = true;
            webSettings.DomStorageEnabled = true;
            webSettings.AllowFileAccessFromFileURLs = true;
            // webSettings.JavaScriptEnabled.
            webview.SetDownloadListener(this);
      }
     //Interface Download Listener Method
       public interface IDownloadListener : Android.Runtime.IJavaObject, IDisposable
        {
         //I got nothing here and this is what i think needs to call OndownloadStart  
        }
      //implementing OnDownloadStart Method
       public void OnDownloadStart(string url, string userAgent, string contentDisposition, string mimetype, long contentLength)
        {
            DownloadManager.Request request = new DownloadManager.Request(Android.Net.Uri.Parse(url));
            String cookies = CookieManager.Instance.GetCookie(url);
            request.AddRequestHeader("cookie", cookies);
            request.AddRequestHeader("User-Agent", userAgent);
            request.SetDescription("Downloading file to crn folder...");
            request.SetTitle(URLUtil.GuessFileName(url, contentDisposition, mimetype));
            request.AllowScanningByMediaScanner();
            request.SetNotificationVisibility(Android.App.DownloadVisibility.VisibleNotifyCompleted);
            File dest = new File(Android.OS.Environment.RootDirectory + "download");
            if (!dest.Exists())
            {
                if (!dest.Mkdir())
                { Log.Debug("TravellerLog ::", "Problem creating Image folder"); }
            }
            request.SetDestinationInExternalFilesDir(Application.Context, "download", 
       URLUtil.GuessFileName(url, contentDisposition, mimetype));
            DownloadManager manager = 
       (DownloadManager)GetSystemService(Android.App.Application.DownloadService);
            manager.Enqueue(request);
            //Notify if success with BroadCast Receiver
        }
}

Which part of this code is running wrong? Any help is appreciated..

  • you don't need to define your own IDownloadListener interface, you need to provide an implementation of it – Jason Sep 27 '20 at 16:37
  • @Jason, How exactly do I do that? –  Sep 27 '20 at 16:43
  • remove `public interface IDownloadListener...` – Jason Sep 27 '20 at 16:44
  • What about the ```method```,```OnDownloadStart```, how do i implement it? –  Sep 27 '20 at 16:47
  • 1
    you already have an implementation of that. If you don't understand how C# Interfaces work, take the time to read the docs. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interfaces/ – Jason Sep 27 '20 at 16:49
  • Cool, so the Interface declaration in the class is enough to make it work? –  Sep 27 '20 at 16:50

1 Answers1

1

You don't need to create a new IDownloadListener interface, IDownloadListener interface is a system IDownloadListener under namespace Android.Webkit:

namespace Android.Webkit
{
    [Register("android/webkit/DownloadListener", "", "Android.Webkit.IDownloadListenerInvoker", ApiSince = 1)]
    public interface IDownloadListener : IJavaObject, IDisposable, IJavaPeerable
    {
        void OnDownloadStart(string url, string userAgent, string contentDisposition, string mimetype, long contentLength);
    }
}

Any class or struct that implements the IDownloadListener interface must contain a definition for an Equals method that matches the OnDownloadStart that the interface specifies.

So just like this:

public class MainActivity : AppCompatActivity, IDownloadListener
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
       SetContentView(Resource.Layout.activity_main);

    }

    public void OnDownloadStart(string url, string userAgent, string contentDisposition, string mimetype, long contentLength)
    {
        throw new NotImplementedException();
    }
}
nevermore
  • 15,432
  • 1
  • 12
  • 30
  • Its downloading but i cant seem to find the location of the downloaded file, can you check my file logic in the code i posted please –  Sep 28 '20 at 06:38
  • Is download folder exist in your app? Are you using SetDestinationInExternalFilesDir correctly? The second parameter is dirType and the third is subPath. Here is [an example](https://forums.xamarin.com/discussion/100856/setting-destination-directory-for-android-app-downloadmanager). – nevermore Sep 28 '20 at 07:05
  • What about the +"download" part, what does it do? –  Sep 28 '20 at 08:19
  • What does ```SetDestinationInExternalFilesDir(Application.Context, "download", URLUtil.GuessFileName(url, contentDisposition, mimetype));``` do? –  Sep 28 '20 at 08:21
  • I need method to save file to ```internal storage``` –  Sep 28 '20 at 08:24
  • If you do research and you will find solutions. [Reading or Writing to files on internal storage](https://learn.microsoft.com/en-us/xamarin/android/platform/files/#reading-or-writing-to-files-on-internal-storage) and [write-a-file-in-android-devices-internal-storage](https://stackoverflow.com/questions/43931910/xamarin-forms-write-a-file-in-android-devices-internal-storage). – nevermore Sep 28 '20 at 08:29
  • @CodeTiger Does my solution work for you? If yes, can you please accept it (click the ☑️ in the upper left corner of this answer ) so that we can help more people with same problem:). – nevermore Sep 29 '20 at 05:25