![](/img/trans.png)
[英]xamarin android webview file upload download does not work . please i am comfortable with c#
[英]Xamarin WebView download doesn't work for Mp4Upload
我有一個小的 Xamarin 表單應用程序,我想用它來從 mp4Upload 下載文件。 這是通過將 mp4Upload url 加載到WebView
上,然后使用WebView.EvaluateJavascriptAsync()
以編程方式單擊下載按鈕來完成的。
問題是它不會觸發下載。
public class AndroidWebView : WebViewRenderer
{
public AndroidWebView(Context ctx) : base(ctx)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Settings.UserAgentString = "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.4) Gecko/20100101 Firefox/4.0";
}
Control.Download += DownloadEvent;
}
private void DownloadEvent(object sender, Android.Webkit.DownloadEventArgs e)
{
string url = e.Url;
DownloadManager.Request request = new DownloadManager.Request(Android.Net.Uri.Parse(url));
request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted);
request.SetDestinationInExternalPublicDir(Android.OS.Environment.DirectoryDownloads, "CPPPrimer");
DownloadManager dm = (DownloadManager)Android.App.Application.Context.GetSystemService("download");
dm.Enqueue(request);
Toast.MakeText(Android.App.Application.Context, e.Url, ToastLength.Long).Show();
}
}
我已經用 github url 測試了上面的代碼,以下載一個可以正常工作的 random.gitignore 文件。
如果我手動單擊下載以及使用 cefsharp 使用ChromiumWebBrowser.ExecuteScriptAsync()
以編程方式單擊下載,則 mp4Upload 鏈接也適用於 chrome。
有誰知道如何解決這個問題?
它並不像看起來那么簡單,尤其是對於在_blank
目標中打開的下載。 這是我在一個項目中使用的代碼:
using Xamarin.Forms;
using Android.Webkit;
using Android.Content;
using System.Threading.Tasks;
using Xamarin.Forms.Platform.Android;
// In your android webview renderer
protected override void OnElementChanged(ElementChangedEventArgs<XamWebView> e)
{
base.OnElementChanged(e);
if (this.Control != null)
{
var xamWebView = (AppWebView)e.NewElement;
this.AllowFileDownloads(this.Control, xamWebView);
}
}
private void AllowFileDownloads(DroidWebView webView, AppWebView customWebView)
{
webView.Settings.SetSupportMultipleWindows(false);
var downloadListener = new WebViewDownloadListener(this.Context);
webView.SetDownloadListener(downloadListener);
}
using System;
using Android.App;
using Android.Widget;
using Android.Webkit;
using Android.Content;
using Xamarin.Essentials;
public class WebViewDownloadListener : Java.Lang.Object, IDownloadListener
{
private Context AppContext { get; }
public event Action<string> OnDownloadStarted;
private DownloadManager DownloadManager => DownloadManager.FromContext(this.AppContext);
public WebViewDownloadListener(Context appContext)
{
this.AppContext = appContext;
this.AppContext.RegisterReceiver(new OnDownloadCompleteOpenFileInDefaultApp(), new IntentFilter(DownloadManager.ActionDownloadCom
}
public void OnDownloadStart(string url, string userAgent, string contentDisposition, string mimetype, long contentLength)
{
this.OnDownloadStarted?.Invoke(url);
var downloadRequest = BuildDownloadRequest(url, userAgent, contentDisposition, mimetype);
AppErrorHandler.ExecuteSafely(async () =>
{
if (ShouldAskPermissionToSaveFile)
{
var permission = await Permissions.RequestAsync<Permissions.StorageWrite>();
if (permission == PermissionStatus.Granted)
this.EnqueueDownloadRequest(downloadRequest);
}
else
this.EnqueueDownloadRequest(downloadRequest);
});
}
private static bool ShouldAskPermissionToSaveFile => Android.OS.Build.VERSION.SdkInt <= Android.OS.BuildVersionCodes.P;
private void EnqueueDownloadRequest(DownloadManager.Request downloadRequest)
{
this.DownloadManager.Enqueue(downloadRequest);
Toast.MakeText(this.AppContext, "Downloading File", ToastLength.Long).Show();
}
private static DownloadManager.Request BuildDownloadRequest(string url, string userAgent, string contentDisposition, string mimetype)
{
var request = new DownloadManager.Request(Android.Net.Uri.Parse(url));
request.SetMimeType(mimetype);
request.SetDescription("Downloading file...");
request.AddRequestHeader("User-Agent", userAgent);
request.AddRequestHeader("cookie", CookieManager.Instance.GetCookie(url));
request.SetNotificationVisibility(DownloadVisibility.VisibleNotifyCompleted);
request.SetDestinationInExternalPublicDir(
Android.OS.Environment.DirectoryDownloads,
URLUtil.GuessFileName(url, contentDisposition, mimetype)
);
return request;
}
}
using Java.IO;
using Android.App;
using Android.Widget;
using Android.Content;
using Android.Database;
using AndroidX.Core.Content;
public class OnDownloadCompleteOpenFileInDefaultApp : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (DownloadManager.ActionDownloadComplete.Equals(intent.Action))
{
ICursor cursor = GetDbCursorForDownloadedFile(context, intent);
if (cursor.MoveToFirst())
{
var (downloadStatus, downloadUri, mimeType) = ExtractDataFromCursor(cursor);
if (downloadStatus == (int)DownloadStatus.Successful && downloadUri != null)
{
var fileUri = GetFileUri(context, downloadUri);
var openFileIntent = CreateOpenFileIntent(mimeType, fileUri);
LaunchOpenFileIntent(context, openFileIntent);
}
}
cursor.Close();
}
}
private static ICursor GetDbCursorForDownloadedFile(Context context, Intent intent)
{
var downloadManager = DownloadManager.FromContext(context);
var downloadId = intent.GetLongExtra(DownloadManager.ExtraDownloadId, 0);
var query = new DownloadManager.Query();
query.SetFilterById(downloadId);
var cursor = downloadManager.InvokeQuery(query);
return cursor;
}
private static (int status, string downloadUri, string mimeType) ExtractDataFromCursor(ICursor cursor) =
(
cursor.GetInt(cursor.GetColumnIndex(DownloadManager.ColumnStatus)),
cursor.GetString(cursor.GetColumnIndex(DownloadManager.ColumnLocalUri)),
cursor.GetString(cursor.GetColumnIndex(DownloadManager.ColumnMediaType))
);
private static Android.Net.Uri GetFileUri(Context context, string downloadUri)
{
var fileUri = Android.Net.Uri.Parse(downloadUri);
if (ContentResolver.SchemeFile.Equals(fileUri.Scheme))
{
// FileUri - Convert it to contentUri.
File file = new File(fileUri.Path);
fileUri = FileProvider.GetUriForFile(context, $"{context.PackageName}.fileprovider", file);
}
return fileUri;
}
private static Intent CreateOpenFileIntent(string mimeType, Android.Net.Uri fileUri)
{
Intent openAttachmentIntent = new Intent(Intent.ActionView);
openAttachmentIntent.SetDataAndType(fileUri, mimeType);
openAttachmentIntent.SetFlags(ActivityFlags.GrantReadUriPermission);
return openAttachmentIntent;
}
private static void LaunchOpenFileIntent(Context context, Intent openAttachmentIntent)
{
try
{
context.StartActivity(openAttachmentIntent);
}
catch (ActivityNotFoundException)
{
Toast.MakeText(context, "Could not open file.", ToastLength.Long).Show();
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.