我目前正在开发可以拍照的应用程序。我主要将其用作教程:https://developer.android.com/guide/topics/media/camera#capture-picture 应当指出,我不打算让它录制视频。
无论如何,每次我单击按钮拍照时,都会有些滞后,并且什么也没有发生。 Logcat会显示“ D / [应用程序名称]:创建目录失败”。是的,我确实搜索过该词,但是找不到真正对我有帮助的解决方案。
最奇怪的部分是,如果我再次单击捕获按钮,应用程序将崩溃并显示以下消息:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.assessment, PID: 13633
java.lang.RuntimeException: takePicture failed
at android.hardware.Camera.native_takePicture(Native Method)
at android.hardware.Camera.takePicture(Camera.java:1551)
at android.hardware.Camera.takePicture(Camera.java:1493)
at com.example.assessment.MainActivity.onClick(MainActivity.java:113)
...
我将在下面的代码中标记第113行。
我希望解决方案是我忽略的简单事物。
我认为可能是导致问题的原因之一,但是我不确定方法的作用。我将在这些区域标记很多星号。
正如我所说,我曾尝试寻找解决方案,但据我所知,一切都是正确的。
主要活动:
package com.example.assessment;
//Imports are here
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Camera camera;
private CameraPreview preview;
public static final int MEDIA_TYPE_IMAGE = 1;
//Skipped this code, it just declared buttons
PictureCallback picture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
//Put error message here
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d("Assessment", "File not Found");
} catch (IOException e) {
Log.d("Assessment", "Cannot access file");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); //These two lines hides the notification bar at the top of the screen
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_main);
//Skipped code here, it just sets up the buttons
//The following takes the user to a new activity if they lack permissions - I check for permissions for the camera, read externally, and write externally. Yes, I made sure they were all enabled when testing the app.
if (!(PermissionsActivity.hasAllPermissions())) {
Intent goToPermissionsIntent = new Intent(MainActivity.this, PermissionsActivity.class);
startActivity(goToPermissionsIntent);
}
if(hasCamera(this)){
camera = getCameraInstance();
preview = new CameraPreview(this, camera);
FrameLayout fl_preview = (FrameLayout)findViewById(R.id.flo_cameraPreview);
fl_preview.addView(preview);
}
}
/// Check if this device has a camera - from API
private boolean hasCamera(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
return true;
} else {
return false;
}
}
// Gets an instance of the Camera object - from API
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
//Do something here
}
return c;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_capture:
//captures photo
//The line below is line 113
camera.takePicture(null, null, picture);
break;
//I had two other switch cases here but they are irreverent for now - they just took you to other activities.
}
}
//I took this from the API, it is never called though
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image */
private static File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "Assessment");
//******* Below is where the log notification above is referenced. I am not sure what to do.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("Assessment", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg");
} else {
return null;
}
return mediaFile;
}
@Override
protected void onPause() {
super.onPause();
if (camera != null){
camera.release(); // release the camera for other applications
camera = null;
}
}
}