简体   繁体   中英

Android app crashes when taking photo

I am new to android programming and have never used Java before but I am trying to create an app that allows a user to go through a check list, and take photos whenever necessary. I have a Button which is used to store an image in an ImageView. It was working fine until I tried to make the photo save to the device's storage. I used the official documentation found here: https://developer.android.com/training/camera/photobasics.html . The problem is, when I click the button to open the camera, I get a message saying the app has stopped. At this point the camera still opens and I can take a picture but when I click "OK", the app has already closed in the background and so there is nowhere for the picture to go.

The relevant Java looks like this:

public class MainActivity extends AppCompatActivity {

static final int REQUEST_IMAGE_CAPTURE = 1;
ImageView externalPhotoImageView;
String mCurrentPhotoPath;

private File createImageFile() throws IOException {
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
            imageFileName,
            ".jpg",
            storageDir
    );

    mCurrentPhotoPath = image.getAbsolutePath();
    return image;
}

public void launchCamera (View view) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {

        }
        if (photoFile != null) {
            Uri photoURI = FileProvider.getUriForFile(this,
                    "com.instaguard.vacantpropertychecklist",
                    photoFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
        }
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
        Bitmap photo = (Bitmap) extras.get("data");
        externalPhotoImageView.setImageBitmap(photo);
    }
}

private void galleryAddPic() {
    Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
    File f = new File(mCurrentPhotoPath);
    Uri contentUri = Uri.fromFile(f);
    mediaScanIntent.setData(contentUri);
    this.sendBroadcast(mediaScanIntent);
}

private void setPic() {
    // Get the dimensions of the View
    int targetW = externalPhotoImageView.getWidth();
    int targetH = externalPhotoImageView.getHeight();

    // Get the dimensions of the bitmap
    BitmapFactory.Options bmOptions = new BitmapFactory.Options();
    bmOptions.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
    int photoW = bmOptions.outWidth;
    int photoH = bmOptions.outHeight;

    // Determine how much to scale down the image
    int scaleFactor = Math.min(photoW/targetW, photoH/targetH);

    // Decode the image file into a Bitmap sized to fill the View
    bmOptions.inJustDecodeBounds = false;
    bmOptions.inSampleSize = scaleFactor;

    Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
    externalPhotoImageView.setImageBitmap(bitmap);
  }
}

Also I don't know if this is the best way of doing this as there will be multiple occurrences of the user having the ability to take photos. Any help would be massively appreciated!

Here is the logcat:

08-18 09:11:27.556 16401-16401/? E/Zygote: v2
08-18 09:11:27.556 16401-16401/? I/libpersona: KNOX_SDCARD checking this for 10260
08-18 09:11:27.556 16401-16401/? I/libpersona: KNOX_SDCARD not a persona
08-18 09:11:27.557 16401-16401/? E/Zygote: accessInfo : 0
08-18 09:11:27.561 16401-16401/? W/SELinux: SELinux selinux_android_compute_policy_index : Policy Index[1],  Con:u:r:zygote:s0 SPD:SEPF_SECMOBILE_7.0_0006 RAM:SEPF_SECMOBILE_7.0_0005, [-1 -1 0 1 0 1]
08-18 09:11:27.562 16401-16401/? I/SELinux: SELinux: seapp_context_lookup: seinfo=untrusted, level=s0:c512,c768, pkgname=com.instaguard.vacantpropertychecklist 
08-18 09:11:27.565 16401-16401/? I/art: Late-enabling -Xcheck:jni
08-18 09:11:27.581 16401-16401/? D/TimaKeyStoreProvider: TimaSignature is unavailable
08-18 09:11:27.582 16401-16401/? D/ActivityThread: Added TimaKeyStore provider
08-18 09:11:27.590 16401-16408/? I/art: Debugger is no longer active
08-18 09:11:27.590 16401-16408/? I/art: Starting a blocking GC Instrumentation
08-18 09:11:27.677 16401-16401/? W/System: ClassLoader referenced unknown path: /data/app/com.instaguard.vacantpropertychecklist-1/lib/arm64
08-18 09:11:27.685 16401-16401/? D/ContextRelationMgrBrdg: loadKlass() : caller=com.samsung.android.bridge.multiscreen.common.ContextRelationManagerBridge.<clinit>:28 android.app.LoadedApk.makeApplication:840 
08-18 09:11:27.695 16401-16401/? I/InstantRun: starting instant run server: is main process
08-18 09:11:27.746 16401-16401/? W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
08-18 09:11:27.935 16401-16401/? D/InputTransport: Input channel constructed: fd=76
08-18 09:11:27.935 16401-16401/? D/ViewRootImpl@220191b[MainActivity]: setView = DecorView@5331ab8[MainActivity] touchMode=true
08-18 09:11:27.999 16401-16420/? I/OpenGLRenderer: Initialized EGL, version 1.4
08-18 09:11:27.999 16401-16420/? D/OpenGLRenderer: Swap behavior 1
08-18 09:11:28.002 16401-16420/? D/libGLESv1: STS_GLApi : DTS is not allowed for Package : com.instaguard.vacantpropertychecklist
08-18 09:11:28.003 16401-16420/? D/mali_winsys: EGLint new_window_surface(egl_winsys_display*, void*, EGLSurface, EGLConfig, egl_winsys_surface**, egl_color_buffer_format*, EGLBoolean) returns 0x3000,  [1440x2560]-format:1
08-18 09:11:28.015 16401-16406/? I/art: Do partial code cache collection, code=24KB, data=30KB
08-18 09:11:28.015 16401-16406/? I/art: After code cache collection, code=24KB, data=30KB
08-18 09:11:28.015 16401-16406/? I/art: Increasing code cache capacity to 128KB
08-18 09:11:28.017 16401-16401/? D/ScrollView:  onsize change changed 
08-18 09:11:28.036 16401-16401/? W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
08-18 09:11:28.102 16401-16401/? D/ViewRootImpl@220191b[MainActivity]: MSG_RESIZED_REPORT: ci=Rect(0, 96 - 0, 0) vi=Rect(0, 96 - 0, 0) or=1
08-18 09:11:28.102 16401-16401/? D/ViewRootImpl@220191b[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1
08-18 09:11:28.104 16401-16401/? V/InputMethodManager: Starting input: tba=android.view.inputmethod.EditorInfo@93f6e92 nm : com.instaguard.vacantpropertychecklist ic=com.android.internal.widget.EditableInputConnection@a9ec063
08-18 09:11:28.104 16401-16401/? I/InputMethodManager: [IMM] startInputInner - mService.startInputOrWindowGainedFocus
08-18 09:11:28.143 16401-16415/? D/InputTransport: Input channel constructed: fd=84
08-18 09:11:28.173 16401-16401/? V/InputMethodManager: Starting input: tba=android.view.inputmethod.EditorInfo@3c84460 nm : com.instaguard.vacantpropertychecklist ic=com.android.internal.widget.EditableInputConnection@35a8d19
08-18 09:11:28.306 16401-16401/? D/ViewRootImpl@220191b[MainActivity]: MSG_RESIZED: ci=Rect(0, 96 - 0, 1128) vi=Rect(0, 96 - 0, 1128) or=1
08-18 09:11:28.339 16401-16401/? D/ScrollView:  onsize change changed 
08-18 09:11:28.341 16401-16406/? I/art: Do partial code cache collection, code=61KB, data=60KB
08-18 09:11:28.341 16401-16406/? I/art: After code cache collection, code=59KB, data=58KB
08-18 09:11:28.341 16401-16406/? I/art: Increasing code cache capacity to 256KB
08-18 09:11:32.949 16401-16401/com.instaguard.vacantpropertychecklist D/ViewRootImpl@220191b[MainActivity]: ViewPostImeInputStage processPointer 0
08-18 09:11:32.950 16401-16401/com.instaguard.vacantpropertychecklist W/System: ClassLoader referenced unknown path: /system/framework/QPerformance.jar
08-18 09:11:32.951 16401-16401/com.instaguard.vacantpropertychecklist E/BoostFramework: BoostFramework() : Exception_1 = java.lang.ClassNotFoundException: Didn't find class "com.qualcomm.qti.Performance" on path: DexPathList[[],nativeLibraryDirectories=[/system/lib64, /vendor/lib64]]
08-18 09:11:32.951 16401-16401/com.instaguard.vacantpropertychecklist V/BoostFramework: BoostFramework() : mPerf = null
08-18 09:11:33.014 16401-16401/com.instaguard.vacantpropertychecklist D/ViewRootImpl@220191b[MainActivity]: ViewPostImeInputStage processPointer 1
08-18 09:11:33.048 16401-16401/com.instaguard.vacantpropertychecklist D/AndroidRuntime: Shutting down VM


                                                                                        --------- beginning of crash
08-18 09:11:33.049 16401-16401/com.instaguard.vacantpropertychecklist E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                        Process: com.instaguard.vacantpropertychecklist, PID: 16401
                                                                                        java.lang.IllegalStateException: Could not execute method for android:onClick
                                                                                            at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293)
                                                                                            at android.view.View.performClick(View.java:6213)
                                                                                            at android.widget.TextView.performClick(TextView.java:11074)
                                                                                            at android.view.View$PerformClick.run(View.java:23645)
                                                                                            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:6692)
                                                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
                                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
                                                                                         Caused by: java.lang.reflect.InvocationTargetException
                                                                                            at java.lang.reflect.Method.invoke(Native Method)
                                                                                            at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
                                                                                            at android.view.View.performClick(View.java:6213) 
                                                                                            at android.widget.TextView.performClick(TextView.java:11074) 
                                                                                            at android.view.View$PerformClick.run(View.java:23645) 
                                                                                            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:6692) 
                                                                                            at java.lang.reflect.Method.invoke(Native Method) 
                                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 
                                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) 
                                                                                         Caused by: 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 com.instaguard.vacantpropertychecklist.MainActivity.launchCamera(MainActivity.java:206)
                                                                                            at java.lang.reflect.Method.invoke(Native Method) 
                                                                                            at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
                                                                                            at android.view.View.performClick(View.java:6213) 
                                                                                            at android.widget.TextView.performClick(TextView.java:11074) 
                                                                                            at android.view.View$PerformClick.run(View.java:23645) 
                                                                                            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:6692) 
                                                                                            at java.lang.reflect.Method.invoke(Native Method) 
                                                                                            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 
                                                                                            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) 

And the Manifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.instaguard.vacantpropertychecklist">
<uses-feature android:name="android.hardware.camera"
    android:required="true" />
<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"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".utilitiespage"></activity>
    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.android.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>

If you are using an android device upper than lollipop you have to grant camera permission on run time either. and for doing this:

if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {
        requestPermissions(new String[]{Manifest.permission.CAMERA},
                1);


        return;
    }

Handle the permissions request response

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! do the
                // calendar task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'switch' lines to check for other
        // permissions this app might request
    }
}

Do not forget to get permission on manifest

thank to this

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM