android6.0开发时出现Bugjmeter录制bugfree视频出现等待,应如何处理

Android其他总结(10)
Dex分包,解决64K限制的问题:
参考链接:
问题1:Android项目中的命名规则
举例如下:
TemplateActivity
Activity布局文件:
activity_模块名_template
Activity布局文件Id定义:template_listView(组件类型)[_history]
TemplateAdapter
Adapter布局文件:
模块名_template_item
Adapter布局文件中Id定义:template_item_tv(组件类型)_title
String|dimen|style:
模块名_template_title(文字内容表达意思)
[]:可选; ():解释
使用场景:
获取设备信息,键值对形式,然后进行Base64传递到Server。
例如:osv=6.0&screenpix=&IP=::1%1
遇到问题:
获取到的IP含有:等非字符和数字的内容,传递到Server进行Base64解码就会出现错误。
解决办法:
对获取到的设备信息进行encode,即对value URLEncoder.encode(value.toLowerCase(), "utf-8");
key不进行处理。
有时候获取到的Base64数据不完整,也会报错。
Error:(23, 12) This support library should not use a lower version (19) than the targetSdkVersion (20)
#解决办法:
compile 'com.android.support:appcompat-v7:19.+'
compile 'com.android.support:appcompat-v7:20+'
问题4: 登陆页面 输入时账号时 弹出键盘覆盖 密码输入框
期望:输入能够把输入页面顶上去。
解决方法:Activity设置成非全屏且:android:windowSoftInputMode = "adjustResize"
期望:点击一次弹出DatePickerDialog
解决方法:EditText改为TextView即可。
问题6:The content of the adapter has changed but ListView did not receive a notification
期望:不出现该bug
在Android开发过程中,使用了大量的ListView,发现这个错误偶尔会出现。特别是做压力测试的时候,不停的点击刷新,更容易出现这个错误。代码中已经使用了Adapter的notifyDataSetChanged()方法通知UI更新了,但是还是会出现这个错误。究其根本原因,还是线程之间同步的问题。比如,线程1更新了Adapter中的内容,却还没有来得及通知内容已经更新,就又有线程2更新了Adapter中的内容,这个时候如果线程1再通知内容更新,就会出现上述异常了。
在此提出一些解决办法:
对线程进行管理,如果当前Actitivty暂停了,及时停止这些线程。
数据更新后,要及时使用notifyDataSetChanged()方法通知UI,避免出现数据不一致的情况。
数据的更新,最好放在主线程中进行。这样可以使用同步数据更新与通知内容更新部分的代码。
最后补充一条我最终解决问题的方法:
在用到多线程的时候,可以对数据做缓存处理, 比如与ListView绑定的数据存储在ArrayList (dataList), 在线程中先将数据加入到临时ArrayList(tmpList) , 最后在调用notifyDataSetChanged()方法通知UI更新之前, 把临时ArrayList(tmpList)中的数据更新到ArrayList(dataList)中, 然后清空临时ArrayList(tmpList)数据。
问题7:内存泄露
思路:使用Memory Analyzer Tool(MAT)内存分析工具进行分析。
Jpush推送相关问题:
关于不活跃用户:长期未打开APP,则会被Jpush标志为不活跃用户,之后不再接收推送,(除非用户主动打开APP,此句话待验证)
新建的APP,所有安装用户都是活跃用户。
小米的手机,普通App默认是非自启动,自启动广播也被屏蔽。
EditText焦点键盘弹出问题:
在EditText的父级控件中找一个,设置成
android:focusable="true"
android:focusableInTouchMode="true"
问题10: 在Eclipse添加Android兼容包( v4、v7 appcompat )
问题11: ScrollView 和Listview冲突的解决方案:
问题12: 不同版本ADT混淆方式:
问题13 自动开关机实现:
FragmentStatePagerAdapter+viewpager第二次进入该fragment不显示数据
解决方法:
在含有ViewPager的Fragment的onCreateView方法中添加代码:
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null) {
parent.removeView(view);
AAPT err(): libpng error: Not a PNG file
使用的图片中存在不是png的图片
解决办法:
仅仅改后缀名是不可以的,必须使用工具转换,此处 推荐使用ImageMagick
16 Android半透明设置:
android:background="#b0000000"
支持格式如下:
#b0|000000 :b0代表透明度Alpha
com.mon.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Users/lincoln/Android/sdk/build-tools/23.0.3/aapt'' finished with non-zero exit value 1" data-snippet-id="ext.c9aab077cdd61fbf76c7c8" data-snippet-saved="false" data-codota-status="done">Error:Execution failed for task':app:processDebugResources'.& com.mon.process.ProcessException: org.gradle.process.internal.ExecException: Process 'command '/Users/lincoln/Android/sdk/build-tools/23.0.3/aapt'' finished with non-zero exit value 1
:app:processDebugResources’;说明是资源出问题了;
常见原因:
如下代码:如果没有定义格式,即没有format=”dimension”就会报错
<pre class="prettyprint prettyprinted" data-original-code="
" data-snippet-id="ext.75e957b777ba1cdcff1c5cb" data-snippet-saved="false" data-codota-status="done">
name="Btn_normal"&
name="img_width"
format="dimension"/&
EditTextView:
1. 设置光标到指定位置:setSelection()
2. 隐藏光标:setCursorVisible(false);
3. 选中内容:setSelectAllOnFocus(true);
4. 失去焦点:
et.requestFocus(); //请求获取焦点
et.clearFocus(); //清除焦点
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3764次
排名:千里之外
原创:29篇
(1)(1)(1)(5)(14)(11)作为Android开发者,最头疼是什么?相信大家会异口同声的说Bug!的确,这些是避免不了的同时也是最烦人,调Bug,改Bug,一个项目做完,剩下的几乎全是Bug的调试,有的公司很可能在项目上线前还有改不完的Bug,针对这些困扰Android开发者的种种难题,整理出了这些难题或是Bug的解决方案,希望能给大家带来帮助。
Android其它相关难题
Nielsen最近的研究数据表明,Android系统的设备已经在数量上超过iOS系统了…Android 如何实现垃圾清理、缓存清理?要删除什么哪些文件或者要怎么做?这…作为Android开发程序员,我们经常会遇到项目中R文件的丢失问题,大部分情况…默认EditText在获得焦点时,会弹出软键盘,如果想实现当EditText获得焦点时…上次鄙人做了一个简单的利用webView实现的一个浏览器!其中遇到了两个问题…可能对于Android开发者来说,软引用这个词有的会不是很熟悉,软引用在Java…在adroid 应用程序中,我们经常会用到异步加载。 所以我们也要知道如何取消…想学习Android编程应该有一年时间了...一直没有真的去做,应该就在几天前吧…
你在Android开发过程中,遇到哪类问题最多?
多线程方面
屏幕的分辨率
网络通信相关
Socket管理
UI和IO方面
作为Android开发者,最头疼是什么?相信大家会异口同声的说Bug!的确,这些是避...
谷歌在新品发布会上正式发布了传闻已久的Android 4.3 Jelly Bean更新。从命名可...
作为Android开发者,我们都离不开Android模拟器来运行我们项目,当然,你可能会...
作为Android开发人员,在开发项目的过程中,我们往往会遇到各种各样的难题,针...Android 6.0在我们原有的AndroidManifest.xml声明权限的基础上,又新增了运行时权限动态检测,以下权限都需要在运行时判断:
身体传感器
运行时权限处理
Android6.0系统默认为targetSdkVersion小于23的应用默认授予了所申请的所有权限,所以如果你以前的APP设置的targetSdkVersion低于23,在运行时也不会崩溃,但这也只是一个临时的救急策略,用户还是可以在设置中取消授予的权限。
声明目标SDK版本我们需要在build.gradle中声明targetSdkVersion为23
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "你的appid"
minSdkVersion 18
targetSdkVersion 23
//让他支持6.0权限
versionCode 1
versionName "1.0"
buildTypes {
minifyEnabled false proguardFiles getDefaultProguardFile ( 'proguard-android.txt'), 'proguard-rules.pro' } }
检查并申请权限
我们需要在用到权限的地方,每次都检查是否APP已经拥有权限,比如我们有一个下载功能,需要写SD卡的权限,我们在写入之前检查是否有WRITE_EXTERNAL_STORAGE权限,没有则申请权限
if (ContextCompat.checkSelfPermission(
this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED)
//申请WRITE_EXTERNAL_STORAGE权限
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE},
WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
请求权限后,系统会弹出请求权限的Dialog
用户选择允许或需要后,会回调onRequestPermissionsResult方法, 该方法类似于onActivityResult
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
doNext(requestCode,grantResults);
我们接着需要根据requestCode和grantResults(授权结果)做相应的后续处理
private void doNext(int requestCode, int[] grantResults) {
if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST_CODE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
// Permission Granted
// Permission Denied
Fragment中运行时权限的特殊处理
在Fragment中申请权限,不要使用ActivityCompat.requestPermissions, 直接使用Fragment的requestPermissions方法,否则会回调到Activity的 onRequestPermissionsResult
如果在Fragment中嵌套Fragment,在子Fragment中使用requestPermissions方 法,onRequestPermissionsResult不会回调回来,建议使用 getParentFragment().requestPermissions方法,这个方法会回调到父Fragment中的onRequestPermissionsResult,加入以下代码可以把回调透传到子Fragment
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
List&Fragment& fragments = getChildFragmentManager().getFragments();
if (fragments != null) {
for (Fragment fragment : fragments) {
if (fragment != null) {
fragment.onRequestPermissionsResult(requestCode,permissions,grantResults);
相关开源项目
PermissionsDispatcher
使用标注的方式,动态生成类处理运行时权限,目前还不支持嵌套Fragment。
RxPermissions
基于RxJava的运行时权限检测框架
简化运行时权限的处理,比较灵活
android-RuntimePermissions
Google官方的例子
以下权限只需要在AndroidManifest.xml中声明即可使用
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT
如果你喜欢这篇文章,花0.2s点下面的赞,谢谢哈
本文来自微信公众账号提交,由微讯啦收录,转载请注明出处。
微信扫码 分享文章[Android开发] Android6.0运行时权限处理 | IT知识库
-& 正文阅读
[Android开发]Android6.0运行时权限处理
Android6.0运行时权限处理
在运行时请求权限从Android 6.0(API级别23)开始,用户权限授予应用程序在应用程序运行时,当他们安装程序。这种方法简化了应用程序的安装过程,因为用户不需要安装或更新应用程序时授予权限。这也给了用户更多的控制应用程序的功能;例如,一个用户可以选择给相机应用程序访问相机而不是设备的位置。用户可以随时撤销权限,通过将应用程序的设置屏幕。系统权限分为两类,普通和危险:正常的权限不直接用户的隐私风险。如果你的应用程序清单列出了一个正常的权限,系统自动授予许可。
危险的权限可以给应用程序访问用户的机密数据。如果你的应用程序清单列出了一个正常的权限,系统自动授予许可。如果你列出一个危险的许可,用户必须显式地给应用程序审批。&
在所有版本的Android系统,您的应用程序需要申报的正常和危险的权限需要在其应用程序清单,如声明中所述的权限。然而,宣言的影响是不同的根据系统版本和SDK应用程序的目标水平:如果设备运行Android 5.1或更低,或应用程序的目标SDK是22或更低:如果你在清单列表一个危险的许可,用户授予权限安装应用程序时,如果他们不授予权限,系统没有安装应用程序。
如果设备运行Android 6.0或更高版本,和你的应用程序的目标SDK是23或更高:应用列表的权限清单,它必须要求每个危险的权限需要在应用程序运行时。用户可以授予或拒绝每一个权限,应用程序可以继续运行能力有限,即使用户拒绝权限请求。注意:从Android 6.0(API级别23),用户可以在任何时候从任何应用程序撤销权限,即使应用程序API级别较低的目标。你应该测试你的应用程序,以确认它正确行为的时候丢失了一个需要许可,无论什么API级别应用程序的目标。这节课描述了如何使用Android支持库检查,和请求,权限。Android 6.0的Android框架提供了类似的方法(API级别23)。然而,使用支持库比较简单,因为应用程序不需要检查哪个版本的Android上运行之前调用的方法。检查权限&如果你的应用需要一个危险的许可,你必须检查你是否有权限每次执行一个操作,要求许可。用户总是可以撤销许可,所以即使相机昨天使用的应用程序,它不能假设它今天仍有该权限。检查如果你有权限,调用ContextCompat.checkSelfPermission()方法。例如,这个代码片段展示了如何检查活动日历上写权限:
// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.WRITE_CALENDAR);如果应用程序许可,该方法返回PackageManager。PERMISSION_GRANTED,应用程序可以继续运行。如果应用程序没有许可,方法返回PERMISSION_DENIED,应用程序必须显式地要求用户许可。请求的权限如果你的应用需要一个应用程序清单中列出的危险的许可,它必须要求用户授予权限。Android提供了几种方法可用于请求许可。调用这些方法提出一个标准的Android对话框中,您不能定制。解释为什么这个应用程序需要的权限在某些情况下,您可能想要帮助用户理解为什么你的应用需要一个许可。摄影为例,如果一个用户启动一个应用程序,用户可能不会感到惊讶,允许应用程序要求使用相机,但是用户可能不理解为什么这个应用程序要访问用户的位置或联系人。在请求许可之前,你应该考虑为用户提供一个解释。记住,你不想淹没用户提供解释,如果你提供太多的解释,用户可能会发现应用令人沮丧和删除它。您可以使用的一种方法是提供一个解释只有在用户已经拒绝了该权限的请求。如果用户一直试图使用功能需要一个许可,但一直拒绝许可的要求,这可能表明用户不理解为什么允许应用程序需要提供该功能。在这样的情况下,它可能是一个好主意给一个解释。帮助找到的情况下,用户可能需要一个解释,Android提供了一种utiltity方法,shouldShowRequestPermissionRationale()。这个方法返回true,如果应用程序要求这个许可之前,用户拒绝请求。注意:如果用户拒绝许可请求过去,再次选择了不要问选项允许请求系统对话框中,这个方法返回false。该方法还返回false如果设备政策禁止应用程序拥有该权限。请求所需要的权限如果应用程序已经不允许它的需求,应用程序必须调用一个requestPermissions()方法来请求适当的权限。应用程序通过它想要的权限,以及一个整数要求您指定识别这个许可请求的代码。这种方法异步函数:它返回,用户响应对话框之后,系统调用应用程序的回调方法对结果的影响,通过相同的请求代码,应用程序传递给requestPermissions()。下面的代码检查应用程序允许读取用户的联系,必要时请求许可:
// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}注意:当您的应用程序调用requestPermissions(),系统显示一个标准对话框给用户。应用程序不能配置或改变对话框。如果需要提供任何信息或向用户解释,你应该这样做之前你叫requestPermissions(),解释为什么所述应用程序需要的权限。处理权限请求响应当应用程序请求权限,系统向用户提供了一个对话框。当用户响应,系统调用应用程序的onRequestPermissionsResult()方法,传递用户响应。你的应用必须覆盖那个方法来找出是否被授予许可。回调传递相同的请求代码传递给requestPermissions()。例如,如果一个应用程序请求READ_CONTACTS访问它可能回调方法如下:
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length & 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
// permission denied, boo! Disable the
// functionality that depends on this permission.
// other 'case' lines to check for other
// permissions this app might request
}所示的对话框,系统描述了允许组织你的应用程序需要访问;它不特定的权限列表。举个例子,如果你请求READ_CONTACTS许可,该系统对话框只是说你的应用程序需要访问设备的联系人。一旦为每个用户只需要许可权限组。如果你的应用程序请求的任何其他权限组(应用程序清单中列出),系统自动赋予他们。请求许可时,系统调用你onRequestPermissionsResult()回调方法和通过PERMISSION_GRANTED,以同样的方式将如果用户有明确授予你的要求通过系统对话框。注意:应用程序仍然需要每个许可需要显式地请求,即使用户已经允许另一个在同一组。此外,权限分组的分组可能改变未来的Android版本。你的代码不应该依赖于假设特定的权限或不在同一组。例如,假设您在应用程序列表READ_CONTACTS和WRITE_CONTACTS清单。如果你请求READ_CONTACTS和用户授予权限,然后你请求WRITE_CONTACTS,系统立即授予许可没有与用户交互。如果用户拒绝权限请求,应用程序应该采取适当的措施。例如,您的应用程序可能会显示一个对话框解释为什么它不能执行用户所请求的操作,需要许可。当系统要求用户授予权限,用户可以选择告诉系统不要求许可了。在这种情况下,任何时候一个应用程序使用requestPermissions()要求权限,系统立即否认了这一请求。系统调用你onRequestPermissionsResult()回调方法和通过PERMISSION_DENIED,以同样的方式将如果用户已经明确拒绝了你的请求。这意味着当你叫requestPermissions(),你不能假设任何直接与用户交互。&
加: 16:05:21&
更: 16:05:23&
&&网站联系: qq: email:&序自从升级到Android M以来,最大的改变就是增加了运行时权限RuntimePermission,6.0以上的系统如果没有做适配,运行了targetSDK=23的App时就会报权限错误。我们知道6.0以下的系统是按照的时候权限申请的,6.0和之后的版本是我们想要使用某个app的权限,去动态申请的,这也是基于安全上的考虑吧(比如:单机的象棋对战,请求访问通讯录权限等不合理的权限,这肯定是有问题的)。为了保护用户的隐私,谷歌官方将权限分为了两类,一个是正常权限(Normal Permissions),这类权限不涉及用户隐私,是不需要用户进行授权的,比如访问网络,手机震动等。还有一类是危险权限(Dangerous Permissions),一般是涉及到用户隐私的,需要用户进行授权,比如操作SD卡的写入,相机,录音等。我们来看一张权限的清单文件:我们可以通过adb shell pm list permissions -d -g进行查看。权限如何申请那么对于我们开发者来说,怎么适配6.0呢?按着官方的api走就行:1,在AndroidManifest文件中添加需要的权限。2,检查权限if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
}建议这些检查权限的代码可以写到基类里面去。3,申请授权 ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);说明:第一个参数是Context;第二个参数是需要申请的权限的字符串数组;第三个参数为requestCode,主要用于回调的时候检测。可以第二个参数看出,6.0是一次性申请多个权限的,系统会通过对话框逐一询问用户是否授权。4,处理权限申请回调@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length & 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
// permission denied, boo! Disable the
// functionality that depends on this permission.
}不过这里有个情况,对于用户上次拒绝的权限,在下次需要这个权限的时候,系统怎么处理的了?if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS))
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
}所以完整的处理逻辑:if (ContextCompat.checkSelfPermission(thisActivity,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
Manifest.permission.READ_CONTACTS)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(thisActivity,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}项目实践权限工具类:public class PermissionUtils {
private static final ArrayMap&String, Integer& MIN_SDK_PERMISSIONS;
MIN_SDK_PERMISSIONS = new ArrayMap&&(8);
MIN_SDK_PERMISSIONS.put(&com.android.voicemail.permission.ADD_VOICEMAIL&, 14);
MIN_SDK_PERMISSIONS.put(&android.permission.BODY_SENSORS&, 20);
MIN_SDK_PERMISSIONS.put(&android.permission.READ_CALL_LOG&, 16);
MIN_SDK_PERMISSIONS.put(&android.permission.READ_EXTERNAL_STORAGE&, 16);
MIN_SDK_PERMISSIONS.put(&android.permission.USE_SIP&, 9);
MIN_SDK_PERMISSIONS.put(&android.permission.WRITE_CALL_LOG&, 16);
MIN_SDK_PERMISSIONS.put(&android.permission.SYSTEM_ALERT_WINDOW&, 23);
MIN_SDK_PERMISSIONS.put(&android.permission.WRITE_SETTINGS&, 23);
private static volatile int targetSdkVersion = -1;
public static boolean checkPermissions(int... grantResults) {
if (grantResults.length == 0) {
for (int result : grantResults) {
if (result != PackageManager.PERMISSION_GRANTED) {
public static boolean hasSelfPermissions(Context context, String... permissions) {
for (String permission : permissions) {
if (permissionExists(permission) && !hasSelfPermission(context, permission)) {
private static boolean permissionExists(String permission) {
Integer minVersion = MIN_SDK_PERMISSIONS.get(permission);
return minVersion == null || Build.VERSION.SDK_INT &= minV
private static boolean hasSelfPermission(Context context, String permission) {
return PermissionChecker.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
} catch (RuntimeException t) {
public static boolean shouldShowRequestPermissionRationale(Activity activity, String... permissions) {
for (String permission : permissions) {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
@TargetApi(Build.VERSION_CODES.DONUT)
public static int getTargetSdkVersion(Context context) {
if (targetSdkVersion != -1) {
return targetSdkV
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
targetSdkVersion = packageInfo.applicationInfo.targetSdkV
} catch (PackageManager.NameNotFoundException ignored) {
return targetSdkV
}这里可以根据实际情况进行优化和扩展基类:public class BasePermissionActivity extends AppCompatActivity {
private PermissionHandler mHandler=
private static int requesrCode=001;
* 请求权限
protected void requestPermission(String[] permissions, PermissionHandler handler) {
if (PermissionUtils.hasSelfPermissions(this, permissions)) {
handler.onGranted();
mHandler =
ActivityCompat.requestPermissions(this, permissions, requesrCode);
protected void requestPermission( PermissionHandler handler,String permissions) {
if (PermissionUtils.hasSelfPermissions(this, permissions)) {
handler.onGranted();
mHandler =
ActivityCompat.requestPermissions(this, new String[]{permissions} , requesrCode);
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (mHandler == null)
if (PermissionUtils.checkPermissions(grantResults)) {
mHandler.onGranted();
if (!PermissionUtils.shouldShowRequestPermissionRationale(this, permissions)) {
if (!mHandler.onNeverRequest()) {
Toast.makeText(this, &权限已被拒绝,请在设置-应用-权限中打开&, Toast.LENGTH_SHORT).show();
mHandler.onDenied();
public abstract class PermissionHandler {
//权限通过
public abstract void onGranted();
//权限拒绝
public void onDenied() {
//不再询问
public boolean onNeverRequest() {
}测试:public class MainActivity extends BasePermissionActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
private void init() {
request1();
private void request1() {
requestPermission(new String[]{Manifest.permission.CAMERA}, new PermissionHandler() {
public void onGranted() {
Intent intent = new Intent(); //调用照相机
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
startActivity(intent);
public void onDenied() {
Toast.makeText(MainActivity.this, &拒绝&, Toast.LENGTH_SHORT).show();
private void request2() {
requestPermission(new String[]{Manifest.permission.CAMERA}, new PermissionHandler() {
public void onGranted() {
Intent intent = new Intent(); //调用照相机
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
startActivity(intent);
public void onDenied() {
Toast.makeText(MainActivity.this, &拒绝&, Toast.LENGTH_SHORT).show();
}代码:最后附上鸿洋封装的比较好的库:
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:393125次
积分:8833
积分:8833
排名:第1646名
原创:444篇
转载:257篇
译文:14篇
评论:62条
阅读:1699
文章:15篇
阅读:12902
文章:31篇
阅读:29556
文章:17篇
阅读:10575
文章:19篇
阅读:14276
文章:10篇
阅读:10708
文章:13篇
阅读:22832
文章:70篇
阅读:63352
(25)(30)(37)(50)(26)(51)(16)(34)(24)(18)(7)(23)(15)(7)(22)(16)(4)(15)(8)(11)(7)(8)(6)(16)(15)(7)(8)(8)(22)(24)(14)(27)(13)(20)(27)(58)(2)

我要回帖

更多关于 android 6.0 bug 的文章

 

随机推荐