首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安卓权限checkSelfPermission不起作用

安卓权限checkSelfPermission不起作用
EN

Stack Overflow用户
提问于 2019-09-12 23:28:05
回答 3查看 2.5K关注 0票数 2

在我的应用程序的AndroidManifest.xml中,我将目标API指定为26:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.javasrv"
android:minSdkVersion="23"
android:targetSdkVersion="26"
android:versionCode="6"
android:versionName="1.0.0">
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

但当我在安卓x86 8.1上运行这个应用程序,并通过系统菜单禁用存储访问权限时,它说:“这个应用程序是专为较旧版本的安卓设计的。拒绝许可可能会使它不再像预期的那样工作。”

怎么可能呢?

此外,运行时权限检查也有问题:它始终认为,即使我在系统设置中禁用了访问权限,也仍然会授予该访问:

代码语言:javascript
复制
if (ContextCompat.checkSelfPermission(LoaderActivity.this, permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    Toast.makeText(LoaderActivity.this, "PERMISSION_DENIED", Toast.LENGTH_SHORT).show();
    Log.d("*** Loader::onCreate ***", "PERMISSION_DENIED");
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission.WRITE_EXTERNAL_STORAGE)) {
    } else {
    }
    ActivityCompat.requestPermissions(this, new String[]{permission.WRITE_EXTERNAL_STORAGE}, 0);
} else {
    Toast.makeText(LoaderActivity.this, "PERMISSION_GRANTED", Toast.LENGTH_SHORT).show();
    Log.d("*** Loader::onCreate ***", "PERMISSION_GRANTED");
}

再一次,还不清楚这是怎么回事。有什么想法吗?

编辑:,我正在使用android v26和android库v23。

汇编脚本:

代码语言:javascript
复制
file=javasrv.apk

