2013-12-17 2 views
14

나는 9 패치 이미지 배경을 가진 위젯을 가지고 있습니다. 이미지가/sdcard/mydir/bgs에 저장되었습니다.안드로이드 - 컨텐츠를 열 수 없습니다 : file : /// storage/emulated/0

Unable to open content: file:///storage/emulated/0/sdcard/mydir/bgs 

..

다음

...

open failed: EACCES (Permission denied) 

이 : 나는 setImageViewUri 방법과 이미지를로드 할 때

,이 오류가 발생했습니다 홈 화면에만 표시되며 Nexus 10 및 Nexus 7에서만 표시됩니다 (최신 런처 4.4이 버그가 없음). 있다). 내 응용 프로그램에서 일부 RemoteViews도 있고 모든 제대로 작동합니다.

는 또한 매니페스트 중 하나 READ_EXTERNAL_STORAGE, 하나 WRITE_EXTERNAL_STORAGE에 추가했습니다.

어떻게 해결할 수 있습니까?

업데이트 :이 방법 setImageViewUri을 검사했습니다 나는 내 파일의 경로를 변경하는 것으로 나타났습니다.

if (value != null) { 
      // Resolve any filesystem path before sending remotely 
      value = value.getCanonicalUri(); 
      if (StrictMode.vmFileUriExposureEnabled()) { 
       value.checkFileUriExposed("RemoteViews.setUri()"); 
      } 
     } 

이 방법

내 값 (/ SDCARD/MYDIR/BGS) 내로 변경을 수신 (스토리지// 0/SDCARD/MYDIR/BGS 에뮬레이트). 그러나이 파일은 adb를 통해 시스템에 존재하지 않습니다.

+0

공유 코드를 저장을 가능하게하고 또한 전체 로그 캣 출력을 게시합니다. –

답변

6

setImageViewUri 파일과 함께 사용이 더 이상 안전하지 않을 나타납니다.

왜?

젤리 빈은 READ_EXTERNAL_STORAGE 권한을 소개했다. 외부 저장소에서 읽으려는 앱은이 권한을 보유해야합니다. 이것은 기본적으로 KitKat 때까지 적용되지 않았습니다.

시작 프로그램에이 권한이 없습니다. 사실 사용자가 첨부 한 모든 RemoteView가 해당 권한을 보유한다는 보장은 없습니다. 이렇게하면 원격 이미지보기가 지정된 URI를 읽을 수 있는지 여부를 모르기 때문에 setImageViewUri를 사용하는 것이 안전하지 않습니다.

지금 무엇?

옵션 1 : setImageViewBitmap.

당신으로 인해 실패 바인더 거래에 떨어진이 옵션에서 이동했을 수 있습니다

. 그 트릭은 이미지가 1MB 미만인지 확인하는 것입니다. 이것은 소리가 나는 것처럼 어렵지 않습니다. 이미지가 얼마나 커질 지 정확히 계산할 수 있습니다. 예를 들어 ARGB_8888 이미지를 사용하는 경우 픽셀 당 4 바이트가 필요합니다.물론

1 Mb = 1048576 bytes = 262144 pixels = 512 x 512 image

당신이 픽셀을 2 배 얻을 RGB_565를 사용에서 더 많은 것을 만들 수 있겠 어 : 우리가 최대 크기를 calulate 수 있습니다.

위젯이 작 으면 큰 이미지가 필요하지 않을 수도 있습니다. 귀하의 appwidget는 다음하여 특정 옵션에 대해 질문 할 수 있습니다

Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetIds[i]); 

int minWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH); 
int minHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT); 

int maxWidth = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH); 
int maxHeight = options.getInt(AppWidgetManager.OPTION_APPWIDGET_MAX_HEIGHT); 

그냥 당신이 당신의 비트 맵을 확장 변환해야합니다 때문에 반환 값은 픽셀 딥에없는 것을 유의하십시오.

옵션 2 : 어떤 이유로 여전히 IPC 제한을 좋아하지 않는 경우에 당신은 항상 사용자 지정 콘텐츠 공급자를 구축 할 수 있습니다, 콘텐츠 제공자에게

를 사용합니다. 그 uri를 setImageViewUri에 전달하면 좋을 것입니다.

경로 전환은 어떻게됩니까?

경로 전환은 실제 문제가 아닙니다. 그것은 문제가있는 것처럼 보이지만 에뮬레이션은 실제로 정상적으로 작동합니다. //storage/emulated/0/sdcard/mydir/bgs 안에 파일을 만들어보세요. 파일이 잘 만들어집니다.

예외가 FileNotFoundException이지만 메시지가 Permission Denied 인 것을 알 수 있습니다.

10

당신은 매니페스트에

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> 

이 필요합니다.

+1

추가했습니다. READ 및 WRITE 권한. – CeccoCQ

0

SD 카드 경로를 수동으로 입력한다고 생각합니다. 대신 수동으로 입력 SD 카드 경로의이 같은 저장 경로를 얻어야한다 : // URI를 :

File extStore = Environment.getExternalStorageDirectory(); 
String mPath = extStore.getAbsolutePath() + "/mydir/bgs"; 
+0

최근 편집을 확인하십시오. 감사. – CeccoCQ

14

Google은 Lollipop에서와 같이 앱에 사용자가 기기에서 사용할 권한을 명시 적으로 부여하고 앱을 거부하려는 권한을 명시 적으로 부여하는 새로운 방법을 도입했습니다. 당신이 통지하는 경우, 당신의 안드로이드 모니터, 로그는

java.io.FileNotFoundException: /storage/emulated/0/advert.mp4: open failed: EACCES (Permission denied) 

EACCESS permission denied는 자바의 악명 높은 FileNotFoundException의 원인이다.

은 당신의 앱 권한을 고토,이 문제를 해결하고 앱

enter image description here

+0

기본적으로 모든 권한은 해제됩니다. 사용자는 앱을 설치할 때마다 모든 것을 활성화해야합니까? 나는 내 전화 (버전 6.0.1)에서 그것을 한 적이 없어 ... – Matt

+0

릴리스 된 응용 프로그램에서이 작업을 수행하지 마십시오. 귀하의 사용자는 당신에게 감사하지 않을 것입니다. 대신 런타임에 앱 내에서 권한을 요청해야합니다. https://developer.android.com/training/permissions/requesting.html – Kuffs