[英]Xamarin android webview dont open camera
我真的是 xamarin 的初學者。 我需要一個應用程序,什么是在 webview 中加載網站。 網站需要上傳文件<input type="file" accept="image/*" />
。 在移動瀏覽器中它是完美的,可以打開相機或從存儲中選擇。 IOS webview 也在工作,我給了許可,沒關系。 但是在 android 中,我嘗試了很多代碼,但最好的結果是沒有攝像頭的文件選擇器,它甚至沒有從存儲中加載圖像 I select。 誰能幫忙,有什么問題嗎? 我當前的代碼:
public class MainActivity : AppCompatActivity
{
private static IValueCallback mUploadMessage;
private static int FILECHOOSER_RESULTCODE = 1;
public static IValueCallback mUMA;
public static int FCR = 1;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
var web = this.FindViewById<WebView>(Resource.Id.wv);
web.Settings.JavaScriptEnabled = true;
web.SetWebChromeClient(new myWebChromeClient(this));
web.LoadUrl....
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
if (requestCode == FILECHOOSER_RESULTCODE)
{
if (null == mUploadMessage) return;
Android.Net.Uri result = intent == null || resultCode != Result.Ok ? null : intent.Data;
mUploadMessage.OnReceiveValue(result);
mUploadMessage = null;
}
}
public class myWebChromeClient : WebChromeClient
{
Activity mActivity = null;
public myWebChromeClient(Activity activity)
{
mActivity = activity;
}
public override bool OnShowFileChooser(WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
{
if (MainActivity.mUMA != null)
{
mUMA.OnReceiveValue(null);
}
mUMA = filePathCallback;
Intent captureIntent = fileChooserParams.CreateIntent();
Intent contentSelectionIntent = new Intent(Intent.ActionGetContent);
contentSelectionIntent.AddCategory(Intent.CategoryOpenable);
contentSelectionIntent.SetType("*/*");
Intent[] intentArray;
if (captureIntent != null)
{
intentArray = new Intent[] { captureIntent };
}
else
{
intentArray = new Intent[0];
}
Intent chooserIntent = new Intent(Intent.ActionChooser);
chooserIntent.PutExtra(Intent.ExtraIntent, contentSelectionIntent);
chooserIntent.PutExtra(Intent.ExtraTitle, "Image Chooser");
chooserIntent.PutExtra(Intent.ExtraInitialIntents, intentArray);
mActivity.StartActivityForResult(chooserIntent, FCR);
return base.OnShowFileChooser(webView, filePathCallback, fileChooserParams);
}
}
}
我寫了一個demo,通過HTML頁面中的Input按鈕打開相機,我用本地HTML頁面做一個測試,這里是運行GIF。
這是我在MainActivity.cs
中的代碼。
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using Android.Webkit;
using Android.Content;
using Java.IO;
using Android.Net;
using Android.Support.V4.Content;
using Android;
using Android.Content.PM;
namespace MyWebviewDemo
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true,LaunchMode =Android.Content.PM.LaunchMode.SingleTop)]
public class MainActivity : AppCompatActivity
{
private static IValueCallback mUploadMessage;
private static int FILECHOOSER_RESULTCODE = 1;
public static IValueCallback mUMA;
public static int FCR = 1;
public static IValueCallback mUploadCallbackAboveL;
public static int PHOTO_REQUEST=10023;
public static Uri imageUri;
public static MainActivity Instance;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
WebView webView1 = FindViewById<WebView>(Resource.Id.webView1);
webView1.Settings.JavaScriptEnabled = true;
webView1.Settings.UseWideViewPort=true;
webView1.Settings.LoadWithOverviewMode=true;
webView1.Settings.DomStorageEnabled=true;
webView1.Settings.DefaultTextEncodingName="UTF-8";
webView1.SetWebViewClient(new MyWebViewClient(this));
webView1.SetWebChromeClient(new myWebChromeClient(this));
webView1.LoadUrl("file:///android_asset/index.html");
Instance = this;
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) != (int)Permission.Granted)
{
RequestPermissions(new string[] { Manifest.Permission.Camera }, 0);
}
//開啟存儲權限
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.WriteExternalStorage) != (int)Permission.Granted)
{
RequestPermissions(new string[] { Manifest.Permission.ReadExternalStorage, Manifest.Permission.WriteExternalStorage }, 0);
}
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent intent)
{
if (requestCode == FILECHOOSER_RESULTCODE)
{
if (null == mUploadMessage) return;
Android.Net.Uri result = intent == null || resultCode != Result.Ok ? null : intent.Data;
mUploadMessage.OnReceiveValue(result);
mUploadMessage = null;
}else if (requestCode== PHOTO_REQUEST)
{
Uri result = intent == null || resultCode != Result.Ok ? null : intent.Data;
if (mUploadCallbackAboveL != null)
{
onActivityResultAboveL(requestCode, resultCode, intent);
}
else if (mUploadMessage != null)
{
mUploadMessage.OnReceiveValue(result);
mUploadMessage = null;
}
//mUploadMessage.OnReceiveValue(result);
//mUploadMessage = null;
}
}
private void onActivityResultAboveL(int requestCode, Result resultCode, Intent data)
{
if (requestCode != PHOTO_REQUEST || mUploadCallbackAboveL == null)
{
return;
}
Uri[] results = null;
if (resultCode == Result.Ok)
{
results = new Uri[] { imageUri };
results[0] = MainActivity.imageUri;
//if (data == null)
//{
// results = new Uri[] { imageUri };
//}
//else
//{
// results[0] = MainActivity.imageUri;
// //get the data
// string dataString = data.DataString;
// ClipData clipData = data.ClipData;
// if (clipData != null)
// {
// results = new Uri[clipData.ItemCount];
// for (int i = 0; i < clipData.ItemCount; i++)
// {
// ClipData.Item item = clipData.GetItemAt(i);
// results[i] = item.Uri;
// }
// }
// if (dataString != null)
// results = new Uri[] { Uri.Parse(dataString) };
//}
}
mUploadCallbackAboveL.OnReceiveValue(results);
mUploadCallbackAboveL = null;
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
internal class MyWebViewClient : WebViewClient
{
private MainActivity mainActivity;
public MyWebViewClient(MainActivity mainActivity)
{
this.mainActivity = mainActivity;
}
}
public class myWebChromeClient : WebChromeClient
{
Activity mActivity = null;
public myWebChromeClient(Activity activity)
{
mActivity = activity;
}
public override bool OnShowFileChooser(WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
{
MainActivity.mUploadCallbackAboveL = filePathCallback;
TakePhoto();
//if (MainActivity.mUMA != null)
//{
// MainActivity.mUMA.OnReceiveValue(null);
//}
//MainActivity.mUMA = filePathCallback;
//Intent captureIntent = fileChooserParams.CreateIntent();
//Intent contentSelectionIntent = new Intent(Intent.ActionGetContent);
//contentSelectionIntent.AddCategory(Intent.CategoryOpenable);
//contentSelectionIntent.SetType("*/*");
//Intent[] intentArray;
//if (captureIntent != null)
//{
// intentArray = new Intent[] { captureIntent };
//}
//else
//{
// intentArray = new Intent[0];
//}
//Intent chooserIntent = new Intent(Intent.ActionChooser);
//chooserIntent.PutExtra(Intent.ExtraIntent, contentSelectionIntent);
//chooserIntent.PutExtra(Intent.ExtraTitle, "Image Chooser");
//chooserIntent.PutExtra(Intent.ExtraInitialIntents, intentArray);
//mActivity.StartActivityForResult(chooserIntent, MainActivity.FCR);
return true;
}
private void TakePhoto()
{
File fileUri = new File(Environment.ExternalStorageDirectory.Path);
//MainActivity.imageUri = Uri.FromFile(fileUri);
if (Build.VERSION.SdkInt >=Android.OS.BuildVersionCodes.N)
{
if (!fileUri.Exists())
{
fileUri.Mkdir();
}
File file = new File(fileUri, SystemClock.CurrentThreadTimeMillis()+".jpg");
MainActivity.imageUri = FileProvider.GetUriForFile(mActivity, "com.companyname.mywebviewdemo" + ".fileprovider", file);//通過FileProvider創建一個content類型的Uri
}
PhotoUtils.TakePicture(MainActivity.Instance, MainActivity.imageUri, MainActivity.PHOTO_REQUEST);
}
}
}
這是我用來拍照的 Util.cs。
public static void TakePicture(Activity activity, Android.Net.Uri imageUri, int requestCode)
{
Intent intentCamera = new Intent();
intentCamera.SetAction(MediaStore.ActionImageCapture);
// intentCamera.PutExtra(MediaStore.ExtraOutput, imageUri);
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.N)
{
intentCamera.AddFlags(ActivityFlags.GrantReadUriPermission);
}
if (activity != null)
{
activity.StartActivityForResult(intentCamera, requestCode);
}
}
我將我的演示更新為 github,您可以下載並測試它。
https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/MyWebviewDemo.zip
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.