Xamarin网络视图-Android上的摄像头
我有一个Xamarin.Forms应用程序,带有Android自定义网络视图。 我也有一个网络应用程序,这个可以用相机拍照 当我使用带有WebView的移动应用程序导航到网站时,它无法 捕捉任何图像。请看截图。这是模拟器屏幕。 在真正的手机上,图像是白色的 注意:在模拟器上,我可以通过重置设备使其工作,然后它再次工作,有些东西是随机的。在真正的设备上,我不能让它工作 当然,我已经设置并请求访问摄像头,但这没有帮助 我还测试了此页面: 但我得到了以下错误:“NotAllowedError” 但是如果你看一下代码,你会发现我请求了许可,它被授予了 代码如下:Xamarin网络视图-Android上的摄像头,android,xamarin,xamarin.forms,webview,android-webview,Android,Xamarin,Xamarin.forms,Webview,Android Webview,我有一个Xamarin.Forms应用程序,带有Android自定义网络视图。 我也有一个网络应用程序,这个可以用相机拍照 当我使用带有WebView的移动应用程序导航到网站时,它无法 捕捉任何图像。请看截图。这是模拟器屏幕。 在真正的手机上,图像是白色的 注意:在模拟器上,我可以通过重置设备使其工作,然后它再次工作,有些东西是随机的。在真正的设备上,我不能让它工作 当然,我已经设置并请求访问摄像头,但这没有帮助 我还测试了此页面: 但我得到了以下错误:“NotAllowedError” 但是
public class HybridWebViewRenderer : WebViewRenderer
{
private const string JavascriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
private Context _context;
public HybridWebViewRenderer(Context context) : base(context)
{
_context = context;
global::Android.Webkit.WebView.SetWebContentsDebuggingEnabled(true);
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);
//---- Interop
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
((HybridWebView)Element).Cleanup();
}
if (e.NewElement != null)
{
Control.AddJavascriptInterface(new JsBridge(this), "jsBridge");
}
//---- Cookies
if (e.OldElement == null)
{
Control.Settings.AllowFileAccess = true;
Control.Settings.AllowFileAccessFromFileURLs = true;
Control.Settings.AllowUniversalAccessFromFileURLs = true;
Control.SetWebViewClient(new CookieWebViewClient(Element as HybridWebView));
Control.SetWebChromeClient(new HybridWebChromeClient(_context));
}
}
}
internal class HybridWebChromeClient : WebChromeClient
{
private Context _context;
private MainActivity _mainActivity;
public HybridWebChromeClient(Context context)
{
_context = context;
_mainActivity = context as MainActivity;
}
[TargetApi(Value = 21)]
public override void OnPermissionRequest(PermissionRequest request)
{
((Android.App.Activity)_context).RunOnUiThread(() =>
{
request.Grant(request.GetResources());
});
}
public override bool OnShowFileChooser(Android.Webkit.WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
{
_mainActivity._uploadMessage = filePathCallback;
Intent i = new Intent(Intent.ActionGetContent);
i.AddCategory(Intent.CategoryOpenable);
i.SetType("*/*");
// The camera intent
Intent captureIntent = new Intent(Android.Provider.MediaStore.ActionImageCapture);
List<IParcelable> targetedShareIntents = new List<IParcelable>();
targetedShareIntents.Add(captureIntent);
captureIntent.AddCategory(Intent.ActionCameraButton);
//add camera intent to the main intent (i)
i.PutExtra(Intent.ExtraInitialIntents, targetedShareIntents.ToArray());
_mainActivity.StartActivityForResult(Intent.CreateChooser(i, "File Chooser"), 1);
return true;
}
//public override bool OnShowFileChooser(Android.Webkit.WebView webView, IValueCallback filePathCallback, FileChooserParams fileChooserParams)
//{
// _mainActivity.mUploadMessage = filePathCallback;
// Intent Fileintent = new Intent(Intent.ActionGetContent);
// Fileintent.AddCategory(Intent.CategoryOpenable);
// Fileintent.SetType("/");
// var intents = new List<Intent>();
// if (_context.PackageManager.HasSystemFeature(PackageManager.FeatureCameraAny))
// {
// Intent captureIntent = new Intent(Android.Provider.MediaStore.ActionImageCapture);
// var resolveinfolist = _context?.PackageManager?.QueryIntentActivities(captureIntent, 0);
// if (resolveinfolist != null && resolveinfolist.Count > 0)
// {
// var item = resolveinfolist[0];
// var packagename = item.ActivityInfo?.PackageName;
// var intent = new Intent(captureIntent);
// intent.SetComponent(new ComponentName(packagename, item.ActivityInfo.Name));
// intent.SetPackage(packagename);
// intent.AddFlags(ActivityFlags.GrantReadUriPermission);
// intent.AddFlags(ActivityFlags.GrantWriteUriPermission);
// File storageDir = new File(Environment.ExternalStorageDirectory, "filename");
// var file = Android.OS.Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures);
// _mainActivity.ImageFile = storageDir;
// var uri = FileProvider.GetUriForFile(_context, _context.PackageName + ".provider", storageDir);
// intent.PutExtra(Android.Provider.MediaStore.ExtraOutput, uri);
// intents.Add(intent);
// }
// }
// intents.Add(Fileintent);
// var res = Intent.CreateChooser(intents[0], fileChooserParams.Title);
// intents?.RemoveAt(0);
// res.PutExtra(Intent.ExtraInitialIntents, intents?.ToArray());
// _mainActivity.StartActivityForResult(res, 1000);
// return true;
//}
}
internal class CookieWebViewClient : WebViewClient
{
private readonly HybridWebView _hybridWebView;
internal CookieWebViewClient(HybridWebView hybridWebView)
{
_hybridWebView = hybridWebView;
_hybridWebView.OnRequestNativeSetCookie += AppCookiesManager_OnSetCookie;
_hybridWebView.OnRequestNativeCookieRead += HybridWebView_OnRequestNativeCookieRead;
_hybridWebView.OnRequestNativeCookieWrite += HybridWebView_OnRequestNativeCookieWrite;
}
private void HybridWebView_OnRequestNativeCookieWrite(string url, CookieCollection cookies)
{
CookieManager.Instance.Flush();
}
private void HybridWebView_OnRequestNativeCookieRead(string url, CookieCollection cookies)
{
}
private void AppCookiesManager_OnSetCookie(Cookie cookie)
{
string cookieValue = cookie.Value;
string cookieDomain = cookie.Domain;
string cookieName = cookie.Name;
// Path
// Secure
// Expires
string currentCookie = CookieManager.Instance.GetCookie(cookieDomain) ?? "";
CookieManager.Instance.SetCookie(cookieDomain, cookieName + "=" + cookieValue + ";" + currentCookie);
CookieManager.Instance.Flush();
}
public override void OnPageFinished(global::Android.Webkit.WebView view, string url)
{
// Set all the cookies on the view
if (Build.VERSION.SdkInt < BuildVersionCodes.Lollipop)
CookieSyncManager.Instance.Sync();
CookieManager.Instance.Flush();
CookieManager.AllowFileSchemeCookies();
CookieManager.SetAcceptFileSchemeCookies(true);
CookieManager.Instance.AcceptCookie();
CookieManager.Instance.AcceptThirdPartyCookies(view);
CookieManager.Instance.SetAcceptCookie(true);
CookieManager.Instance.SetAcceptThirdPartyCookies(view, true);
}
}
公共类HybridWebViewRenderer:WebViewRenderer
{
私有常量字符串JavascriptFunction=“函数invokeCharpAction(数据){jsBridge.invokeAction(数据);}”;
私人语境(private Context)(私人语境);;
公共HybridWebViewRenderer(上下文):基础(上下文)
{
_上下文=上下文;
全局::Android.Webkit.WebView.SetWebContentsDebuggingEnabled(true);
}
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
//----互操作
if(e.OldElement!=null)
{
RemoveJavascriptInterface(“jsBridge”);
((HybridWebView)元素).Cleanup();
}
if(例如NewElement!=null)
{
AddJavascriptInterface(新的JsBridge(this),“JsBridge”);
}
//----饼干
if(e.OldElement==null)
{
Control.Settings.AllowFileAccess=true;
Control.Settings.AllowFileAccessFromFileURLs=true;
Control.Settings.allowuniversalaccessfromfileurl=true;
SetWebViewClient(新的CookieWebViewClient(元素为HybridWebView));
Control.SetWebChromeClient(新的HybridWebChromeClient(_context));
}
}
}
内部类HybridWebChromeClient:WebChromeClient
{
私人语境(private Context)(私人语境);;
私人主活动(u main activity);;
公共HybridWebChromeClient(上下文)
{
_上下文=上下文;
_mainActivity=作为mainActivity的上下文;
}
[TargetApi(值=21)]
公共覆盖在PermissionRequest上无效(PermissionRequest请求)
{
((Android.App.Activity)_context).RunOnUiThread(()=>
{
request.Grant(request.GetResources());
});
}
public override bool OnShowFileChooser(Android.Webkit.WebView WebView、IValueCallback filePathCallback、FileChooserParams FileChooserParams)
{
_mainActivity.\u uploadMessage=filePathCallback;
意图i=新意图(Intent.ActionGetContent);
i、 添加类别(意图.类别可处罚);
i、 集合类型(“*/*”);
//摄像机的意图
Intent captureIntent=新的意图(Android.Provider.MediaStore.ActionImageCapture);
List targetedShareContents=新列表();
targetedShareContents.Add(captureIntent);
captureIntent.AddCategory(Intent.ActionCameraButton);
//将相机意图添加到主要意图(i)
i、 PutExtra(Intent.ExtraInitialIntents,targetedShareContents.ToArray());
_mainActivity.StartActivityForResult(Intent.CreateChooser(i,“文件选择器”),1);
返回true;
}
//public override bool OnShowFileChooser(Android.Webkit.WebView WebView、IValueCallback filePathCallback、FileChooserParams FileChooserParams)
//{
//_mainActivity.mUploadMessage=filePathCallback;
//Intent Fileintent=新的Intent(Intent.ActionGetContent);
//Fileintent.AddCategory(Intent.CategoryOpenable);
//Fileintent.SetType(“/”);
//var intents=新列表();
//if(_context.PackageManager.HasSystemFeature(PackageManager.FeatureCameraAny))
// {
//Intent captureIntent=新的意图(Android.Provider.MediaStore.ActionImageCapture);
//var resolveinfolist=_context?.PackageManager?.querytentActivities(captureIntent,0);
//if(resolveinfolist!=null&&resolveinfolist.Count>0)
// {
//var item=resolveinfolist[0];
//var packagename=item.ActivityInfo?.packagename;
//var意图=新意图(captureIntent);
//SetComponent(新组件名(packagename,item.ActivityInfo.Name));
//intent.SetPackage(packagename);
//intent.AddFlags(ActivityFlags.grantradeuripermission);
//intent.AddFlags(ActivityFlags.GrantWriteUriPermission);
//File storageDir=新文件(Environment.ExternalStorageDirectory,“filename”);
//var file=Android.OS.Environment.GetExternalStoragePublicDirectory(Environment.DirectoryPictures);
//_main activity.ImageFile=storageDir;
//var uri=FileProvider.GetUriForFile(_context,_context.PackageName+“.provider”,storageDir);
//intent.PutExtra(Android.Provider.MediaStore.ExtraOutput,uri);
//意图。添加(意图);
// }
// }
//添加(Fileintent);
//var res=Intent.CreateChooser(intents[0],fileChooserParams.Title);
//意图?.RemoveAt(0);
//res.PutExtra(Intent.ExtraInitialIntents,intents?.ToArray());
//_主要活动。StartActivityForResult(res,1000);
//返回true;
//}
}
private async Task<bool> OnRequestCameraAccess()
{
PermissionStatus status = await Permissions.CheckStatusAsync<Permissions.Camera>();
if (status != PermissionStatus.Granted)
{
status = await Permissions.RequestAsync<Permissions.Camera>();
}
//status = await Permissions.RequestAsync<Permissions.Media>();
//status = await Permissions.RequestAsync<Permissions.Microphone>();
//status = await Permissions.RequestAsync<Permissions.Photos>();
//status = await Permissions.RequestAsync<Permissions.StorageRead>();
//status = await Permissions.RequestAsync<Permissions.StorageWrite>();
return status == PermissionStatus.Granted;
}