当前位置: 移动技术网 > 移动技术>移动开发>Android > Xamarin 安卓 相机 各种坑 目标API Android 6以后,我选的目标API版本是 Android 10

Xamarin 安卓 相机 各种坑 目标API Android 6以后,我选的目标API版本是 Android 10

2020年07月17日  | 移动技术网移动技术  | 我要评论

第一次在CSDN上写博客,为了记录我踩坑的心路历程,同时也为了其它踩坑的小盆友,指一条明路。

因为客户要求增加拍照功能, 本以为这及其简单,因为以前做过二维码识别,用的zixing.dll插件,直接有绑定imageview的例程,拿过来直接用就返回个二维码结果,这次想直接调用系统相机(因为自己做页面总是有不同机型显示图像拉伸问题,不知道怎么解决)然后返回个照片直接用就行了,结果真的让我搜索了一整个星期!从上周五搜索到这周五,从微软官方文档到CSDN各种大神博客,艾玛那个相机使用方法多的啊,不行不行的,这一周我下载大神的例子工程数十个,有的工程打开直接一堆报错,这没有那没有,有的工程一打开一顿更新猛如虎,夸夸夸更新一个钟头(我可是2020.07.01刚从微软官网下载的最新的vs2019,现在2020.07.16),然后开始报错,无法运行,最终成功运行工程0个,我还从各种大神的文章里,直接搬运代码数十篇,包括各种建照相机类,各种声明权限,妈耶,那叫一个复杂,我有一本Xamarin开发Android应用实战的书,清华大学出版社2013年出版的,这本书上的代码针对的是最高版本安卓4.x,以前用还能用,最近客户要增加照相功能,以前没用过,安卓6以后各种使用方式和那本书上都不太一样了,所以各种百度,摘抄的各种代码,让我成功获取了权限,代码如下

加一个using
using Android.Support.V4.Content;

在需要干事的函数中建立一个权限数组,列出你需要的权限,如果没有则请求权限,我这里是获取个读写存储器的权限,我也不知道应该是userdic还是external,反正读写存储器一共就这4个,我就都获取了。

 Android.Content.PM.Permission[] qx = new Android.Content.PM.Permission[4];
            qx[0] = ContextCompat.CheckSelfPermission(this, Android.Manifest.Permission.ReadExternalStorage);
            qx[1] = ContextCompat.CheckSelfPermission(this, Android.Manifest.Permission.WriteExternalStorage);
            qx[2] = ContextCompat.CheckSelfPermission(this, Android.Manifest.Permission.ReadUserDictionary);
            qx[3] = ContextCompat.CheckSelfPermission(this, Android.Manifest.Permission.WriteUserDictionary);
            bool qxjg = true;
            for (int i = 0; i < qx.Length; i++)
            {
                switch (qx[i])
                {
                    case Android.Content.PM.Permission.Denied:
                        qxjg = false;
                        i = 2100000000;
                        break;
                }
            }
            if (!qxjg)
            {

//没有权限申请一下
                RequestPermissions(new string[] { Android.Manifest.Permission.ReadExternalStorage, Android.Manifest.Permission.WriteExternalStorage, Android.Manifest.Permission.ReadUserDictionary, Android.Manifest.Permission.WriteUserDictionary }, 2);
            }
            else
            {
               //已经有权限,干事
            }

然后在建立窗口的时候系统已经自动生成的权限回调函数里判定一下

       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);

//前两行系统自动生成的,下面是我写的,case 2是申请权限的时候传入的数字,我前面传入的2,这里就case 2
            switch (requestCode)
            {
                case 2:
                    bool qxjg = true;
                    for (int i = 0; i < grantResults.Length; i++)
                    {
                        switch (grantResults[i])
                        {
                            case Android.Content.PM.Permission.Denied:
                                qxjg = false;
                                i = 2100000000;
                                break;
                        }
                    }
                    if (qxjg)
                    {
                        hs005();
                    }
                    else
                    {
                        Toast.MakeText(this, "没有读写存储器权限!请在权限管理中开放权限!\r\n3秒后退出。", ToastLength.Long).Show();//没有权限,弹窗提示一下

//下面这个线程我直接延迟3秒退出程序了,直接删除就行了,因为如果在这里Thread.Sleep(3000)会把主界面卡住,弹窗3秒后才弹出来,所以开个线程,里面就2行,等3秒然后Finish();我就不列出来了,这三行没用。
                        th001 = new System.Threading.Thread(tx001);
                        th001.IsBackground = true;
                        th001.Start();
                    }
                    break;
            }
        }

以上内容花了我3天时间,才弄明白,以前不知道安卓6之后还需要权限,我以前目标API一直是安卓4.4,所以都不知道这个情况,这次我换了安卓10,发现以前代码都不能用了。

到目前为止,我能正常弹出相机,也能拍照得到返回值了。(相机也得用上面的权限获取方式获取一下权限,Android.Manifest.Permission.Camera,权限内容换成这个就行了,好多大神纹章就写Manifest.Permission.Camera,结果报错说找不到Manifest,我研究了一天,才发现加上Android.就行了,那些写文章的人都是吃屎的吧!不写清楚点,变量就写个后边半拉起码告诉我们要using Android;吧!)

然后一个弹出相机事件就两行

Intent ina = new Intent(Android.Provider.MediaStore.ActionImageCapture);

StartActivityForResult(ina, 1);//这个1写几都行,和获取权限的时候一样,写几返回的时候就case几。

覆写个回调函数,获取相机返回结果为Result.Ok

protected override void OnActivityResult(int requestCode, [GeneratedEnum] Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);
            switch (requestCode)
            {
                #region case 1 拍照结果
                case 1:
                    switch (resultCode)
                    {
                        case Result.Ok:
                            break;
                    }
                    break;
                #endregion
            }

}

然后我就遇到了有史以来最大的坑。获取照片,就是我说的,下载了数十个工程,摘抄了数十篇纹章,都获取不了文件,就获取照片这个问题,已经搜索了4天了,终于看到一个逗逼的提问!

逗逼提问地址:https://ask.csdn.net/questions/753961#answer_1298893

窝巢!就这么1行,真的获取到了!虽然只是一个缩略图

Bitmap bm = (Bitmap)data.Extras.Get("data"); 

我存储出文件来,至少找到了缩略图,另外在网上搜索了一下Android.Gxxxxx.bitmap转byte数组的方式
                            byte[] bitmapData;
                            using (var stream = new MemoryStream())
                            {
                                你的bitmap图片.Compress(Bitmap.CompressFormat.Png, 0, stream);
                                bitmapData = stream.ToArray();
                            }
                            using (System.IO.FileStream fos = new FileStream(qj.lj路径 + "/缩略图.jpg",FileMode.Create))
                            {
                                fos.Write(bitmapData, 0, bitmapData.Length);
                            }

然后缩略图真的保存出来了!打开相机获取缩略图,说简单点一共就5行,1行判断权限,1行申请权限,1行新建相机,1行打开相机,1行获取缩略图,就tmd这5行,让我找了近百篇各种博客才找到,你们这些大神是不是都有病!我咧个去。

到目前为止我还没有找到原图,等找到以后会进行更新!

本文地址:https://blog.csdn.net/center1370/article/details/107387901

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网