# export CLASSPATH=/opt/android-sdk/platforms/android-26/android.jar:/opt/android-sdk/extras/android/support-library/23.2.1/android-support-v4.jar
#
rm -f com/javasrv/*.class
javac -cp $CLASSPATH -source 1.8 -target 1.8 com/javasrv/*.java
#dx --dex --output classes.dex com/javasrv/*.class
dx --dex --output classes.dex com/javasrv/*.class android/support/v4/app/*.class android/support/v4/content/*.class

#aapt package -f -m -F "$file" -M AndroidManifest.xml -S res -I "$CLASSPATH"
#aapt add "$file" classes.dex
rm -rf build && mkdir build
find ./res -type f  | grep -vE '\.sw.$' | xargs -I{} aapt2 compile -o build "{}" --no-crunch
aapt2 link -R build/* --manifest AndroidManifest.xml $(echo "$CLASSPATH" | tr -d '\n' | xargs -d':' -L1 -I{} echo " -I {} ") -o "$file" --auto-add-overlay
zip -uj "$file" classes.dex

zipalign -f 4 "$file" "$file.aligned"
mv -f "$file.aligned" "$file"
apksigner sign --ks-pass pass:pwd --ks javasrv.keystore "$file"

Edit2:这里是另一个可能与aapt2有关的问题。如果我在compileSdkVersion中指定AndroidManifest.xml,它将引发一个错误:

代码语言:javascript
复制
AndroidManifest.xml:2: error: attribute android:compileSdkVersion not found.
error: failed processing manifest.

我只是通过从清单中删除compileSdkVersion来忽略它。我现在不知道我是否应该..。

Edit3:与权限检查的logcat相关。我只能访问/data/log.txt。但这应该够了。不是吗?

代码语言:javascript
复制
08-16 19:24:39.236 18965 18965 E /system/bin/webview_zygote32: Failed to make and chown /acct/uid_99182: Permission denied
08-16 19:24:39.236 18965 18965 E Zygote  : createProcessGroup(99182, 0) failed: Permission denied
08-16 19:24:39.239  2219  2900 I am_proc_start: [0,18965,99182,com.android.chrome:sandboxed_process0,webview_service,com.javasrv/org.chromium.content.app.SandboxedProcessService0]
08-16 19:24:39.239  2219  2900 I ActivityManager: Start proc 18965:com.android.chrome:sandboxed_process0/u0i182 for webview_service com.javasrv/org.chromium.content.app.SandboxedProcessService0
08-16 19:24:39.255 18965 18965 W /system/bin/webview_zygote32: Unexpected CPU variant for X86 using defaults: x86_64
08-16 19:24:39.256 18931 18931 I auditd  : type=1400 audit(0.0:3392): avc: denied { read } for comm="com.javasrv" name="vmstat" dev="proc" ino=4026531858 scontext=u:r:untrusted_app_25:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=1
08-16 19:24:39.256 18931 18931 I com.javasrv: type=1400 audit(0.0:3392): avc: denied { read } for name="vmstat" dev="proc" ino=4026531858 scontext=u:r:untrusted_app_25:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=1
08-16 19:24:39.256 18931 18931 I auditd  : type=1400 audit(0.0:3393): avc: denied { open } for comm="com.javasrv" path="/proc/vmstat" dev="proc" ino=4026531858 scontext=u:r:untrusted_app_25:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=1
08-16 19:24:39.256 18931 18931 I com.javasrv: type=1400 audit(0.0:3393): avc: denied { open } for path="/proc/vmstat" dev="proc" ino=4026531858 scontext=u:r:untrusted_app_25:s0:c512,c768 tcontext=u:object_r:proc:s0 tclass=file permissive=1
08-16 19:24:39.263 18959 18959 W zygote  : Unexpected CPU variant for X86 using defaults: x86_64
08-16 19:24:39.281  1022  1022 I auditd  : type=1400 audit(0.0:3395): avc: denied { read } for comm="loop0" path="/mnt/android-8.1-r2/system.img" dev="vda2" ino=1422631 scontext=u:r:kernel:s0 tcontext=u:object_r:unlabeled:s0 tclass=file permissive=1
08-16 19:24:39.281  1022  1022 I loop0   : type=1400 audit(0.0:3395): avc: denied { read } for path="/mnt/android-8.1-r2/system.img" dev="vda2" ino=1422631 scontext=u:r:kernel:s0 tcontext=u:object_r:unlabeled:s0 tclass=file permissive=1
08-16 19:24:39.289  2671  2691 D SubscriptionController: [getPhoneId] asked for default subId=-1
08-16 19:24:39.290  2671  2691 D SubscriptionController: [getSubId]- invalid slotIndex=-1
08-16 19:24:39.336 18931 18931 D *** Loader::onCreate ***: PERMISSION_GRANTED
08-16 19:24:39.336 18931 18931 D *** getListFiles ***: [W]/sdcard/Download/FDroid.apk
08-16 19:24:39.336 18931 18931 D *** getListFiles ***: [W]/sdcard/Download/javasrv.apk

Edit4: --这是启动我请求权限的活动的方式:

代码语言:javascript
复制
Intent intent = new Intent(this, LoaderActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// If set in an Intent passed to Context.startActivity(), this flag will cause any existing task that would be associated with the activity to be cleared before the activity is started. That is, the activity becomes the new root of an otherwise empty task, and any old activities are finished. This can only be used in conjunction with FLAG_ACTIVITY_NEW_TASK.
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);

编辑5:神圣!我只是解压缩了得到的apk,并注意到我的android:versionCode和android:versionName分别变成了platformbuildversioncode和platformbuildversionname。这太疯狂了!我想知道这是怎么回事。补充道:啊哦。它与aapt2的版本有某种联系。我用的是构建工具28.0.3。把它改成26.0.2,它表现得没有那种疯狂。

编辑6:由于aapt2的错误,我回到了aapt。至少它不会把舱单搞得太乱:

代码语言:javascript
复制
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:minSdkVersion="23" android:targetSdkVersion="26" package="com.javasrv" platformBuildVersionCode="26" platformBuildVersionName="8.0.0">

但出于某种原因,它删除了我的应用程序自定义版本号和版本代码。但至少这不应该影响应用程序的工作。不过,我仍在苦苦挣扎的是,我无法指定compileSdkVersion,因为compileSdkVersion与compileSdkVersion包中没有找到的错误相同。

编辑7:好。下面是我从最终apk(我用aapt2 v26构建的)清单的头部分:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8" standalone="no"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" android:minSdkVersion="23" android:targetSdkVersion="26" package="com.javasrv">
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

所以,唯一缺少的就是compileSdkVersion。我仍然不知道如何使aapt2将该值放入清单中。但我测试了apk和具有运行时权限的bug仍然存在。很奇怪。

编辑8:安装了最新的aapt2版本。从这里开始:https://dl.google.com/dl/android/maven2/com/android/tools/build/aapt2/3.6.0-alpha11-5720371/aapt2-3.6.0-alpha11-5720371-linux.jar仍然是一样的-它不会插入compileSdkVersion。

编辑9:实际上很明显,在我使用的名称空间中没有compiledSdkVersion。我在文档中也找不到它:https://developer.android.com/guide/topics/manifest/uses-sdk-element --在我看来,我根本不应该使用它--实际上,我认为它没有任何用途。如果我只需要指定最低版本和目标版本,谁会关心我编译了我的应用程序的版本呢?所以窃听器应该在别的地方。

编辑10:升级到24.1.1版的安卓支持库。对运行时权限的检查仍然不顺利。

编辑11:试图调用requestPermissions,尽管它错误地检测到它是被授予的,并且得到了一个运行时错误:没有找到类android.support.v4.app.ActivityCompatApi23。有趣的是。嗯。显然,我应该使用与我的SDK相同版本的Android支持库。但我不清楚如何获得支持库的最新版本(请参阅Install latest android support library CLI ),所以是的。从24.1.1的aar中提取jar文件可能是个坏主意--显然它不是整个库,而是一个补丁。所以我决定使用JAR23.2.1,这是某个家伙编译的:https://github.com/pbakondy/cordova-plugin-android-support-v4-jar

编辑12:与v23.2.1Android支持库回到原处,我决定在用PERMISSION_GRANTED消息调用Log.d之后立即调用requestPermissions。这是输出:

代码语言:javascript
复制
08-17 12:50:15.132 28837 28837 D *** Loader::onCreate ***: PERMISSION_GRANTED
08-17 12:50:15.136 28837 28891 I com.javasrv: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
08-17 12:50:15.139  2219  2600 I ActivityManager: START u0 {act=android.content.pm.action.REQUEST_PERMISSIONS pkg=com.google.android.packageinstaller cmp=com.google.android.packageinstaller/com.android.packageinstaller.permission.ui.GrantPermissionsActivity (has extras)} from uid 10081
08-17 12:50:15.141  2219  2600 I wm_task_moved: [179,1,6]
08-17 12:50:15.142  2219  2600 I am_create_activity: [0,28890900,179,com.google.android.packageinstaller/com.android.packageinstaller.permission.ui.GrantPermissionsActivity,android.content.pm.action.REQUEST_PERMISSIONS,NULL,NULL,8388608]
08-17 12:50:15.147  2219  2600 I am_pause_activity: [0,43511476,com.javasrv/.LoaderActivity]
08-17 12:50:15.182  2446  2446 V StatusBar: setLightsOn(true)
08-17 12:50:15.183 28837 28837 I am_on_resume_called: [0,com.javasrv.LoaderActivity,LAUNCH_ACTIVITY]
08-17 12:50:15.254 28837 28873 W cr_media: Requires BLUETOOTH permission
08-17 12:50:15.273 28837 28837 I am_on_paused_called: [0,com.javasrv.LoaderActivity,handlePauseActivity]
08-17 12:50:15.284  2219  2259 I am_restart_activity: [0,28890900,179,com.google.android.packageinstaller/com.android.packageinstaller.permission.ui.GrantPermissionsActivity]
08-17 12:50:15.285  2219  2259 I am_set_resumed_activity: [0,com.google.android.packageinstaller/com.android.packageinstaller.permission.ui.GrantPermissionsActivity,minimalResumeActivityLocked]
08-17 12:50:15.291  2219  2298 I sysui_count: [window_time_0,3]
08-17 12:50:15.291  2219  2298 I sysui_multi_action: [757,803,799,window_time_0,802,3]
08-17 12:50:15.297  2446  2446 V StatusBar: setLightsOn(true)
08-17 12:50:15.304  2219  5022 I am_finish_activity: [0,28890900,179,com.google.android.packageinstaller/com.android.packageinstaller.permission.ui.GrantPermissionsActivity,app-request]
08-17 12:50:15.305  2219  5022 I am_pause_activity: [0,28890900,com.google.android.packageinstaller/com.android.packageinstaller.permission.ui.GrantPermissionsActivity]
08-17 12:50:15.308  2219  2298 I sysui_count: [window_time_0,0]
08-17 12:50:15.308  2219  2298 I sysui_multi_action: [757,803,799,window_time_0,802,0]
08-17 12:50:15.439  2219  2259 I am_set_resumed_activity: [0,com.javasrv/.LoaderActivity,resumeTopActivityInnerLocked]
08-17 12:50:15.446  2219  2259 I am_resume_activity: [0,43511476,179,com.javasrv/.LoaderActivity]
08-17 12:50:15.457  2219  2298 I sysui_count: [window_time_0,0]
08-17 12:50:15.457  2219  2298 I sysui_multi_action: [757,803,799,window_time_0,802,0]
08-17 12:50:15.557  2446  2446 I chatty  : uid=10030(com.android.systemui) identical 5 lines
08-17 12:50:15.594  2446  2446 V StatusBar: setLightsOn(true)

没有出现对话。看起来,这个系统让应用程序认为这个许可是被授予的。

我想知道为什么..。舱单肯定出了什么问题,但怎么了?

我将通过via分析器输出整个清单:

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:minSdkVersion="23"
    android:versionCode="6"
    android:versionName="1.0.0"
    android:targetSdkVersion="26"
    package="com.javasrv">

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

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

    <application
        android:label="@ref/0x7f060000"
        android:icon="@ref/0x7f020000">

        <activity
            android:theme="@ref/0x010300f0"
            android:label="@ref/0x7f060000"
            android:name="com.javasrv.MainActivity">

            <intent-filter>

                <action
                    android:name="android.intent.action.MAIN" />

                <category
                    android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:theme="@ref/0x010300f0"
            android:label="@ref/0x7f060000"
            android:name="com.javasrv.LoaderActivity">

            <intent-filter>

                <action
                    android:name="android.intent.action.MAIN" />

                <category
                    android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        <activity
            android:theme="@ref/0x01030011"
            android:label="@string/0xb"
            android:icon="@ref/0x7f010000"
            android:name="com.javasrv.TestActivity"
            android:screenOrientation="1">

            <intent-filter>

                <action
                    android:name="android.intent.action.MAIN" />

                <category
                    android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>

        <service
            android:name=".MyTestService" />

        <service
            android:name=".MyJobService"
            android:permission="android.permission.BIND_JOB_SERVICE" />

        <receiver
            android:name="Boot">

            <intent-filter
                android:priority="100">

                <action
                    android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
    </application>
</manifest>

有什么想法吗?

问题已经解决了,

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-09-14 04:13:17

哇。一直以来,问题都是与AndroidManifest.xml有关。我在错误的地方指定了minSdkVersion。我应该在uses sdk xml标记中这样做,而不是在清单标记中这样做,就像在Android网站上写的那样:https://developer.android.com/guide/topics/manifest/uses-sdk-element

我不知道我是从哪里得到这样一个想法的:这些属性应该写在清单标记中。也许这就是gradle所做的--它在编译apk时传递属性。

编辑:另外,在许可被授予之后,必须重新启动应用程序。否则,checkSelfPermission将通知进程已被授予,但应用程序将无法访问文件:Writing external storage doesn't work until I restart the application on Android M

票数 0
EN

Stack Overflow用户

发布于 2019-09-12 23:57:46

也许这能帮到你。

只要让你的应用程序升级,你就可以把compileSdkVersion和targetSdkVersion作为26。

票数 0
EN

Stack Overflow用户

发布于 2019-09-13 07:57:15

如果校验权限不起作用,则可以尝试对话框权限。

当应用程序从checkSelfPermission()接收到checkSelfPermission时,您需要提示用户该权限。Android提供了几种可以用来请求权限的方法,比如requestPermissions()。

代码语言:javascript
复制
  ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    1);

然后重写该方法。

代码语言:javascript
复制
  @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode) {
        case 1: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted

            } else {
                // permission denied

                Toast.makeText(BiggerScreen.this, "Permission denied to write your External storage", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        // other 'case' lines to check for other
        // permissions this app might request
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57915597

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档