[Xamarin][转载]基于Xamarin.Android实现的简单的浏览器

基于Xamarin Android实现的简单的浏览器

  最近做了一个Android浏览器,当然功能比较简单,主要实现了自己想要的一些功能……现在有好多浏览器为什么还要自己写?当你使用的时候总有那么一些地方不如意,于是就想自己写一个。

 

  开发环境:Xamarin Android(非Forms)+联想机子(5.0)+荣耀机子(8.0)

 

  【开发目标】

 

  1、浏览器的基本功能,关联Http和Https(在另一个APP中打开网页时,可以弹出本应用)

 

  2、创建应用目录,用来存放离线网页文件

 

  3、可以离线保存网页(格式为mht)

 

  4、关联mht和mhtml格式的文件

 

  【涉及到的技术点】

 

  1、重写Activity中的OnBackPressed方法,实现webview回退和再按一次退出程序的功能

 

  2、重写Activity中的OnConfigurationChanged方法,实现横竖屏功能

 

  【webview相关技术点】

 

  1、开启一些常用的设置:JavaScriptEnabled、DomStorageEnabled(如果DomStorageEnabled不启用,网页中的下拉刷新和加载更多将不起作用;例子:百度首页加载新闻)

 

  2、重写WebViewClient中的ShouldOverrideUrlLoading方法,在点击打开网页中的链接时,用自己的webview中打开连接,而不是打开其他的浏览器

 

  3、重写WebChromeClient中的OnReceivedTitle和OnProgressChanged方法,分别获取页面标题(作为离线文件的名称)和加载进度

 

  4、采用事件的方式,通知主Activity关于页面加载开始、加载结束、标题、加载进度等的一些事情,进而更新UI(这里和Java的写法有些不同)

 

  5、页面加载进度条

 

  【悬浮按钮】1、全屏(退出)按钮  2、保存网页  3、扫描二维码(版本兼容问题尚未实现)

 

  【网址输入框】

 

  1、输入正确的网址之后点击输入法中的“前往”调转

 

  2、隐藏输入法

 

  以上列到的功能基本实现,最后在荣耀V10上测试时,其他的功能还好,就是在打开离线文件时也不报错,就是打不开……郁闷啊!最后查了一下也没有找到原因。这里说一下场景,以方便大神发现问题,希望大神不吝赐教。在我的联想手机上测试时发现本地文件路径是这样的:file:///storage/emulated/0/DDZMyBrowser/SavePages/1.mht  此时可以正常浏览,而V10中得到的路径是这样的,内部存储:content://com.huawei.hidisk.fileprovider/root/storage/emulated/0/DDZMyBrowser/SavePages/1.mht   SD卡:content://com.huawei.hidisk.fileprovider/root/storage/0ABF-6213/1.mht  这两个都打不开。我查询的结果,这路径应该是利用FileProvider生成的(7.0以上),哎,并非真正的android开发,并不太懂,一脸懵逼,不知道是不是因为这个原因……开始我还寄希望于将content://转为file:///格式的,但是都失败了,最后想想网上说的webview支持content://开头的啊,自己在输入框中手动修改为:file:///storage/emulated/0/DDZMyBrowser/SavePages/1.mht  发现是可以征程浏览的……

 

  上一下截图:

 

  1、应用首页

 

 

 

  2、再按一次退出程序

 

 

 

  3、横屏

 

 

 

  4、竖屏

 

 

 

  5、网页中的下拉刷新

 

 

 

  6、加载更多

 

 

 

  7、用自己的webview中打开连接,而不是打开其他的浏览器;进度条

 

 

 

  8、全屏

 

 

 

  9、离线保存

 

 

 

  10、关联MHT

 

 

 

  11、关联HTTP和HTTPS

 

 

 

   12、actionGo

 

 

 

   13、最后再来一张V10加载异常的图片

 

 

 

   去去去,传上去之后发现图片太大了,全是百度的图片……这事儿弄得

 

  最后在贴一下代码,记录一下

 

  CS代码:

 

 

