Android 6.0(Marshmallow)向用户显示拒绝权限和没有权限请求对话框

时间:2015-12-13 09:12:07

标签: java android xml permissions android-6.0-marshmallow

在阅读了Android文档后,我决定玩游戏并“从我的设备上读取短信。”

但是,在Manifest中设置权限,编写代码以在后面的代码中请求权限(java),并在RequestPermission()上设置断点后,我可以看到我的应用程序崩溃,因为“权限被拒绝。” / p>

当我宣布文档告诉我声明并且已经实现了那个让操作系统要求用户授予或拒绝许可的东西时,我为什么要获得权限被拒绝?甚至没有发生 - 它没有给我一个授予或拒绝权限的对话框 - 我的应用程序在它出现之前就崩溃了!)

我怎样才能弄清楚发生了什么?我如何要求用户获得[具体] READ_SMS权限的许可?

请注意,在尝试修复时,我一直在抨击桌面,所以这里的代码是我的最新代码,但是已经有大约20个(完整的) -writes。因此,如果缺少某些东西,它可能已经存在但被删除,因为它不起作用,或者被删除以便进行故障排除以查看哪些不起作用。

清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.me.app">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_SMS" />
        <uses-permission android:name="android.permission.RECEIVE_SMS" />
        <uses-feature
            android:name="android.hardware.telephony"
            android:required="true">
        </uses-feature>
        <grant-uri-permission android:path="content://sms/"
            android:pathPattern=".*"
            android:pathPrefix="\"/>
        <activity
            android:name=".Main"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

Main.java(onCreate(...)):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Testing Snackbar", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
            this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    RequestPermission(this);
}

Main.java(权限方法):

private static final int MY_PERMISSIONS_REQUEST_READ_SMS = 226;

protected void RequestPermission(Activity activity)
{
    if(ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED)
    {
        if(ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.READ_SMS)) {
            return;
        }
        else
        {
            ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.READ_SMS
            }, MY_PERMISSIONS_REQUEST_READ_SMS);
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)
{
    switch(requestCode)
    {
        case MY_PERMISSIONS_REQUEST_READ_SMS:
        {
            if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                MessageAdapter messageAdapter = new MessageAdapter(GetMessages());
                RecyclerView recList = (RecyclerView) findViewById(R.id.messagesList);
                recList.setAdapter(messageAdapter);

                // CardView List
                LinearLayoutManager llm = new LinearLayoutManager(this.getApplicationContext());
                llm.setOrientation(LinearLayoutManager.VERTICAL);
                recList.setLayoutManager(llm);
            }
            else
            {
                return;
            }

            return;
        }
    }
}

2 个答案:

答案 0 :(得分:2)

你应该解决的一个问题是:

if(ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.READ_SMS)) {
            return;
        }

这里你只是回来了,而实际上你应该显示rationalle为什么你需要这个权限然后请求它。通常的方法是使用Snackbar或对话框,或者只是立即调用ActivityCompat.requestPermissions( - 至少是为了测试目的。

[编辑]

  Snackbar.make(activity, R.string.rationaleStringId, Snackbar.LENGTH_INDEFINITE)
          .setAction(android.R.string.ok, new View.OnClickListener() {
            @Override
            @TargetApi(Build.VERSION_CODES.M)
            public void onClick(View v) {
                 ActivityCompat.requestPermissions(activity, new String[] {Manifest.permission.READ_SMS}, MY_PERMISSIONS_REQUEST_READ_SMS);
            }
          }).show();

答案 1 :(得分:1)

您的<uses-permission>元素位于错误的位置,<uses-feature>元素也是如此。它们位于<application>元素之外,作为根<manifest>元素的直接子元素。

此外,删除<grant-uri-permission>元素。它不仅位于正确的位置,而且没有一个正确的位置,因为它只是<provider>元素的子元素。