我希望我的应用拍照(不是有意)。 我希望我的活动A.class拍照并给其他活动B.class我的图片的absolutePath()在意图的putExtra中调用B.Class。
这是我的代码
ANDROID CODE
public class A extends Activity {
private SurfaceHolder previewHolder=null;
private Camera camera=null;
private boolean inPreview=false;
private boolean cameraConfigured=false;
protected static final String TAG = "DEBUG_TAG";
protected Throwable e;
private File pictureFile;
private String picturePath;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.capture);
SurfaceView preview=(SurfaceView)findViewById(R.id.SurfaceView_camera);
previewHolder=preview.getHolder();
previewHolder.addCallback(surfaceCallback);
TextView capturer = (TextView)findViewById(R.id.TextView_capturer);
capturer.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
camera.takePicture(null, null, mPicture);
(L.88) call_next_activity(v);
}
});
}
@Override
public void onPause() {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera=null;
inPreview=false;
super.onPause();
}
@Override
public void onResume() {
super.onResume();
camera=Camera.open();
startPreview();
}
private void initPreview(int width, int height) {
if (camera!=null && previewHolder.getSurface()!=null) {
try {
camera.setPreviewDisplay(previewHolder);
} catch (Throwable t) {
Log.e("PreviewDemo-surfaceCallback", "Exception in setPreviewDisplay()", t);
Toast.makeText(capture.this, t.getMessage(), Toast.LENGTH_LONG).show();
}
if (!cameraConfigured) {
Camera.Parameters parameters=camera.getParameters();
camera.setDisplayOrientation(90);
parameters.set("rotation", 90);
Camera.Size Previewsize=getBestPreviewSize(width, height, parameters);
parameters.setPreviewSize(Previewsize.width, Previewsize.height);
Camera.Size PictureSize = getBestPictureSize(width, height, parameters);
parameters.setPictureSize(PictureSize.width, PictureSize.height);
parameters.setJpegQuality(100);
camera.setParameters(parameters);
cameraConfigured=true;
}
}
}
private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
if (size.width<=width && size.height<=height) {
if (result==null) {
result=size;
} else {
int resultArea=result.width*result.height;
int newArea=size.width*size.height;
if (newArea>resultArea) {
result=size;
}
}
}
}
return(result);
}
private Camera.Size getBestPictureSize(int width, int height, Camera.Parameters parameters) {
Camera.Size result = null;
for (Camera.Size size : parameters.getSupportedPictureSizes()) {
if (size.width>=width && size.height>=height) {
if (result==null) {
result=size;
} else {
int resultArea=result.width*result.height;
int newArea=size.width*size.height;
if (newArea>resultArea) {
result=size;
}
}
}
}
return(result);
}
private void startPreview() {
if (cameraConfigured && camera!=null) {
camera.startPreview();
inPreview=true;
}
}
private static File getOutputMediaFile(){
String NewFolder = "/TEST";
String StorageDirectory;
StorageDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File mediaStorageDir = new File(StorageDirectory + NewFolder);
if (!mediaStorageDir.exists()){
if (!mediaStorageDir.mkdirs()){
Log.d("Jours de Chefs", "failed to create directory");
return null;
} else {
mediaStorageDir.mkdir();
}
}
String date = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss", Locale.FRANCE).format(new Date());
File photo = new File(StorageDirectory + NewFolder, "Full_TEST_" + date + ".jpg");
return photo;
}
public void call_next_activity(View v) {
// ----- HERE I HAVE EXCEPTION -----//
// When i want to call picturePath or pictureFile, i get Exception :
// NullPointerException
(L.246) if (!picturePath.isEmpty()) {
Toast.makeText(capture.this, "CA MARCHE !!!!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(capture.this, "CA MARCHE PAS", Toast.LENGTH_LONG).show();
}
}
private PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
pictureFile = getOutputMediaFile();
chemin_acces_photo = pictureFile.getPath();
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: " + e.getMessage());
return;
}
// ----- HERE TOAST SHOW ME RIGHT PATH ----- //
// NO EXCEPTION, NO BUG, EVERYTHING IS OKAY
Toast.makeText(capture.this, pictureFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
}
};
SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
// no-op -- wait until surfaceChanged()
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
initPreview(width, height);
startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// no-op
}
};
}
一切都很好,但是当我想调用pictureFile.getAbsolutePath()时,我有这个错误:
LOGCAT代码
E/AndroidRuntime(14165): FATAL EXCEPTION: main
E/AndroidRuntime(14165): java.lang.NullPointerException
E/AndroidRuntime(14165): at XXXXXXXXXXXXXX.capture.call_next_activity(capture.java:246)
E/AndroidRuntime(14165): at XXXXXXXXXXXXXX.capture$3.onClick(capture.java:88)
E/AndroidRuntime(14165): at android.view.View.performClick(View.java)
E/AndroidRuntime(14165): at android.view.View$PerformClick.run(View.java)
E/AndroidRuntime(14165): at android.os.Handler.handleCallback(Handler.java)
E/AndroidRuntime(14165): at android.os.Handler.dispatchMessage(Handler.java)
E/AndroidRuntime(14165): at android.os.Looper.loop(Looper.java)
E/AndroidRuntime(14165): at android.app.ActivityThread.main(ActivityThread.java)
E/AndroidRuntime(14165): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(14165): at java.lang.reflect.Method.invoke(Method.java:511)
E/AndroidRuntime(14165): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java)
E/AndroidRuntime(14165): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java)
E/AndroidRuntime(14165): at dalvik.system.NativeStart.main(Native Method)
有人能解释我为什么我的pictureFile == NULL?
编辑1 : Melquiades回答
这是因为camera.takePicture()是异步的。你有:
@Override
public void onClick(View v) {
camera.takePicture(null, null, mPicture);
call_next_activity(v); //<----------here picturePath is not yet initialised
}
因此,当您调用上面的takePicture()时,它会立即返回并且call_next_activity()是&gt;已调用,但picturePath尚未设置。
将你的call_next_activity()代码移动到你的mPicture()回调中,在设置了picturePath之后。
很好的解释,但现在我遇到了新的问题: 我的call_next_activity(v)代码是一个例子,在这个函数中,我想改变活动,然后我的真实代码如果:
ANDROID CODE
public void call_next_activity(v) {
Intent intent = new Intent (this, next_activity.class);
intent.putExtra("image_path", picturePath);
startActivity(intent);
}
我无法将call_next_activity()代码放入mPicture回调中,因为我的这个不是我的视图,而是 Camera.PictureCallback(){}
有什么想法吗?
编辑2 :答案 关注Melquiades Edit,只需删除call_next_activity(v)函数, 在onPictureTaken()函数的末尾写下call_next_activity代码:
public void onPictureTaken(byte[] data, Camera camera) {
pictureFile = getOutputMediaFile();
if (pictureFile == null){
Log.d(TAG, "Error creating media file, check storage permissions: " + e.getMessage());
return;
}
Toast.makeText(capture.this, pictureFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d(TAG, "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d(TAG, "Error accessing file: " + e.getMessage());
}
// ----- call_next_activity code here ----- //
Intent intent = new Intent (getApplicationContext(), next_activity.class);
intent.putExtra("image_path", pictureFile.getAbsolutePath());
startActivity(intent);
}
PS:我删除了我的picturePath(string)变量,并通过pictureFile.getAbsolutePath()更改picturePath。
谢谢大家!
答案 0 :(得分:1)
这是因为camera.takePicture()是异步的。你有:
@Override
public void onClick(View v) {
camera.takePicture(null, null, mPicture);
call_next_activity(v); //<----------here picturePath is not yet initialised
}
因此,当您调用上面的takePicture()时,它会立即返回并调用call_next_activity(),但还没有设置picturePath。
将你的call_next_activity()代码移动到你的mPicture()回调中,在设置了picturePath之后。
编辑:
声明
private Context context;
在你的A类中,然后在setContentView()之后将它设置在onCreate()上:
context = this;
最后,用它来设定你的意图:
public void call_next_activity(v) {
Intent intent = new Intent (context, next_activity.class);
intent.putExtra("image_path", picturePath);
startActivity(intent);
}
或者,您可以使用:
Intent intent = new Intent(getApplicationContext(), next_activity.class);
或
Intent intent = new Intent(A.this, next_activity.class);
答案 1 :(得分:0)
根据您的相关代码,我认为您收到java.lang.NullPointerException
,因为您的String
变量picturePath
没有任何价值。请初始化一些值。
希望它能帮到你