复制代码

  1 using Android.App;

  2 using Android.Widget;

  3 using Android.OS;

  4 using Android.Webkit;

  5 using System;

  6 using Android.Support.Design.Widget;

  7 using Android.Content;

  8 using Android.Views;

  9 using Java.IO;

 10 using Android.Views.InputMethods;

 11 using Android.Content.PM;

 12 using Android.Content.Res;

 13 using Android.Provider;

 14 using Android.Database;

 15 

 16 namespace DDZ.MyBrowser

 17 {

 18     /// <summary>

 19     /// 获取网页Title

 20     /// </summary>

 21     /// <param name="title"></param>

 22     public delegate void MyWebViewTitleDelegate(string title);

 23 

 24     /// <summary>

 25     /// 获取网页加载进度

 26     /// </summary>

 27     public delegate void MyWebViewProgressChangedDelegate(int newProgress);

 28 

 29     /// <summary>

 30     /// 网页加载完成事件

 31     /// </summary>

 32     public delegate void MyWebViewPageFinishedDelegate();

 33 

 34     [IntentFilter(

 35         new[] { Intent.ActionView },

 36         Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },

 37         DataSchemes = new[] { "http", "https" })]

 38     [IntentFilter(

 39         new[] { Intent.ActionView },

 40         Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },

 41         DataSchemes = new[] { "file", "content" }, DataMimeType = "*/*", DataHost = "*", DataPathPattern = ".*\\\\.mhtml")]

 42     [IntentFilter(

 43         new[] { Intent.ActionView },

 44         Categories = new[] { Intent.CategoryDefault, Intent.CategoryBrowsable },

 45         DataMimeType = "*/*", DataSchemes = new[] { "file", "content" }, DataHost = "*", DataPathPattern = ".*\\\\.mht")]

 46     [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true,

 47         ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize | ConfigChanges.KeyboardHidden)]

 48     public class MainActivity : Activity

 49     {

 50         WebView myBrowser;

 51         EditText edtTxtUrl;

 52         FloatingActionButton fabMain;

 53         FloatingActionButton fabSubQRcodeScan;

 54         FloatingActionButton fabSubToggleFullScreen;

 55         FloatingActionButton fabSubSaveMHT;

 56         ProgressBar myBrowserPBar;

 57 

 58         private static bool isFabOpen;

 59         private static bool isFullScreen;

 60         private static DateTime lastClickGoBack = DateTime.Now;

 61 

 62         private static string currentPageTitle;

 63         private readonly string externalStorageDirPath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;

 64         private readonly string selfFolderName = "DDZMyBrowser";

 65         private static string selfApplicationDirPath;

 66         protected override void OnCreate(Bundle savedInstanceState)

 67         {

 68             // https://blog.csdn.net/niunan/article/details/71774292

 69             base.OnCreate(savedInstanceState);

 70             // Set our view from the "main" layout resource

 71             SetContentView(Resource.Layout.activity_main);

 72 

 73             //  1、浏览器控件相关

 74             myBrowser = FindViewById<WebView>(Resource.Id.myBrowser);

 75             //  要与Javascript交互,则webview必须设置支持Javascript

 76             myBrowser.Settings.JavaScriptEnabled = true;

 77             //  支持通过JS打开新窗口 

 78             myBrowser.Settings.JavaScriptCanOpenWindowsAutomatically = true;

 79             myBrowser.Settings.DomStorageEnabled = true;

 80             myBrowser.Settings.AllowFileAccessFromFileURLs = true;

 81 

 82             var myWebViewClient = new MyWebViewClient();

 83             myWebViewClient.GetWebViewPageFinishedDelegate += MyWebViewClient_GetWebViewPageFinishedDelegate;

 84             myBrowser.SetWebViewClient(myWebViewClient);

 85             var myWebChromeClient = new MyWebChromeClient();

 86             myWebChromeClient.GetWebViewTitleDelegate += MyWebChromeClient_GetWebViewTitleDelegate;

 87             myWebChromeClient.GetWebViewProgressChangedDelegate += MyWebChromeClient_GetWebViewProgressChangedDelegate;

 88             myBrowser.SetWebChromeClient(myWebChromeClient);

 89             edtTxtUrl = FindViewById<EditText>(Resource.Id.edtTxtUrl);

 90             edtTxtUrl.EditorAction += EdtTxtUrl_EditorAction;

 91             myBrowserPBar = FindViewById<ProgressBar>(Resource.Id.myBrowserPBar);

 92 

 93             //  2、右下方悬浮控件

 94             fabMain = FindViewById<FloatingActionButton>(Resource.Id.fabMain);

 95             fabSubQRcodeScan = FindViewById<FloatingActionButton>(Resource.Id.fabSubQRcodeScan);

 96             fabSubToggleFullScreen = FindViewById<FloatingActionButton>(Resource.Id.fabSubToggleFullScreen);

 97             fabSubSaveMHT = FindViewById<FloatingActionButton>(Resource.Id.fabSubSaveMHT);

 98             fabMain.Click += FabMain_Click;

 99             fabSubQRcodeScan.Click += FabSubQRcodeScan_Click;

100             fabSubToggleFullScreen.Click += FabSubToggleFullScreen_Click; ;

101             fabSubSaveMHT.Click += FabSubSaveMHT_Click;

102 

103             //  3、第三方应用使用该应用打开网页时,"this.Intent.DataString" 获取需要打开的网址

104             //      自己打开时,"this.Intent.DataString" 的值为空

105             String url = this.Intent.DataString;

106             if (!String.IsNullOrEmpty(url))

107             {              

108                 if (this.Intent.Data.Scheme == "content")

109                 {

110                     //  DocumentsContract.IsDocumentUri(this, this.Intent.Data):false

111 

112                     //  this.Intent.Data.Authority:com.huawei.hidisk.fileprovider

113                     //  this.Intent.Data.Host:com.huawei.hidisk.fileprovider

114                     //  this.Intent.Data.Path:/root/storage/0ABF-6213/xxx.mht

115                     //  this.Intent.Data.PathSegments:this.Intent.Data.Path的数组形式

116 

117                     //  Android.Support.V4.Content.FileProvider.GetUriForFile()

118                     //   this.Intent.SetFlags(ActivityFlags.GrantReadUriPermission).SetFlags(ActivityFlags.GrantWriteUriPermission);

119                 }

120             }

121             edtTxtUrl.Text = url;

122             LoadOnePage(url);

123 

124             //  4、创建应用目录

125             CreateSelfApplicationFolder();

126         }       

127 

128         private void EdtTxtUrl_EditorAction(object sender, TextView.EditorActionEventArgs e)

129         {

130             string inputUrl = edtTxtUrl.Text.Trim();

131             if (e.ActionId == ImeAction.Go)

132             {

133                 HideSoftInputFn();

134                 LoadOnePage(inputUrl);

135             }

136         }

137 

138         #region 获取WebView加载页面相关信息的一些自定义事件

139         private void MyWebViewClient_GetWebViewPageFinishedDelegate()

140         {

141             Toast.MakeText(this, "加载完成", ToastLength.Long).Show();

142         }

143 

144         private void MyWebChromeClient_GetWebViewProgressChangedDelegate(int newProgress)

145         {

146             myBrowserPBar.Visibility = ViewStates.Visible;

147             myBrowserPBar.Progress = newProgress;

148             if (newProgress == 100)

149             {

150                 myBrowserPBar.Visibility = ViewStates.Gone;

151             }

152         }

153 

154         private void MyWebChromeClient_GetWebViewTitleDelegate(string title)

155         {

156             currentPageTitle = title;

157         }

158         #endregion

159 

160         #region 悬浮按钮

161         private void FabMain_Click(object sender, EventArgs e)

162         {

163             if (!isFabOpen)

164             {

165                 HideSoftInputFn();

166                 ShowFabMenu();

167             }

168             else

169             {

170                 CloseFabMenu();

171             }

172             SetToggleFullScreenBtnImg();

173         }

174 

175         private void FabSubQRcodeScan_Click(object sender, EventArgs e)

176         {

177             Toast.MakeText(this, "扫描二维码", ToastLength.Long).Show();

178         }

179 

180         private void FabSubSaveMHT_Click(object sender, EventArgs e)

181         {

182             string savePageDirPath = $"{selfApplicationDirPath}{File.Separator}SavePages";

183             File dir = new File(savePageDirPath);

184             if (!dir.Exists())

185             {

186                 bool retBool = dir.Mkdir();

187             }

188             myBrowser.SaveWebArchive($"{savePageDirPath}{File.Separator}{currentPageTitle}.mht");

189         }

190 

191         private void FabSubToggleFullScreen_Click(object sender, EventArgs e)

192         {

193             if (isFullScreen)

194             {   //  目前为全屏状态,修改为非全屏

195                 edtTxtUrl.Visibility = ViewStates.Visible;

196                 this.Window.ClearFlags(WindowManagerFlags.Fullscreen);

197             }

198             else

199             {   //  目前为非全屏状态,修改为全屏

200                 edtTxtUrl.Visibility = ViewStates.Gone;

201                 this.Window.SetFlags(WindowManagerFlags.Fullscreen, WindowManagerFlags.Fullscreen);

202             }

203             isFullScreen = !isFullScreen;

204             SetToggleFullScreenBtnImg();

205         }

206 

207         private void ShowFabMenu()

208         {

209             isFabOpen = true;

210             fabSubQRcodeScan.Visibility = ViewStates.Visible;

211             fabSubToggleFullScreen.Visibility = ViewStates.Visible;

212             fabSubSaveMHT.Visibility = ViewStates.Visible;

213 

214             fabMain.Animate().Rotation(135f);

215             fabSubQRcodeScan.Animate()

216                .TranslationY(-600f)

217                .Rotation(0f);

218             fabSubToggleFullScreen.Animate()

219                .TranslationY(-410f)

220                .Rotation(0f);

221             fabSubSaveMHT.Animate()

222                 .TranslationY(-220f)

223                 .Rotation(0f);

224         }

225 

226         private void CloseFabMenu()

227         {

228             isFabOpen = false;

229 

230             fabMain.Animate().Rotation(0f);

231             fabSubQRcodeScan.Animate()

232                 .TranslationY(0f)

233                 .Rotation(90f);

234             fabSubToggleFullScreen.Animate()

235                 .TranslationY(0f)

236                 .Rotation(90f);

237             fabSubSaveMHT.Animate()

238                 .TranslationY(0f)

239                 .Rotation(90f);

240 

241             fabSubQRcodeScan.Visibility = ViewStates.Gone;

242             fabSubToggleFullScreen.Visibility = ViewStates.Gone;

243             fabSubSaveMHT.Visibility = ViewStates.Gone;

244         }

245 

246         private void SetToggleFullScreenBtnImg()

247         {

248             if (isFullScreen)

249             {

250                 fabSubToggleFullScreen.SetImageResource(Resource.Drawable.fullscreenExit);

251             }

252             else

253             {

254                 fabSubToggleFullScreen.SetImageResource(Resource.Drawable.fullscreen);

255             }

256         }

257         #endregion

258 

259         #region 重写基类 Activity 方法

260         public override void OnConfigurationChanged(Configuration newConfig)

261         {

262             base.OnConfigurationChanged(newConfig);

263             if (newConfig.Orientation == Android.Content.Res.Orientation.Portrait)

264             {

265                 edtTxtUrl.Visibility = ViewStates.Visible;

266                 fabMain.Visibility = ViewStates.Visible;

267                 this.Window.ClearFlags(WindowManagerFlags.Fullscreen);

268                 isFullScreen = false;

269                 Toast.MakeText(Application.Context, "竖屏模式!", ToastLength.Long).Show();

270             }

271             else

272             {

273                 CloseFabMenu();

274                 edtTxtUrl.Visibility = ViewStates.Gone;

275                 fabMain.Visibility = ViewStates.Gone;

276                 this.Window.SetFlags(WindowManagerFlags.Fullscreen, WindowManagerFlags.Fullscreen);

277                 isFullScreen = true;

278                 Toast.MakeText(Application.Context, "横屏模式!", ToastLength.Long).Show();

279             }

280         }

281         public override void OnBackPressed()

282         {

283             if (myBrowser.CanGoBack())

284             {

285                 myBrowser.GoBack();

286             }

287             else

288             {

289                 if ((DateTime.Now - lastClickGoBack).Seconds > 2)

290                 {

291                     Toast.MakeText(this, $"再按一次退出程序", ToastLength.Long).Show();

292                     lastClickGoBack = DateTime.Now;

293                 }

294                 else

295                 {

296                     this.Finish();

297                 }

298             }

299         }

300         #endregion

301 

302         private void LoadOnePage(String url = "")

303         {

304             currentPageTitle = null;

305             if (String.IsNullOrEmpty(url)) url = "https://www.baidu.com/";

306             myBrowser.LoadUrl(url);

307         }

308 

309         private void HideSoftInputFn()

310         {

311             //  隐藏键盘

312             InputMethodManager imm = (InputMethodManager)this.GetSystemService(Context.InputMethodService);

313             imm.HideSoftInputFromWindow(edtTxtUrl.WindowToken, 0);

314         }

315 

316         private void CreateSelfApplicationFolder()

317         {

318             selfApplicationDirPath = $"{externalStorageDirPath}{File.Separator}{selfFolderName}";

319             File dir = new File(selfApplicationDirPath);

320             if (!dir.Exists())

321             {

322                 bool retBool = dir.Mkdir();

323             }

324         }

325 

326         private String GetRealPathFromURI(Context context, Android.Net.Uri uri)

327         {

328             String retPath = null;

329             if (context == null || uri == null) return retPath;

330             Boolean isKitKat = Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat;

331             if (isKitKat && DocumentsContract.IsDocumentUri(context, uri))

332             {

333                 if (uri.Authority.Equals("com.android.externalstorage.documents", StringComparison.OrdinalIgnoreCase))

334                 {

335                     String docId = DocumentsContract.GetDocumentId(uri);

336                     String[] split = docId.Split(':');

337                     if (split[0].Equals("primary", StringComparison.OrdinalIgnoreCase))

338                     {

339                         retPath = Android.OS.Environment.ExternalStorageDirectory + "/" + split[1];

340                     }

341                 }

342             }

343             return retPath;

344         }

345 

346         private String GetFilePathFromContentUri(Context context,Android.Net.Uri url)

347         {

348             String filePath = null;

349             String[] filePathColumn = { MediaStore.MediaColumns.Data };

350             using (ICursor cursor = context.ContentResolver.Query(url, filePathColumn, null, null, null))

351             {

352                 if (cursor != null && cursor.MoveToFirst())

353                 {

354                     int columnIndex = cursor.GetColumnIndexOrThrow(filePathColumn[0]);

355                     if (columnIndex > -1)

356                     {

357                         filePath = cursor.GetString(columnIndex);

358                     }

359                 }

360             }

361             return filePath;

362         }

363     }

