由於在項目中使用了WebView容器來加載網頁對某些信息進行編輯處理,中間需要用到拍照/圖片庫上傳圖片,在iOS中網頁代碼可以正常調用拍照功能和選擇圖庫圖片功能,但是在Android下面怎么都調不到拍照功能,百度了下在原生程序下面也是同樣的調用不到,要自己去處理,有幾種處理辦法,我這里選擇了用JS調用原生代碼來實現拍照和圖片選擇功能。在Xamarin.Forms下面我們要自己寫Renderer來實現。這里同樣是參考Xamarin官網的例子來實現的,下面是個小例子來理解原生代碼和JS代碼之間的互相調用。
1.在Form中定義HybridWebView,繼承於WebView,代碼如下:
1 public class HybridWebView:WebView 2 { 3 public event EventHandler<EventArgs> CallAction; 4 public void SendClick(string data) 5 { 6 CallAction?.Invoke(this,new EventArgs()); 7 } 8 }
2.在Android項目下面自定義Renderer:
1 public class HybridWebViewRenderer:WebViewRenderer 2 { 3 const string JavaScriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}"; 4 5 public HybridWebView webView; 6 7 protected override void OnElementChanged(ElementChangedEventArgs<WebView> e) 8 { 9 base.OnElementChanged(e); 10 if (e.OldElement != null) 11 { 12 Control.RemoveJavascriptInterface("jsBridge"); 13 } 14 if (e.NewElement != null) 15 { 16 webView = e.NewElement as HybridWebView; 17 18 Control.AddJavascriptInterface(new JSBridge(this), "jsBridge"); 19 InjectJS(JavaScriptFunction); 20 } 21 22 void InjectJS(string script) 23 { 24 if (Control != null) 25 { 26 Control.LoadUrl(string.Format("javascript: {0}", script)); 27 } 28 } 29 } 30 }
3.定義jsbridge
1 public class JSBridge : Java.Lang.Object 2 { 3 readonly WeakReference<HybridWebViewRenderer> hybridWebViewRenderer; 4 5 public JSBridge(HybridWebViewRenderer hybridRenderer) 6 { 7 hybridWebViewRenderer = new WeakReference<HybridWebViewRenderer>(hybridRenderer); 8 } 9 10 [JavascriptInterface] 11 [Export("invokeAction")] 12 public void InvokeAction(string data) 13 { 14 HybridWebViewRenderer hybridRenderer; 15 16 if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget(out hybridRenderer)) 17 { 18 hybridRenderer.webView.SendClick(data); 19 } 20 } 21 }
4.要注意的是我們要在Android項目中引入程序集Mono.Android.Export,不然程序會報錯。
5.定義html文件中的js代碼:
1 <html> 2 <head /> 3 <body> 4 <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script> 5 <h1>HybridWebView Test</h1> 6 <br /> 7 Enter name: <input type="text" id="name"> 8 <br /> 9 <br /> 10 <button type="button" onclick="javascript:invokeCSCode($('#name').val());">Invoke C# Code</button> 11 <br /> 12 <p id="result">Result:</p> 13 14 <script type="text/javascript"> 15 //調用C#代碼 16 function invokeCSCode(data) { 17 invokeCSharpAction(data); 18 } 19 20 //C#調用此js方法 21 function print(url) { 22 alert(url); 23 } 24 </script> 25 </body> 26 </html> 27
6.在程序中調用
1 public MainPage() 2 { 3 InitializeComponent(); 4 webView.Source = string.Format("file:///android_asset/Content/{0}", "index.html"); 5 webView.CallAction += WebView_CallAction; 6 } 7 8 private void WebView_CallAction(object sender, EventArgs e) 9 { 10 object test = "http://www.baidu.com"; 11 webView.Eval(string.Format("print('" + test + "')")); 12 }
代碼地址:https://github.com/zjmsky/HybridWebViewTest