当前位置: 首页 > 科技观察

程序员如何从产品角度提升应用体验:Android权限优化

时间:2023-03-19 21:09:42 科技观察

前言:你在开发过程中是否经常遇到这种情况:很多产品体验细节,特别是涉及到技术的产品细节和设计可能没有给出详细的解决方案,甚至可能不太注意这方面的体验细节。比如应用的缓存清理机制应该如何实现?权限申请应该放在哪里?如果用户没有给应用必要的权限,用户应该怎么办...这时候,作为开发者,尤其是对于自己的产品追求更好用户体验的开发者,其实可以作为一个产品,从角度思考产品,如何在技术实现细节上让自己的APP体验更好。不要低估这些细节。一个产品最好的体验是由无数细节组成的。1、应用通知权限优化众所周知,推送对于一个APP来说是一个非常重要的功能。在好的产品设计中,推送可以有效提高产品活跃度,增加用户忠诚度和留存率。但是,用户可能会无意中关闭了应用的通知权限,导致无法接收到推送通知(用户主动关闭应用的通知权限除外)。例如,华为手机会在通知中心直接提示用户是否关闭某个应用的通知权限。如果用户,尤其是新手用户,不小心关闭了通知权限,导致应用收不到推送通知,他们可能会把这种情况当成bug,反馈给客服(不要高估用户的顾虑)随时)了解智能手机的使用情况,尤其是当你的APP的目标用户还包括中老年人时)。仔细观察华为手机的推送中心会发现,当应用的通知权限被禁止时,体验好的应用会在合适的时间和场景进行提示,告知用户通知在其中的作用应用程序。尽量消除用户的不信任和谨慎心理,引导用户开启通知权限。那么,我们怎么知道我们的应用通知权限被禁止了呢?被禁了怎么办?下面说说解决办法。1.1检测应用的通知权限状态检测应用的通知权限其实比较简单。通过查询官方文档可以发现,在support库的API版本24.0.0中,已经有现成的方法可以直接查询应用的通知权限状态:NotificationManagerCompat.from(this).areNotificationEnable();但是,这意味着应用的compileSdkVersion也需要和支持库的版本保持一致。如果应用当前使用的compileSdkVersion低于24.0.0或者由于某些历史原因无法将compileSdkVersion提升到24.0.0以上,那么就没有办法检测到应用的通知权限了吗?其实还是有办法的。通过查看系统源码,可以发现NotificationManagerCompat.from(this).areNotificationEnable()方法在不同版本的SDK上有不同的实现。/***返回调用包的通知是否被阻塞*/publicbooleanareNotificationsEnabled(){returnIMPL.areNotificationsEnabled(mContext,mNotificationManager);}IMPL是实现Impl接口的实现类对象,在静态代码块中通过判断手机系统使用的版本号初始化不同的实现类:static{if(BuildCompat.isAtLeastN()){IMPL=newImplApi24();}elseif(Build.VERSION.SDK_INT>=19){IMPL=newImplKitKat();}elseif(Build.VERSION.SDK_INT>=14){IMPL=newImplIceCreamSandwich();}else{IMPL=newImplBase();}SIDE_CHANNEL_BIND_FLAGS=IMPL.getSideChannelBindFlags();}当手机系统Android版本低于4.4.0,areNotificationEnable()方法默认会返回true。所以该方法只能在4.4.0以上的手机系统上返回准确结果。/***返回来自调用包的通知是否被阻止。*/publicbooleanareNotificationsEnabled(){INotificationManagerservice=getService();try{returnservice.areNotificationsEnabled(mContext.getPackageName());}catch(RemoteExceptione){throwe.rethrowFromSystemServer();}}这种反射方式其实是通过AppOpsManager和AppOpsService获取位于/data/system/目录下的Appops.xml文件中的数据。因此,本系统源码中的方法可以单独提取出来,作为检测通知权限状态的通用方法。关于AppOpsManager这里先不展开,后面1.4章单独讲。1.2引导用户跳转到通知权限设置界面现在已经检测到应用的通知权限状态,当应用的通知权限被禁用时,应该出现提示,告知用户通知在其中的作用应用程序并引导用户打开它。通知权限。下面是一个通用的跳转通知权限设置的方法:.settings.APP_NOTIFICATION_SETTINGS");intent.putExtra("app_package",this.getPackageName());intent.putExtra("app_uid",this.getApplicationInfo().uid);startActivity(intent);}elseif(android.os建立"+this.getPackageName()));startActivity(intent);}}5.0以上可以直接跳转到某个应用的通知权限快捷设置界面。但是5.0以下是没有办法直接跳转到通知权限设置界面的,所以目前的方法是跳转到某个应用的设置界面,设置界面列表中应该有通知权限管理的入口。如果你有更好的方法,欢迎在评论中指出。这里还有一个问题需要大家思考:关于notification权限提示方案,应该在什么时候或者什么场景下出现?提示应该多久出现一次?是只提示一次,还是只要用户不打开通知就可以了?总是提示权限?欢迎在留言中发表您的看法。1.3通知权限关闭时,Toast可能无法正常工作。虽然和通知权限的优化无关,但这里还是要提一下。这是我在调研通知权限优化时无意中发现的一个坑:在大部分机型上,关闭应用的通知权限后,系统的Toast会直接无法正常工作。以下是我测试过的数据:可见受此坑影响的机型范围还是挺大的。为什么会这样?查看源码后发现Toast中也使用了NotificationManagerService。Toast执行完show()方法后,enqueueToast()执行如下:pkg+"byuserrequest.");return;}}原来这里也用到了检测通知权限的方法noteNotificationOp()。如果通知权限被禁用,Toast将无法正常工作。对于安卓手机,在应用中随处可见Toast。如果由于通知权限导致Toast不能正常工作,影响还是蛮大的。所以,这里建议大家寻找Toast的替代品,不要在项目中直接使用系统自带的Toast。同样,如果大家有什么好的解决方案,欢迎在留言中指出。1.4AppOpsManager是如何工作的上面说了AppOpsManager,这里简单介绍一下它的工作原理。AppOpsManager的工作框架如下:SettingUI通过AppOpsManager与AppOpsService进行交互,为用户提供管理各个app操作的权限。AppOpsService专门处理各种用户设置,这些设置存储在/data/system/appops.xml文件中。AppOpsService也会被注入各种相关的系统服务来检查权限操作。AppOpsService的判断被注入到每个权限操作对应的系统服务中(比如定位相关的LocationService,Audio相关的AudioService等)。如果用户进行了相应的设置,那么这些系统服务就会进行相应的处理。比如LocationManagerSerivce的位置相关接口实现时,会判断调用该接口的app是否被用户设置为禁止该操作。如果有这样的设置,定位将不会继续。2、应用权限的及时优化限于篇幅,这里以摄像头权限为例。假设需求如下:在需要使用摄像头的场景中,首先检查是否提前开启了摄像头权限。如果没有,请尝试申请相机权限。如果用户仍然拒绝,则会出现权限提示,引导用户开启摄像头权限。以下是微信的处理方法:(1)6.0以上系统,先尝试申请相机权限,用户点击禁用后弹出引导界面。系统自带检查权限是否允许的方法:ActivityCompat.checkSelfPermission(context,permission)但是6.0以下,如果要检查camera权限,没有好的方法。***,查阅了各种资料,似乎只有一种简单粗暴的检测摄像头权限的方法:/***6.0系统以下,通过尝试打开摄像头来判断是否有摄像头权限**@返回*/privatebooleancheckCameraPermissionUnderM(){booleanisCanUse=true;CameramCamera=null;try{mCamera=Camera.open();Camera.ParametersmParameters=mCamera.getParameters();mCamera.setParameters(mParameters);}catch(Exceptione){isCanUse=false;}if(mCamera!=null){try{mCamera.release();}catch(Exceptione){e.printStackTrace();returnisCanUse;}}returnisCanUse;}使用此方法时,手机6.0以下,一般,Camera.open()方法被调用。如果没有开启摄像头权限,会先弹出摄像头权限申请框。如果允许点击,则该方法将返回true,如果禁止点击,则返回false。这里需要指出的是,如果使用相机通过Intentintent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE)跳转到系统的相机界面,那么即使是禁止申请前来拍照。这种情况下,要不要做权限检查就看个人意见了。不知道大家有没有注意到微信6.0及以下版本的弹出提示对话框有点不一样。6.0以上提供了“转到设置”选项。点击后会跳转到设置中的应用列表界面。6.0以下,只是提醒一下。这也是一个产品细节。个人认为,因为6.0以下,国内有些系统在设置里根本就没有权限管理,需要去官方手机管家类应用管理权限。国内这么多系统适应起来有点吃力。如果没有很好的解决方案,那么最好不要擅自帮助用户做决定。可以看出,微信在适配跳转权限设置界面的过程中也是经过多方考量,最终选择了这种折中的方案。说到这里,既然权限提示优化的思路已经有了,那么也可以在自己的项目中封装一个权限管理类,“检查权限-禁止-尝试申请权限-拒绝-弹出提示框-引导用户通过一种方法一次打开权限”。3.小结本文涉及的知识点可能并??不深奥,但我想告诉大家,如果开发者从产品的角度来提升应用体验,可以从什么角度入手。如果我能给你一些灵感就太好了。看完文章想一想,自己申请在权限提示上的体验是不是很完美?如果还有改进的余地,那就根据自己应用Bar的实际情况,快速完善权限提示的体验。相信我,这样做,您的用户会感谢您。