364 

365     public class MyWebViewClient : WebViewClient

366     {

367         public event MyWebViewPageFinishedDelegate GetWebViewPageFinishedDelegate;

368         public override bool ShouldOverrideUrlLoading(WebView view, IWebResourceRequest request)

369         {

370             view.LoadUrl(request.Url.ToString());

371             return true;

372         }

373 

374         public override void OnPageFinished(WebView view, string url)

375         {

376             base.OnPageFinished(view, url);

377             GetWebViewPageFinishedDelegate();

378         }

379     }

380 

381     public class MyWebChromeClient : WebChromeClient

382     {

383         public event MyWebViewTitleDelegate GetWebViewTitleDelegate;//声明一个事件

384 

385         public event MyWebViewProgressChangedDelegate GetWebViewProgressChangedDelegate;

386         public override void OnReceivedTitle(WebView view, string title)

387         {

388             base.OnReceivedTitle(view, title);

389             GetWebViewTitleDelegate(title);

390         }

391 

392         public override void OnProgressChanged(WebView view, int newProgress)

393         {

394             base.OnProgressChanged(view, newProgress);

395             GetWebViewProgressChangedDelegate(newProgress);

396         }

397     }

398 }

复制代码

  布局代码:

 

 

复制代码

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent">

    <LinearLayout

        android:orientation="vertical"

        android:layout_width="match_parent"

        android:layout_height="match_parent">

        <ProgressBar

            style="?android:attr/progressBarStyleHorizontal"

            android:layout_width="match_parent"

            android:layout_height="3dip"

            android:max="100"

            android:progress="0"

            android:visibility="gone"

            android:id="@+id/myBrowserPBar" />

        <android.webkit.WebView

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:layout_weight="1"

            android:id="@+id/myBrowser" />

        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:orientation="horizontal">

            <EditText

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:id="@+id/edtTxtUrl"

                android:inputType="text"

                android:singleLine="true"

                android:imeOptions="actionGo"

                android:hint="请输入网址" />

        </LinearLayout>

    </LinearLayout>

    <android.support.design.widget.FloatingActionButton

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentBottom="true"

        android:layout_alignParentRight="true"

        android:layout_margin="18dp"

        android:visibility="gone"

        android:rotation="90"

        android:src="@drawable/qrcodeScan"

        app:fabSize="mini"

        android:id="@+id/fabSubQRcodeScan" />

    <android.support.design.widget.FloatingActionButton

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentBottom="true"

        android:layout_alignParentRight="true"

        android:layout_margin="18dp"

        android:visibility="gone"

        android:rotation="90"

        android:src="@drawable/saveMht"

        app:fabSize="mini"

        android:id="@+id/fabSubSaveMHT" />

    <android.support.design.widget.FloatingActionButton

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentBottom="true"

        android:layout_alignParentRight="true"

        android:layout_margin="18dp"

        android:visibility="gone"

        android:rotation="90"

        app:fabSize="mini"

        android:id="@+id/fabSubToggleFullScreen" />

    <android.support.design.widget.FloatingActionButton

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_alignParentBottom="true"

        android:layout_alignParentRight="true"

        android:layout_margin="10dp"

        android:src="@drawable/plus"

        app:fabSize="normal"

        android:id="@+id/fabMain" />

