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'を持つものは、少なくとも2つの問題があります。 – CommonsWare

+0

@CommonsWareありがとう、スタックトレース全体を表示するように更新しました。 –

答えて

2

まず、この:

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

両方の場所で同じアルゴリズムを使用します。

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

はこれを一致していません。したがって、2行目を次のように置き換えてください:

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

これは、あなたにNullPointerExceptionを渡します。

第二に、この:私はあなたが本当に欲しいものであるこれらのかわからないので、私は修正を提案することはできません

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

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

はこれを一致していません。

+1

ありがとう! 2番目の問題では、他のアプリが写真にアクセスできるようにするために、この方法で行うことを提案しているGoogleチュートリアルのコードをコピーしました。それは素晴らしいですが、私が作成しようとしているアプリにとって不可欠ではありません。ほとんどの場合、私はちょうどいずれかの方法で働いているアプリケーションの最初の反復を取得したいと思います。だから、私は外部のパスをアンドロイドシステムの実際の外部ディレクトリを指すようにする必要がありますか? –

+0

また、あなたが言及した最初の問題を修正し、新しいエラーを取得しました:java.lang.IllegalArgumentException:/storage/emulated/0/Pictures/jsnap_test.jpegを含む設定済みのルートを見つけることができませんでした。これはコードとファイル内のファイルの位置が一致していないと言っているように示唆していますが、私は外部パスに何を置くべきか正確にはわかりません。 –

+0

@AmrA:既存の 'File '、' 'は動作するはずです。 – CommonsWare

関連する問題