简体   繁体   English

我的应用因拒绝权限而崩溃

[英]My App Crashes because of permission denial

I have an issue with my Android App. 我的Android应用存在问题。 I am asking for permissions to the user to access the READ_EXTERNAL_STORAGE but the bug "permission denial" still makes my app crash. 我正在请求用户访问READ_EXTERNAL_STORAGE的权限,但“拒绝权限”错误仍然使我的应用程序崩溃。

I have spent hours on it and I have no clue how to fix it. 我已经花了几个小时,却不知道如何解决它。

Here's my logcat: 这是我的日志:

 03-07 15:02:12.387 6800-8893/? E/DatabaseUtils: Writing exception to parcel
    java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=8108, uid=10089 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
        at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:605)
        at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:480)
        at android.content.ContentProvider$Transport.query(ContentProvider.java:211)
        at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:112)
        at android.os.Binder.execTransact(Binder.java:453)
03-07 15:02:12.391 8108-11729/? E/iu.UploadsManager: Insufficient permissions to process media
    java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=8108, uid=10089 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
        at android.os.Parcel.readException(Parcel.java:1602)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:183)
        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:135)
        at android.content.ContentProviderProxy.query(ContentProviderNative.java:421)
        at android.content.ContentResolver.query(ContentResolver.java:502)
        at android.content.ContentResolver.query(ContentResolver.java:438)
        at lqt.a(PG:14)
        at com.google.android.libraries.social.autobackup.FingerprintScannerIntentService.onHandleIntent(PG:15)
        at android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:66)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:150)
        at android.os.HandlerThread.run(HandlerThread.java:61)

My Main activity is: 我的主要活动是:

    package com.example.arjufy;


import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.Manifest;
import android.support.v4.app.ActivityCompat;
import android.widget.Toast;

import android.content.Intent;
import android.support.v4.app.Fragment;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;



public class MainActivity extends AppCompatActivity implements MarketPlaceFragment.OnListFragmentInteractionListener {

    private FirebaseAuth mFirebaseAuth;
    private FirebaseUser mFirebaseUser;
    private DatabaseReference mDatabaseReference;
    private String mUsername;
    private String mPhotoUrl;
    public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 123;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (checkPermissionREAD_EXTERNAL_STORAGE(this)) {
            // do your stuff..

            // Initialize Firebase Auth
            mFirebaseAuth = FirebaseAuth.getInstance();
            mFirebaseUser = mFirebaseAuth.getCurrentUser();
            if (mFirebaseUser == null) {
                // Not signed in, launch the Sign In activity
                startActivity(new Intent(this, SplashScreenActivity.class));
                finish();
                return;
            } else {
                mUsername = mFirebaseUser.getEmail();
            }
            mDatabaseReference = FirebaseDatabase.getInstance().getReference();
            setContentView(R.layout.activity_main);
                Fragment fragment = new MarketPlaceFragment();
            getSupportFragmentManager().beginTransaction().replace(R.id.theFragmentFrame, fragment).addToBackStack("MarketPlaceFragment").commit();
        }
        }
    public boolean checkPermissionREAD_EXTERNAL_STORAGE(
            final Context context) {
        int currentAPIVersion = Build.VERSION.SDK_INT;
        if (currentAPIVersion >= android.os.Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(context,
                    Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(
                        (Activity) context,
                        Manifest.permission.READ_EXTERNAL_STORAGE)) {
                    showDialog("External storage", context,
                            Manifest.permission.READ_EXTERNAL_STORAGE);

                } else {
                    ActivityCompat
                            .requestPermissions(
                                    (Activity) context,
                                    new String[] { Manifest.permission.READ_EXTERNAL_STORAGE },
                                    MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
                }
                return false;
            } else {
                return true;
            }

        } else {
            return true;
        }
    }
    public void showDialog(final String msg, final Context context,
                           final String permission) {
        AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
        alertBuilder.setCancelable(true);
        alertBuilder.setTitle("Permission necessary");
        alertBuilder.setMessage(msg + " permission is necessary");
        alertBuilder.setPositiveButton(android.R.string.yes,
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions((Activity) context,
                                new String[] { permission },
                                MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);
                    }
                });
        AlertDialog alert = alertBuilder.create();
        alert.show();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // do your stuff
                } else {
                    Toast.makeText(MainActivity.this, "GET_ACCOUNTS Denied",
                            Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions,
                        grantResults);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        switch (id) {
            case R.id.logoff:
                FirebaseAuth.getInstance().signOut();
                Intent intent1 = new Intent(this, LoginActivity.class);
                startActivity(intent1);
                return true;
            case R.id.profile:
                Intent intent2 = new Intent(this, MyProfileActivity.class);
                startActivity(intent2);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onListFragmentInteraction(DatabaseReference reference) {
        Intent intent = new Intent(this, ProductDetailViewActivity.class);
        intent.putExtra("Product reference", reference.toString());
        startActivity(intent);
    }

}

My manifest is: 我的清单是:

    <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.arjufy">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-feature
        android:name="android.hardware.camera"
        android:required="true" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>


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

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

eenActivity" />
        <activity android:name=".AddProductActivity" />
        <activity android:name=".SignUpActivity" />
        <activity android:name=".MyProfileActivity" />


        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.example.arjufy"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/path_files" />

        </provider>

        <activity android:name=".ProductDetailViewActivity" />

    </application>

</manifest>

and my gradle is: 我的收获是:

apply plugin: 'com.android.application'
apply plugin: 'com.google.gms.google-services'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.arjufy"
        minSdkVersion 23
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.google.firebase:firebase-auth:16.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.android.support:support-v4:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.android.support:design:28.0.0'
    implementation 'com.google.android.gms:play-services-auth:16.0.1'
    implementation 'com.google.firebase:firebase-storage:16.1.0'
    implementation 'com.google.firebase:firebase-database:16.1.0'
    implementation 'com.firebaseui:firebase-ui:0.5.3'
    implementation 'me.relex:circleindicator:2.1.0@aar'
    implementation 'com.getbase:floatingactionbutton:1.10.1'
    implementation 'de.hdodenhof:circleimageview:2.2.0'
    implementation 'com.squareup.picasso:picasso:2.71828'
    implementation 'com.google.firebase:firebase-core:16.0.7'


}