</RelativeLayout>

复制代码

  用到的一些权限

 

 

<uses-permission android:name="android.permission.INTERNET" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

    <uses-permission android:name="android.permission.BIND_INPUT_METHOD" />

  到此就结束了,webview在8.0下打开content://文件失败的问题,如果有大神看到,希望帮忙解答,十分感谢!以后有机会在慢慢完善他的功能。

 

  【2018-06-26更新】

 

  昨天在小米note3测试本应用,本来是想测试一下看看能不能打开离线文件的问题,但是连关联MHT都不行,打开的时候,应用列表没有该应用……郁闷了,越淌水越深啊!

 

  【2018-11-08更新】

 

  开始因为版本兼容的问题,扫描二维码未处理,一直想着过后看看官方能不能解决,但是今天看看,还是不行……但是VS给出了解决方案:

 

 

 

  VS会依次提示单独安装上述的几个包,开始这个项目只安装了一个包,现在的依赖如下:

 

 

 

  这次添加的相机权限

 

<uses-permission android:name="android.permission.CAMERA" />

  相机相关代码

 

  1、初始化

 

复制代码

        protected override void OnCreate(Bundle savedInstanceState)

        {

            ………………

            ………………

            //  5、初始化

            MobileBarcodeScanner.Initialize(Application);

        }

复制代码

  2、点击扫描二维码执行的代码

 

复制代码

        private void FabSubQRcodeScan_Click(object sender, EventArgs e)

        {

            //Toast.MakeText(this, "扫描二维码", ToastLength.Long).Show();

            Task.Run(() =>

            {

                var scanner = new MobileBarcodeScanner();

                var result = scanner.Scan();

                if (result != null)

                {

                    string scanResult = result.Result.Text;

                    this.RunOnUiThread(new Java.Lang.Runnable(() =>

                    {

                        edtTxtUrl.Text = scanResult;

                        LoadOnePage(scanResult);

                    }));

                }

            });

        }

复制代码

  经过这次更新,就可以扫描二维码了……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FL1623863129

你的打赏是我写文章最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值