android - 安全异常 : Permission Denial API 19

标签 android listview android-gallery

我是 android 开发的新手。 在我的应用程序中,我有一个显示在 ListView 中的联系人类。对于我的联系人,我有一张从图库中获得的图像,图像 uri 存储在数据库中。 在我最后Post

我的问题由此 post 得到解决

虽然我的应用程序在 genymotion 和 api 19 中正常工作,但突然出现此错误:

FATAL EXCEPTION: main
                                                                             Process: com.example.sayres.myapplication7, PID: 3865
                                                                             java.lang.SecurityException: Permission Denial: opening provider com.android.providers.media.MediaDocumentsProvider from ProcessRecord{5296e638 3865:com.example.sayres.myapplication7/u0a98} (pid=3865, uid=10098) requires android.permission.MANAGE_DOCUMENTS or android.permission.MANAGE_DOCUMENTS
                                                                                 at android.os.Parcel.readException(Parcel.java:1465)
                                                                                 at android.os.Parcel.readException(Parcel.java:1419)
                                                                                 at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2848)
                                                                                 at android.app.ActivityThread.acquireProvider(ActivityThread.java:4399)
                                                                                 at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2208)
                                                                                 at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1425)
                                                                                 at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1047)
                                                                                 at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:904)
                                                                                 at android.content.ContentResolver.openInputStream(ContentResolver.java:629)
                                                                                 at android.provider.MediaStore$Images$Media.getBitmap(MediaStore.java:803)
                                                                                 at com.example.sayres.myapplication7.mvp.view.adapter.ContactAdapter.getView(ContactAdapter.java:54)
                                                                                 at android.widget.AbsListView.obtainView(AbsListView.java:2255)
                                                                                 at android.widget.ListView.makeAndAddView(ListView.java:1790)
                                                                                 at android.widget.ListView.fillDown(ListView.java:691)
                                                                                 at android.widget.ListView.fillFromTop(ListView.java:752)
                                                                                 at android.widget.ListView.layoutChildren(ListView.java:1616)
                                                                                 at android.widget.AbsListView.onLayout(AbsListView.java:2087)
                                                                                 at android.view.View.layout(View.java:14817)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:4631)
                                                                                 at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:122)
                                                                                 at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
                                                                                 at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1170)
                                                                                 at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:814)
                                                                                 at android.view.View.layout(View.java:14817)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:4631)
                                                                                 at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
                                                                                 at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
                                                                                 at android.view.View.layout(View.java:14817)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:4631)
                                                                                 at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
                                                                                 at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
                                                                                 at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
                                                                                 at android.view.View.layout(View.java:14817)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:4631)
                                                                                 at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
                                                                                 at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
                                                                                 at android.view.View.layout(View.java:14817)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:4631)
                                                                                 at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1671)
                                                                                 at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1525)
                                                                                 at android.widget.LinearLayout.onLayout(LinearLayout.java:1434)
                                                                                 at android.view.View.layout(View.java:14817)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:4631)
                                                                                 at android.widget.FrameLayout.layoutChildren(FrameLayout.java:453)
                                                                                 at android.widget.FrameLayout.onLayout(FrameLayout.java:388)
                                                                                 at android.view.View.layout(View.java:14817)
                                                                                 at android.view.ViewGroup.layout(ViewGroup.java:4631)
                                                                                 at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:1983)
                                                                                 at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1740)
                                                                                 at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:996)
                                                                                 at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5600)
                                                                                 at android.view.Choreographer$CallbackRecord.run(Choreographer.java:761)
                                                                                 at android.view.Choreographer.doCallbacks(Choreographer.java:574)
                                                                                 at android.view.Choreographer.doFrame(Choreographer.java:544)
                                                                                at android.view.Choreograph

根据我上一篇文章,我添加了一些代码,我的 fragment 代码是:

package com.example.sayres.myapplication7.mvp.view.profile;


import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import com.example.sayres.myapplication7.App;
import com.example.sayres.myapplication7.R;
import com.example.sayres.myapplication7.entity.Contact;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import de.hdodenhof.circleimageview.CircleImageView;
public class EditProfileFragment extends Fragment {

private static final int GALLERY_KITKAT_INTENT_CALLED = 1;
private EditFragmentCallBack editFragmentCallBack;
private EditText fragmentEditEditTextName;
private EditText fragmentEditEditTextFamily;
private EditText fragmentEditEditTextPhoneNumber;
private static final int SELECT_FILE = 0;
public static final String TAG = "====>";
private AlertDialog.Builder builder;
private Uri selectedImageUri;
private CircleImageView fragmentEditPicture;
private Bitmap bm;
private Button fragmentEditBtUpdate;
private int id;
private int rowUpdate;
private String name;
private String family;
private String phoneNumber;
private Contact contact;


public EditProfileFragment() {
    // Required empty public constructor
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    Log.d(TAG, "onAttach: is running");

    editFragmentCallBack = (EditFragmentCallBack) context;
    Log.d(TAG, "onAttach: editFragmentCallBack was initialized");
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    Log.d(TAG, "onCreateView- EditFragment: is running");
    View fragmentView = inflater.inflate(R.layout.fragment_edit_profile, container, false);
    initFragment(fragmentView);
    return fragmentView;
}


private void initFragment(View parent) {

    /**
     * referencing of  fragment_edit_profile
     */
    fragmentEditPicture = (CircleImageView) parent.findViewById(R.id.fragment_edit_picture);
    fragmentEditEditTextName = (EditText) parent.findViewById(R.id.fragment_edit_editText_name);
    fragmentEditEditTextFamily = (EditText) parent.findViewById(R.id.fragment_edit_editText_family);
    fragmentEditEditTextPhoneNumber = (EditText) parent.findViewById(R.id.fragment_edit_editText_phone);
    fragmentEditBtUpdate = (Button) parent.findViewById(R.id.fragment_edit_btn_save);


    fragmentEditBtUpdate.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            Log.d(TAG, "onClick: yess");
            id = contact.get_id();
            name = fragmentEditEditTextName.getText().toString();
            family = fragmentEditEditTextFamily.getText().toString();
            phoneNumber = fragmentEditEditTextPhoneNumber.getText().toString();

            Log.d(TAG, "onClick: name " + name);
            Log.d(TAG, "onClick: family " + family);


            contact = new Contact(id, name, family, phoneNumber, selectedImageUri.toString());
            rowUpdate = App.getInstanceImplementation().updateContact(contact);

            Log.i("==>", "btnUpdateContact: " + rowUpdate);

        }
    });
    /**
     * get contact by invoke from CallBack on ProfileActivity
     */
    contact = editFragmentCallBack.getContact();

    fragmentEditEditTextName.setText(contact.getName());
    fragmentEditEditTextFamily.setText(contact.getFamily());
    fragmentEditEditTextPhoneNumber.setText(contact.getPhonNumber());


}

public void selectImage() {
    final CharSequence[] items = {"Choose from Library", "Cancel"};
    builder = new AlertDialog.Builder(getActivity());

    builder.setTitle("Add Photo ");
    builder.setItems(items, new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int item) {
            if (items[item].equals("Choose from Library")) {

                if (Build.VERSION.SDK_INT <19) {
                    Log.d(TAG, "Build.VERSION.SDK_INT <19");

                    Intent intent = new Intent();
                    intent.setType("image/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);

                    startActivityForResult(Intent.createChooser(intent, "Select File"), SELECT_FILE);

                }else {


                    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
//                        Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                    intent.addCategory(Intent.CATEGORY_OPENABLE);
                    intent.setType("image/*");
                    startActivityForResult(intent, GALLERY_KITKAT_INTENT_CALLED);
                }
            } else if (items[item].equals("Cancel")) {

            }
        }
    });
    builder.show();

}


@SuppressLint("NewApi")
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == Activity.RESULT_OK) {
        if (requestCode == SELECT_FILE) {
            onSelectFromGalleryResult(data);

        } else if (requestCode == GALLERY_KITKAT_INTENT_CALLED) {
            selectedImageUri = data.getData();
            final int takeFlags = data.getFlags()
                    & (Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            getActivity().getContentResolver().takePersistableUriPermission(selectedImageUri, takeFlags);

            bm = null;

            try {
                selectedImageUri = data.getData();

                bm = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), data.getData());
            } catch (IOException e) {
                e.printStackTrace();
            }

            Log.d(TAG, "selectedImageUri " + selectedImageUri);
            fragmentEditPicture.setImageBitmap(bm);
        }


    }
}


public void onSelectFromGalleryResult(Intent data) {
    if (data != null) {
        bm = null;

        try {
            selectedImageUri = data.getData();

            bm = MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(), data.getData());
        } catch (IOException e) {
            e.printStackTrace();
        }

        Log.d(TAG, "selectedImageUri " + selectedImageUri);
        fragmentEditPicture.setImageBitmap(bm);
    }

}


public interface EditFragmentCallBack {
    Contact getContact();

    void finishProfile();

}

}

