2017-02-08 14 views
1

私は非常に新しいアンドロイド開発です。 私のアプリでは、リストビューで表示される連絡先クラスを持っています。私の連絡先はギャラリーから取得した画像があり、画像uriはデータベースに保存されています。私は私の最後のポストによるとSecurityException:Permission Denial 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 

:私の最後のPost

genymotionおよびAPI 19で私のアプリが正常に働いている間私の問題は、このpost

フォアによって固定されているが、突然、私はこのエラーを得たで いくつかのコードを追加しました。私のフラグメントコードは:

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

} 

} 

私はを追加しましたのファイルをマニフェストするが、私はまだエラーがある。連絡先情報を表示するリストビューがある。 私contactAdapter

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; 
} 
} 
+0

'Uri'が' contact.getImageSrc() 'で表されていても、コンテンツにアクセスする権利がなくなりました。 – CommonsWare

+0

私の連絡先Image SrcはString.Whatはこの問題を解決するために何ができますか?@CommonsWare –

答えて

2

あなたが他のアプリからUriを取得し、you have temporary rights to the content identified by that Uri

ACTION_OPEN_DOCUMENTで取得した場合は、takePersistableUriPermission()を使用してそのコンテンツに耐えられるようにすることができます。これにはすでにコードがあります。

ACTION_GET_CONTENTUriを取得した場合、コンテンツに長期間アクセスする手段はありません。すぐにコンテンツ(つまり、プロセスがまだ実行中の状態)で使用する必要があります。唯一の本当の選択肢は、あなたがコントロールするいくつかのファイルにコンテンツをコピーすることです。 ContentResolveropenInputStream()を経由してUriで示される内容のInputStreamを取得できます。標準のJava I/Oを使用してそのストリームから一部のファイルにコピーできます。その後、先に進むファイルを使用します。

+0

buddy、あなたは私へのリンクの例を教えてくれますか?どのように私はそれを行うことができます参照してください。 –

+0

@sayreskabir:https://github.com/commonsguy/cw-omnibus/tree/master/Documents/Durable – CommonsWare

関連する問題