J'essaie d'écrire ma première Android, qui impliquera de prendre une photo et de faire des choses avec.
J'ai rassemblé du code après avoir consulté plusieurs didacticiels en ligne, mais j'obtiens l'exception NullPointerException suivante chaque fois que le bouton est cliqué:
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)
Je ne sais pas trop comment résoudre. Voici mon code pertinent:
manifeste:
<?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>
Et 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());
}
}
}
}
Toute aide est grandement appréciée.
Tout d'abord, ceci:
Android:authorities="${applicationId}.fileprovider"
ne correspond pas à ceci:
private static final String AUTHORITY = "org.broadinstitute.jsnap.provider";
Utilisez le même algorithme aux deux endroits. Remplacez donc la deuxième ligne par:
private static final String AUTHORITY = BuildConfig.APPLICATION_ID+".fileprovider";
Cela vous permettra de dépasser le NullPointerException
.
Deuxièmement, ceci:
File photo = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), FILENAME);
ne correspond pas à ceci:
<external-path name="jsnap_images" path="Android/data/org.broadinstitute.jsnap/files/Pictures" />
Étant donné que je ne sais pas lequel est ce que vous voulez vraiment, je ne peux pas suggérer de solution.
Je sais que c'est une question assez ancienne, mais cette réponse s'adresse aux futurs téléspectateurs. J'ai donc rencontré un problème similaire et après des recherches, j'ai trouvé une alternative à cette approche.
Votre intention ici, par exemple: pour afficher votre image depuis votre chemin
val intent = Intent()
intent.setAction(Intent.ACTION_VIEW)
val file = File(currentUri)
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
val contentURI = getContentUri(context!!, file.absolutePath)
intent.setDataAndType(contentURI,"image/*")
startActivity(intent)
Fonction principale ci-dessous
private fun getContentUri(context:Context, absPath:String):Uri? {
val cursor = context.getContentResolver().query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
arrayOf<String>(MediaStore.Images.Media._ID),
MediaStore.Images.Media.DATA + "=? ",
arrayOf<String>(absPath), null)
if (cursor != null && cursor.moveToFirst())
{
val id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID))
return Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, Integer.toString(id))
}
else if (!absPath.isEmpty())
{
val values = ContentValues()
values.put(MediaStore.Images.Media.DATA, absPath)
return context.getContentResolver().insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
}
else
{
return null
}
}