我将 uses-permission android:name="android.permission.MANAGE_DOCUMENTS" 添加到 list 文件,但我仍然遇到错误。我有一个显示联系信息的 ListView 。 我的联系人适配器

package com.example.sayres.myapplication7.mvp.view.adapter;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.sayres.myapplication7.R;
import com.example.sayres.myapplication7.entity.Contact;

import java.io.IOException;
import java.util.List;


public class ContactAdapter extends ArrayAdapter<Contact> {
private Bitmap bm;
private Context context;
private List<Contact> contacts;

public ContactAdapter(Context context, List<Contact> contacts) {
    super(context, 0, contacts);
    this.context = context;
    this.contacts = contacts;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View rootView = View.inflate(getContext(), R.layout.item_contact_list, null);

    /**
     * get reference from item_contact_list Layout
     */
    ImageView imageViewAvatar = (ImageView) rootView.findViewById(R.id.imageView_avatar);
    TextView textViewName = (TextView) rootView.findViewById(R.id.textView_name);
    TextView textViewFamily = (TextView) rootView.findViewById(R.id.textView_family);

    Contact contact = contacts.get(position);

    if (contact.getImageSrc() =="") {
        Log.d("===>", "getImageSrc() == null");
        imageViewAvatar.setImageResource(R.mipmap.ic_launcher);
    } else {

        try {
            bm = MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.parse(contact.getImageSrc()));
            imageViewAvatar.setImageBitmap(bm);

        } catch (IOException e) {
            e.printStackTrace();
        }



    }
    Log.d("===>", "getView from DB: " + Uri.parse(contact.getImageSrc()));
    Log.d("===>", "getView: " + contact.getImageSrc());
    textViewName.setText(contact.getName());
    textViewFamily.setText(contact.getFamily());

    return rootView;

}

此错误针对此行:bm = MediaStore.Images.Media.getBitmap(context.getContentResolver(), Uri.parse(contact.getImageSrc()));

错误是什么?我该如何解决?

编辑:

这是我的联系人类:

package com.example.sayres.myapplication7.entity;

import java.io.Serializable;

public class Contact implements Serializable{
private int _id;
private String name, lastName, phoneNumber,imageSrc;

public Contact(int _id, String name, String family, String phoneNumber, String imageSrc) {
    this._id = _id;
    this.name = name;
    this.lastName = family;
    this.phoneNumber = phoneNumber;
    this.imageSrc = imageSrc;
}

public int get_id() {
    return _id;
}

public Contact set_id(int _id) {
    this._id = _id;
    return this;
}

public String getName() {
    return name;
}

public Contact setName(String name) {
    this.name = name;
    return this;
}

public String getFamily() {
    return lastName;
}

public Contact setFamily(String lastName) {
    this.lastName = lastName;
    return this;
}

public String getPhonNumber() {
    return phoneNumber;
}

public Contact setPhonNumber(String phonNumber) {
    this.phoneNumber = phonNumber;
    return this;
}

public String getImageSrc() {
    return imageSrc;
}

public Contact setImageSrc(String imageSrc) {
    this.imageSrc = imageSrc;
    return this;
}
}

最佳答案

当您从另一个应用程序获取 Uri 时,you have temporary rights to the content identified by that Uri .

如果您通过 ACTION_OPEN_DOCUMENT 获得了 Uri,您可以尝试使用 takePersistableUriPermission() 来获得对该内容的持久访问。您已经有了这方面的代码。

但是,如果您通过 ACTION_GET_CONTENT 获得了 Uri,则无法获得对内容的长期访问权。您必须立即使用内容(即,当您的进程仍在运行时)。您唯一真正的选择是将内容复制到您控制的某个文件中。您可以通过 ContentResolveropenInputStream() 获取由 Uri 标识的内容的 InputStream,并且您然后可以使用标准 Java I/O 从该流复制到某个文件。然后,继续使用该文件。

关于android - 安全异常 : Permission Denial API 19,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42125303/

相关文章:

android - 更改图库所选项目的外观

android - 在项目 'app' 中,已解决的 Google Play 服务库依赖项依赖于另一个

android - 使用设备存储中的图像填充 ListView 中的 ImageView

wpf - 谁将 listviewcolumn 标题绑定(bind)到 WPF 中的列单元格

android - 在 Android 的 View Flipper 上触摸滚动?

Android图库幻灯片动画

android - 自动从 DropBox 复制移动应用构建并安装到设备

android - 无法获得在 Galaxy Nexus 上运行的开放式配件开发工具包

c# - 使用 IP 地址连接到 SQL Server 的多个连接

ios - 如何使用 React Native iOS 将 ListView 放入 ScrollView 中?