Do you have any idea where it might come from? 您是否知道它可能来自哪里?

Thanks a lot for your help. 非常感谢你的帮助。 Very much appreciated. 非常感谢。

Runtime permission has actually taken a new shape in the recent times ... like you need to use a fileprovider, provide Uri and the likes but here is a good library that i have used in the recent times. 最近,运行时权限实际上已经有了新的变化……就像您需要使用fileprovider,提供Uri之类的东西一样,但这是我最近使用的一个很好的库。 It works well and hassle free. 它运作良好且无忧。 You can check it out on codepath. 您可以在codepath上签出。

https://guides.codepath.com/android/Managing-Runtime-Permissions-with-PermissionsDispatcher https://guides.codepath.com/android/Managing-Runtime-Permissions-with-PermissionsDispatcher

Cheers. 干杯。

From Android Developer Documentation 来自Android开发人员文档

If your app needs a dangerous permission, you must check whether you have that permission every time you perform an operation that requires that permission. 如果您的应用需要危险的权限,则每次执行需要该权限的操作时,都必须检查您是否具有该权限。 Beginning with Android 6.0 (API level 23), users can revoke permissions from any app at any time, even if the app targets a lower API level. 从Android 6.0(API级别23)开始,用户可以随时撤消任何应用程序的权限,即使该应用程序定位于较低的API级别也是如此。

So you need to request permission like this 因此,您需要像这样请求权限

  @TargetApi(23)
public void enableRunTimePermisstion() {

    if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) &&
            (getActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) !=
                    PackageManager.PERMISSION_GRANTED))
        if (getActivity().shouldShowRequestPermissionRationale
                (Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            Toast.makeText(getActivity(), "Write storage permission is need for app"
                    , Toast.LENGTH_LONG).show();
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);

        } else {
            requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            Toast.makeText(getActivity(), "request permission"
                    , Toast.LENGTH_LONG).show();
        }


}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 1) {
        if (permissions[0].equals(Manifest.permission.WRITE_EXTERNAL_STORAGE) &&
                grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            Toast.makeText(context, "Write external storage granted", Toast.LENGTH_LONG).show();
            // >> here you call the method that need the permission
        }
    } else {
        Toast.makeText(getActivity(), "Write external permission denied", Toast.LENGTH_SHORT).show();
        enableRunTimePermisstion(); // >> When user request the permission we calling the previous method again.
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM