1

사진을 찍고 물건을 다루는 첫 번째 Android 앱을 작성하려고합니다.FileProvider.getUriForFile은 NullPointerException을 반환합니다.

나는 온라인으로 몇 가지 튜토리얼을보고 있지만, 버튼을 클릭 할 때마다 다음과 같은 NullPointerException이 무엇입니까 후 함께 몇 가지 코드를 넣어했습니다

10-03 14:48:00.284 26310-26310/org.broadinstitute.jsnap E/MainActivity: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference 
10-03 14:48:00.293 26310-26310/org.broadinstitute.jsnap E/MYAPP: exception 
                   java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference 
                    at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:583) 
                    at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:557) 
                    at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:399) 
                    at org.broadinstitute.jsnap.MainActivity.takePhoto(MainActivity.java:54) 
                    at org.broadinstitute.jsnap.MainActivity.access$000(MainActivity.java:24) 
                    at org.broadinstitute.jsnap.MainActivity$1.onClick(MainActivity.java:43) 
                    at android.view.View.performClick(View.java:6205) 
                    at android.widget.TextView.performClick(TextView.java:11103) 
                    at android.view.View$PerformClick.run(View.java:23653) 
                    at android.os.Handler.handleCallback(Handler.java:751) 
                    at android.os.Handler.dispatchMessage(Handler.java:95) 
                    at android.os.Looper.loop(Looper.java:154) 
                    at android.app.ActivityThread.main(ActivityThread.java:6682) 
                    at java.lang.reflect.Method.invoke(Native Method) 
                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520) 
                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410) 

내가 해결하는 방법을 아주 확실하지 않다.

매니페스트 :

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="org.broadinstitute.jsnap"> 

    <uses-permission android:name="android.permission.CAMERA" /> 
    <uses-feature android:name="android.hardware.camera" android:required="true"/> 
    <uses-feature android:name="android.hardware.camera.autofocus" /> 
    <uses-feature android:name="android.hardware.camera.flash" android:required="false"/> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:roundIcon="@mipmap/ic_launcher_round" 
     android:supportsRtl="true" 
     > 
     <activity android:name=".MainActivity"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <provider 
      android:name="android.support.v4.content.FileProvider" 
      android:authorities="${applicationId}.fileprovider" 
      android:exported="false" 
      android:grantUriPermissions="true"> 
      <meta-data 
       android:name="android.support.FILE_PROVIDER_PATHS" 
       android:resource="@xml/file_paths"></meta-data> 
     </provider> 
    </application> 

</manifest> 

file_paths.xml

<?xml version="1.0" encoding="utf-8"?> 
<paths xmlns:android="http://schemas.android.com/apk/res/android"> 
    <external-path name="jsnap_images" path="Android/data/org.broadinstitute.jsnap/files/Pictures" /> 
</paths> 

그리고 MainActivity : 어떤 도움을 주시면 더 좋구요

package org.broadinstitute.jsnap; 

import android.app.Activity; 
import android.content.ContentResolver; 
import android.content.Intent; 
import android.graphics.Bitmap; 
import android.net.Uri; 
import android.os.Build; 
import android.os.Environment; 
import android.provider.MediaStore; 
import android.support.v4.content.FileProvider; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.ImageView; 
import android.widget.Toast; 
import java.io.File; 
import java.io.IOException; 
import java.util.jar.Manifest; 


public class MainActivity extends Activity { 
    private static String logtag = "MainActivity"; 
    private static int TAKE_PICTURE = 1; 
    private static final String AUTHORITY = "org.broadinstitute.jsnap.provider"; 
    private static final String PHOTOS="photos"; 
    private static final String FILENAME="jsnap_test.jpeg"; 
    Uri imageURI; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Button cameraButton = (Button)(findViewById(R.id.cam_button)); 
     cameraButton.setOnClickListener(cameraListener); 

    } 
    private View.OnClickListener cameraListener = new View.OnClickListener() { 
     public void onClick(View v) { 
      try { 
       takePhoto(v); 
      } catch (Exception e) { 
       Log.e(logtag, e.toString()); 
      } 
     } 
    }; 
    private void takePhoto(View v){ 
     Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); 
     File photo = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), FILENAME); 
     imageURI=FileProvider.getUriForFile(this, AUTHORITY, photo); 
     intent.putExtra(MediaStore.EXTRA_OUTPUT, imageURI); 
     // TAKE_PICTURE is a request code saying we want to use the rear-facing camera. 
     startActivityForResult(intent, TAKE_PICTURE); 
    } 

    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) { 
     super.onActivityResult(requestCode, resultCode, intent); 

     if(resultCode == Activity.RESULT_OK) { 
      Uri selectedImage = imageURI; 
      getContentResolver().notifyChange(selectedImage, null); 

      ImageView imageView = (ImageView)findViewById(R.id.image_camera); 
      ContentResolver cr = getContentResolver(); 
      Bitmap bitmap; 

      try { 
       bitmap = MediaStore.Images.Media.getBitmap(cr, selectedImage); 
       imageView.setImageBitmap(bitmap); 
       Toast.makeText(MainActivity.this, selectedImage.toString(), Toast.LENGTH_SHORT).show(); 
      } catch(Exception e) { 
       Log.e(logtag, e.toString()); 
      } 
     } 
    } 
} 

여기 내 관련 코드입니다.

+0

질문을 편집하고 오류 메시지뿐 아니라 전체 Java 스택 추적을 게시하십시오. 'NullPointerException'의 원인이 무엇이든간에,'FileProvider'가 제공하는 메타 데이터에서 설정 한 내용의 일부가 아닌'File'을 갖는 것이 적어도 두 가지 문제가 있습니다. – CommonsWare

+0

@CommonsWare 감사합니다. 전체 스택 추적을 표시하도록 업데이트했습니다. –

답변

2

첫째,이 :

android:authorities="${applicationId}.fileprovider" 

이 일치하지 않습니다

private static final String AUTHORITY = "org.broadinstitute.jsnap.provider"; 

두 곳 모두에서 동일한 알고리즘을 사용합니다. NullPointerException 과거를 얻을 것이다

private static final String AUTHORITY = BuildConfig.APPLICATION_ID+".fileprovider"; 

: 그래서,와 두 번째 줄을 교체합니다.

둘째,이 :

File photo = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), FILENAME); 

이 일치하지 않는 : 당신이 정말 원하는 것입니다 그 어떤 알 수 없기 때문에

<external-path name="jsnap_images" path="Android/data/org.broadinstitute.jsnap/files/Pictures" /> 

, 내가 수정을 제안 할 수 없습니다.

+1

감사! 두 번째 문제는 Google 튜토리얼의 코드를 복사하여 다른 앱이 사진에 액세스 할 수있게하려는 경우 그렇게 할 것을 제안했습니다. 그게 좋겠지 만 내가 만들려고하는 앱에는 필수적이지는 않다. 주로 나는 어느 방향 으로든 작동하는 앱의 첫 번째 반복을 얻고 싶습니다. 그래서, 안드로이드 시스템에서 외부 경로가 실제 외부 디렉토리를 가리 키도록해야합니까? –

+0

또한 언급 한 첫 번째 문제가 수정되어 새로운 오류가 발생합니다. java.lang.IllegalArgumentException : /storage/emulated/0/Pictures/jsnap_test.jpeg가 포함 된 구성된 루트를 찾지 못했습니다. 이것은 당신이 코드와 XML에서 파일 위치가 일치하지 않는다고 말했듯이, 나는 외부 경로에 무엇을 넣어야하는지 정확히 모르겠다. ... –

+0

@AmrA : 기존의'File ','<외부 경로 이름 = "jsnap_images"경로 = "Pictures"/>'가 작동해야합니다. – CommonsWare