首页 文章 精选 留言 我的

精选列表

搜索[密码管理器],共10000篇文章
优秀的个人博客,低调大师

别再问WiFi密码了,HMS Core统一扫码服务让手机一键联网

现代生活离不开网络,在餐厅、商场等公共场所,手机连接WiFi一直是高频使用场景。虽然公共场所的免费WiFi越来越多,但网络连接过程却很麻烦。有的需要打开网页注册或点击广告链接才能上网,还有的要求下载特定App才能连接。 那么有没有什么更方便的联网方式呢?“扫码联网”提出了解决方案,商家可以在店放置包含WiFi信息的二维码。用户打开手机相机扫码即可连接WiFi,还支持将二维码分享给身边好友,使入网更快、更直观,并且无需担心隐私泄露、被推送无用信息等问题。 效果展示 实现原理 通过HMS Core统一扫码服务的码生成和扫码能力,轻松实现扫码连WiFi这一场景。 开发实战 一、构建扫码功能 开发准备 1.1 配置华为Maven仓地址 在项目中“buildscript > repositories”中配置HMS Core SDK的Maven仓地址。在“allprojects > repositories”中配置HMS Core SDK的Maven仓地址。 buildscript { repositories { google() jcenter() // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huawei.com/repo/'} } } allprojects { repositories { google() jcenter() // 配置HMS Core SDK的Maven仓地址。 maven {url 'https://developer.huawei.com/repo/'} } } Gradle 7.0版本后,“allprojects > repositories”配置已迁移到项目级“settings.gradle”文件中。“settings.gradle”文件配置示例如下: dependencyResolutionManagement { ... repositories { google() jcenter() maven {url 'https://developer.huawei.com/repo/'} } } 1.2 添加编译依赖 位置应用build.gradle dependencies{ //Scan SDK implementation 'com.huawei.hms:scan:2.3.0.300' } 1.3 代码混淆 在应用级根目录下打开混淆配置文件“proguard-rules.pro”,加入排除HMS Core SDK的混淆配置脚本。 -ignorewarnings -keepattributes *Annotation* -keepattributes Exceptions -keepattributes InnerClasses -keepattributes Signature -keepattributes SourceFile,LineNumberTable -keep class com.huawei.hianalytics.**{*;} -keep class com.huawei.updatesdk.**{*;} -keep class com.huawei.hms.**{*;} 1.4 Manifest.xml添加权限 <!--相机权限--> <uses-permission android:name="android.permission.CAMERA" /> <!--文件读取权限--> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 1.5 申请动态权限 ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA, Manifest.permission.READ_EXTERNAL_STORAGE}, requestCode); 1.6 申请权限结果 @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (permissions == null || grantResults == null) { return; } // 申请权限成功或已有权限 if (requestCode == CAMERA_REQ_CODE) { // Default View Mode方式扫码接口 // 参数说明: // activity 请求扫码的activity // requestCode 扫码请求的请求码,用于鉴定activity返回时是否从扫码界面返回。 // option 扫码格式选项,可以置为“null” ScanUtil.startScan(this, REQUEST_CODE_SCAN_ONE, new HmsScanAnalyzerOptions.Creator().create()); } } 1.7 回调接口接收扫码结果,相机扫码和导入图片扫码均通过该接口返回。 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK || data == null) { return; } if (requestCode == REQUEST_CODE_SCAN_ONE) { // 导入图片扫描返回结果 HmsScan hmsScan = data.getParcelableExtra(ScanUtil.RESULT); if (hmsScan != null) { // 码值结果 rawResult自定义TextView rawResult.setText(hmsScan.getOriginalValue()); } } } 二、构建码生成功能 构建扫码功能同样需要配置Marven仓地址,添加编译依赖和配置混淆脚本,参考上方1.1,1.2和1.3 2.1 Manifest.xml添加权限 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 2.2 申请动态权限 ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode); 2.3 申请权限结果 @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (permissions == null || grantResults == null) { return; } if (grantResults[0] == PackageManager.PERMISSION_GRANTED && requestCode == GENERATE_CODE) { Intent intent = new Intent(this, GenerateCodeActivity.class); this.startActivity(intent); } } 2.4 生成二维码 public void generateCodeBtnClick(View v) { try { HmsBuildBitmapOption options = new HmsBuildBitmapOption.Creator() .setBitmapMargin(margin) .setBitmapColor(color) .setBitmapBackgroundColor(background) .create(); resultImage = ScanUtil.buildBitmap(content, type, width, height, options); barcodeImage.setImageBitmap(resultImage); } catch (WriterException e) { Toast.makeText(this, "Parameter Error!", Toast.LENGTH_SHORT).show(); } } 2.5 保存二维码 public void saveCodeBtnClick(View v) { if (resultImage == null) { Toast.makeText(GenerateCodeActivity.this, "Please generate barcode first!", Toast.LENGTH_LONG).show(); return; } try { String fileName = System.currentTimeMillis() + ".jpg"; String storePath = Environment.getExternalStorageDirectory().getAbsolutePath(); File appDir = new File(storePath); if (!appDir.exists()) { appDir.mkdir(); } File file = new File(appDir, fileName); FileOutputStream fileOutputStream = new FileOutputStream(file); boolean isSuccess = resultImage.compress(Bitmap.CompressFormat.JPEG, 70, fileOutputStream); fileOutputStream.flush(); fileOutputStream.close(); Uri uri = Uri.fromFile(file); GenerateCodeActivity.this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, uri)); if (isSuccess) { Toast.makeText(GenerateCodeActivity.this, "Barcode has been saved locally", Toast.LENGTH_LONG).show(); } else { Toast.makeText(GenerateCodeActivity.this, "Barcode save failed", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { Toast.makeText(GenerateCodeActivity.this, "Unkown Error", Toast.LENGTH_SHORT).show(); } } 欲了解更多HMS Core统一扫码服务详情,请参阅: https://developer.huawei.com/consumer/cn/doc/development/HMSCore-Guides/service-introduction-0000001050041994?ha_source=hms1 华为开发者联盟官网 获取开发指导文档 参与开发者讨论请到Reddit社区 下载demo和示例代码请到Github 解决集成问题请到Stack Overflow

优秀的个人博客,低调大师

【博客大赛】+移动端4位/6位验证码/密码输入框H5实现

阶段一、六位验证码输入框 先贴图,需要实现的效果是这样的。 实现思路有两个: 1、用6个input,输入一个数字后将focus给下一个输入框。 2、用一个input和6个span,input隐藏,用span显示。 现在大部分都是使用的第二种方法。 两种方案遇到的坑,以及优缺点,如下: 方案一:6个input。 主要就是用js切换focus,在安卓是相当流畅的,但是在ios会严重卡顿,简直逼死强迫症。 HTML: JS: functioninputNext(id){//传过来的id是个对象 varindex=Number(id.id.split("_")[1]) if(id.value.length<1){//删除 id.value='' if(index>1){ varpreId='check_'+Number(Number(index)-1) document.getElementById(preId).focus() returnfalse } }else{ if(id.value.length>1){ varnextValue=id.value.slice(1,2) varnextId='check_'+Number(Number(index)+1) id.value=id.value.slice(0,1) if((index+1)<=6){ document.getElementById(nextId).value=nextValue document.getElementById(nextId).focus() } } } } PS:我这里写的删除方法是有问题的,这也是我果断放弃这种方案的原因之一。 如果正常输入,然后删除是可以的。 但是输入几个数后,先点击中间的框删除一个数字,再回到最后,便只能将中间到最后的这几个删掉,最前面的还需要手动点一下得到focus才能删除。 这对用户来说,简直太不友好了。。。 CSS: .divYZM{ width:90%; margin:0auto; height:100px; background-color:rgba(74,35,35,0.42); } .numDiv{ display:block; width:10%; float:left; border-radius:5px; text-align:center; line-height:60px; font-size:20px; font-weight:900; color:red; background-color:white; height:60px; border:0; padding:0; margin:0; margin-left:5.7%; top:20px; position:relative; caret-color:transparent; } 这里遇到的坑,举一个栗子。 input限制长度的属性maxlength a、与如下两种配合使用(tel也可以限制) 或者 b、当type为number时不起作用。这时需要用js控制。 注意:此外,tel类型的input在ios上会调出全数字键盘,而number类型的input则会调出带有标点符号的键盘。 方案二:1个input和6个span。 隐藏input,用span显示内容。大坑就是,何种情况下能调起ios的软键盘呢? 先贴一下我刚开始的input样式。 width:0; height:0; border:0; padding:0; margin:0; 第二种 display:none; 简单粗暴,结果就是,ios木得反应。为啥呢,我想不通。 后来在晚上睡觉的时候我在想,我这两种方式input都么有占位啊,那是不是占位了就可以了呢? 经测果然是可以的(默默谴责自己懒了一下,没有将不隐藏input的情况,在手机上进行测试)。 但是这里要注意一点,input占位建议写成宽度占位,如果是高度占位,width为0时,会出现输入1234,显示为4321这种情况,光标默认在最前,且用js手动挪动光标到最后也是不起效果的。例如,类似代码我设置了宽度为0,且使用了如下方法挪动光标到最后,以解决输入1234,显示4321的问题。完全没得作用。后来突然想到是不是因为宽度为0。给input加了宽度才正常显示了。 错误代码示例:宽度为0 input的样式: #yzm{ width:0; border:0; padding:0; margin:0; height:.44rem; position:absolute; outline:none; color:transparent; text-shadow:000transparent; margin-left:-100%; } 对应的挪动光标的方法: lettObj=document.getElementById("#yzm"); letlen=tObj.value.length; if(tObj.setSelectionRange){ tObj.setSelectionRange(len,len); tObj.focus(); }elseif(tObj.createTextRange){ varrng=tObj.createTextRange(); rng.move('character',len); rng.select(); } 接下来贴正确代码。 CSS: #yzm{ width:90%; height:.44rem; border:0; padding:0; margin:0; margin-left:-100%; outline:none; color:transparent; text-shadow:000transparent; position:absolute; } #yzmTable{ width:90%; height:100px; margin:0auto; background-color:rgb(441212/93%); border-radius:5px; } #yzmTablespan{ display:block; width:10%; height:60px; float:left; border-radius:5px; text-align:center; line-height:60px; font-size:20px; font-weight:900; color:red; background-color:white; margin-left:5.7%; top:20px; position:relative; } 这里对input的样式也包括对光标的隐藏,我在第一种方案中对光标未进行处理,因为在看到ios的卡卡卡之后果断放弃了第一种方案。 HTML: JS: functionintoYzm(index){ varele=document.getElementById("yzm") ele.focus() } functionyzmInsert(){//input内容改变时触发 for(vari=1;i<=6;i++){ varnextId='s_'+i document.getElementById(nextId).innerHTML='' } varyzm=document.getElementById("yzm").value varyzmArr=yzm.split(''); for(vari=0;i<yzmArr.length;i++){ constnum=yzmArr[i]; varid='s_'+Number(i+1) document.getElementById(id).innerHTML=''+num+'' } } //收起软键盘的方法,点击除了输入框之外的其他区域就收起软键盘 $('body').on('touchend',function(el){ if(el.target.tagName!='SPAN'){ $('yzm').blur() } }) 在第二种方案中有两个地方注意下: a、在js方法中加了对全局中6个span标签(即六个输入框)之外区域点击事件的监听,用以收起软键盘,方法如下。 $('body').on('touchend',function(el){ if(el.target.tagName!='SPAN'){ $('yzm').blur() } }) (比较粗糙,如果页面中还有别的部分就比较受影响了,可以自行改进) b、在隐藏的input中添加了onclick方法,如下并且在其中用了blur方法使得此输入框失去焦点。为什么这么做呢? 因为此处的隐藏并非真正的隐藏,而是透明化处理,边框包括光标全部透明化,但实际上它还是占位的,所以当你点击输入框上方空白处时,仍会唤起软键盘,就和我们之前所想的点击输入框之外区域就收起软键盘冲突了。 因此将input自身的点击获取focus禁止掉,就OK了。 阶段二、四位验证码输入框 pia效果图 基本上是基于以上 阶段一、六位验证码输入方式(以下统称“阶段一”) 的后期填坑 这是仿照“阶段一”又新写了个验证码的小页面,有些微的不同 输入编号后四位,可能有X字母,所以隐藏input的type不能设置为number了,懒惰的我直接删掉了type属性(造坑开始) 且因为上次研究时漏掉了一些知识点,也造了一波坑,以下一一列举。 问题1、四位空格输入,1234,但是每次输入下一个数字,前面的内容都会整体向后移动,输完结果是4321;且输入一半点删除没反应。还得输入总共五位数字才能删除 ??!我懵了,input给显示的几个span的赋值方式(见“阶段一”的js代码)是一样样的呀,怎么回事 debug发现隐藏的input值就已经是4321了,所以不是赋值方法的问题,以下是有问题的隐藏input的样式: #IdentifyNoCheckInput{ width:0; border:0; padding:0; margin:0; height:10px; position:absolute; top:-11px; outline:none; color:transparent; text-shadow:000transparent; } 最初怀疑是光标自动到了最前面导致的,使用了百度的手动移动光标方法,并不管用。 对比“阶段一”中隐藏input的样式,可以发现本次宽度设成了0,有高度(高度随意,只要不挡住别的元素显示就行),有宽度或高度是为了占位,能唤起软键盘。 而“阶段一”中是有宽度的,这个差别引起了我的怀疑。为以上样式新增两条 width:100%; margin-left:-100%; 再进行输入,正常了,输入1234就显示1234,也不会有删不掉的情况存在了。 第一个坑填坑完毕。 总结:设置宽度高度是为了占位,从而唤起软键盘。有高度或有宽度就可以,但是建议设置宽度,以免发生输入内容反转的情况。 问题2、部分ios手机无法正常唤起软键盘 在测试的时候,手机型号就那几个,大家测得顺顺当当。上线之后就报了好多ios无法正常输入的问题。 问题版本如下: 苹果p8,苹果6+(系统版本10),苹果6pok(系统版本11.4.1)和苹果6p plus(系统版本12.4.8) 以下是隐藏input的代码: 最初思路跑偏,开始各种查版本兼容的方法,但是没有合适的解决方案。 后在老大的提醒下,既然上篇文章中的验证码没有报这个问题,这个也不应该有问题啊。 对比发现就是少了个type,就想到是不是缺少type导致的,加了个type="text" emmmm,问题解决。 菜鸟教程描述如下: 大部分的坑都是自己给自己造的~~~ 以下贴完整代码(我这个页面是以iframe被其他页面调用的,所以有个获取链接的操作以及拆分参数的方法) 请输入验证内容--> 确认4){//当type="number",属性maxlength不起作用 inNo=inNo.slice(0,4) document.getElementById("IdentifyNoCheckInput").value=inNo } varinNoArr=inNo.split(''); for(vari=0;i

优秀的个人博客,低调大师

解读阿里云成功运营生态体系的两个关键密码:开放与双向赋能

早在2011年加入阿里云的时候,杨名就发现,生态已经成为阿里云核心的战略。2014年8月,阿里云推出“云合计划”,旨在聚集合作伙伴、构建新的云生态体系,为企业、政府等提供一站式云服务。 三年来,阿里云生态逐渐扩大,云合计划也迎来了新升级,形成了产品生态、行业生态、区域生态、云市场、教育生态。 据统计,阿里云已经占据国内公有云计算市场50%以上的市场份额。这得到了中标软件副总经理李震宁的证实——过去一年之间,他在参与多个地方政府项目评审过程中就发现,半数以上中小企业实际后台运行环境都是阿里云。这也坚定了他跟阿里云合作的信心。 为数百万家中小企业用户提供IT服务的畅捷通总裁杨雨春更是体会到了阿里云对小微企业的帮助。畅捷通将主流应用构建在阿里云平台上,之所以选择与阿里云的合作,相对于其他云计算平台,阿里云以提供一站式服务为代表的商业成熟度最高

优秀的个人博客,低调大师

压缩包怎么加密码发给别人国产电脑,从加密到解压全流程说明,附报错排查

合同扫描件、身份证照片、工资单这类文件,直接拖进微信窗口发给对方,是很多人的默认操作。文件离开本机之后,发送方就不再掌握它的流向:聊天记录可能被同步到其他终端,接收方手机可能丢失,文件可能经过群聊或网盘中转。每经过一道手,内容被非预期读取的概率就高一分。

优秀的个人博客,低调大师

本地管理员权限收敛实践:用 Windows LAPS 做密码轮换,用即时提权管临时授权

这不只是管理问题。微软在Windows LAPS官方文档里讲得很直接:域内多台机器共用一套本地管理员凭据,是横向移动成本最低的路径之一。攻击者拿到一台机器的哈希,不用域管理员权限,就能登录所有共用这份凭据的机器。带管理员权限的终端失陷之后,他还能直接关终端防护、装持久化、清日志,检测和溯源的难度都会上一个台阶。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册