我是Android编程的新手,之前从未使用过Java,但我正在尝试创建一个允许用户查看检查列表的应用程序,并在必要时拍照。我有一个Button,用于在ImageView中存储图像。它工作正常,直到我试图将照片保存到设备的存储空间。我使用了这里的官方文档:https://developer.android.com/training/camera/photobasics.html。问题是,当我点击按钮打开相机时,我收到一条消息,说应用已停止。此时相机仍然打开,我可以拍照,但是当我点击“确定”时,应用程序已经在后台关闭,因此图片无处可去。
相关的Java看起来像这样:
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);
}
}
此外,我不知道这是否是执行此操作的最佳方式,因为会有多次用户能够拍照。任何帮助都会受到大力赞赏!
这是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)
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>
答案 0 :(得分:0)
如果您使用的是高于棒棒糖的Android设备,则必须在运行时授予相机权限。为此:
if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.CAMERA},
1);
return;
}
处理权限请求响应
@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
}
}
不要忘记获得清单
的许可感谢this