我的应用程序因拒绝许可而崩溃

问题描述 投票:0回答:2

我的Android应用程序存在问题。我要求用户访问READ_EXTERNAL_STORAGE的权限,但错误“权限拒绝”仍然使我的应用程序崩溃。

我已经花了几个小时,我不知道如何解决它。

这是我的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)

我的主要活动是:

    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);
    }

}

我的清单是:

    <?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>

我的朋友是:

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'


}

你知道它可能来自哪里吗?

非常感谢你的帮助。非常感谢。

java android android-permissions
2个回答
0
投票

运行时权限实际上在最近的时候已经采用了新的形状......就像你需要使用一个文件提供者,提供Uri和喜欢这样,但这里是一个很好的库,我最近使用过。它运作良好,无忧无虑。你可以在codepath上查看它。

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

干杯。


0
投票

来自Android Developer Documentation

如果您的应用需要危险权限,则每次执行需要该权限的操作时,都必须检查是否拥有该权限。从Android 6.0(API级别23)开始,用户可以随时撤消任何应用的权限,即使该应用针对较低的API级别也是如此。

所以你需要请求这样的许可

  @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.
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.