Reputation: 3
I am really beginner in xamarin.
I need an app, what is load a website in webview. The site need file uploading <input type="file" accept="image/*" />
. In mobile browser it is perfect, can open camera or choose from storage.
IOS webview working too, I gave permission and it is OK. But in android, I tried a lot of code, but the best result a filechooser without camera, and it doesn’t even load the image I select from storage.
Can anyone help, what is the problem?
My current code:
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);
}
}
}
Upvotes: 0
Views: 2227
Reputation: 9264
I write a demo to open the camera by Input button in HTML page, I used local HTML page to make a test, here is running GIF.
Here is my code in 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);
}
}
}
Here is my Util.cs to take a camera.
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);
}
}
I update my demo to github, you can downdload it and test it.
https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/MyWebviewDemo.zip
Upvotes: 1