2017-02-08 3 views
1

나는 아주 안드로이드 개발하고 있습니다. 내 애플 리케이션에서 나는 목록보기에 표시되는 연락처 클래스가 있습니다. 내 연락처는 갤러리에서 가져온 이미지가 있고 이미지 uri는 데이터베이스에 저장되어 있습니다. 이 postSecurityException : 허가 거부 API 19

전면에 의해 고정 마지막 Post

내 문제에 는 genymotion 및 API (19)의 내 응용 프로그램이 제대로 작동 중에 갑자기이 오류가있어 내 마지막 게시물의 I에 따라

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 

을 몇 가지 코드를 추가했으며 코드 조각 코드는 다음과 같습니다.

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_CONTENT을 통해 Uri을 얻은 경우 콘텐츠에 장기간 액세스 할 수있는 방법이 없습니다. 즉시 (즉, 프로세스가 실행 중일 때)의 콘텐츠를 사용해야합니다. 유일한 옵션은 사용자가 제어하는 ​​일부 파일에 내용을 복사하는 것입니다. Uri으로 식별되는 내용에 을 ContentResolveropenInputStream()으로 가져올 수 있습니다. 그러면 표준 Java I/O를 사용하여 해당 스트림에서 일부 파일로 복사 할 수 있습니다. 그런 다음 앞으로 사용할 파일을 사용하십시오.

+0

친구, 내게 예제 링크를 줄 수 있습니까? 어떻게 할 수 있는지 보도록하겠습니다. –

+0

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

관련 문제