可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
in my application,i am using android devices camera to capture an image. for some devices it works fine but some are not. I just tested it on LG nexus 4 E960, after i captured the image my application went crash without able to save the result.
this is my code:
//Using intent to open camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent,CAMERA_CAPTURE);
in the activityResult :
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(resultCode==RESULT_OK)
{
if(requestCode==CAMERA_CAPTURE)
{
Bitmap pictTaken = null ;
Bundle extras = data.getExtras();
if(extras.keySet().contains("data"))
{
pictTaken = (Bitmap) extras.get("data");
picUri = getIntent().getData();
}
else{
picUri = getIntent().getData();
try {
pictTaken = decodeUri(picUri);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Intent cropIntent= new Intent (this, Crop.class);
cropIntent.putExtra("data", picUri.toString());
cropIntent.putExtra("pict", pictTaken);
cropIntent.putExtra("code","camera");
startActivity(cropIntent);
}
}
after captured and save it, the image show in next activity called Crop.class
here is my logcat
12-12 13:26:36.340: E/AndroidRuntime(23575): FATAL EXCEPTION: main
12-12 13:26:36.340: E/AndroidRuntime(23575): Process: com.example.cobaandroid, PID: 23575
12-12 13:26:36.340: E/AndroidRuntime(23575): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.example.cobaandroid/com.example.cobaandroid.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference
12-12 13:26:36.340: E/AndroidRuntime(23575): at android.app.ActivityThread.deliverResults(ActivityThread.java:3368)
12-12 13:26:36.340: E/AndroidRuntime(23575): at android.app.ActivityThread.handleSendResult(ActivityThread.java:3411)
12-12 13:26:36.340: E/AndroidRuntime(23575): at android.app.ActivityThread.access$1300(ActivityThread.java:138)
12-12 13:26:36.340: E/AndroidRuntime(23575): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
12-12 13:26:36.340: E/AndroidRuntime(23575): at android.os.Handler.dispatchMessage(Handler.java:102)
12-12 13:26:36.340: E/AndroidRuntime(23575): at android.os.Looper.loop(Looper.java:136)
12-12 13:26:36.340: E/AndroidRuntime(23575): at android.app.ActivityThread.main(ActivityThread.java:5050)
12-12 13:26:36.340: E/AndroidRuntime(23575): at java.lang.reflect.Method.invoke(Native Method)
12-12 13:26:36.340: E/AndroidRuntime(23575): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
12-12 13:26:36.340: E/AndroidRuntime(23575): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
12-12 13:26:36.340: E/AndroidRuntime(23575): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.toString()' on a null object reference
12-12 13:26:36.340: E/AndroidRuntime(23575): at com.example.cobaandroid.MainActivity.onActivityResult(MainActivity.java:226)
12-12 13:26:36.340: E/AndroidRuntime(23575): at android.app.Activity.dispatchActivityResult(Activity.java:5433)
12-12 13:26:36.340: E/AndroidRuntime(23575): at android.app.ActivityThread.deliverResults(ActivityThread.java:3364)
12-12 13:26:36.340: E/AndroidRuntime(23575): ... 9 more
I got a problem to open/use the camera that work at most android devices, the main goal of this project is heavily depend on the use of the camera. please hand me your help, thank you..
回答1:
try below code,
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File file=getOutputMediaFile(1);
picUri = Uri.fromFile(file); // create
i.putExtra(MediaStore.EXTRA_OUTPUT,picUri); // set the image file
startActivityForResult(i, CAPTURE_IMAGE);
where getOutputMediaFile(int) will be,
/** Create a File for saving an image */
private File getOutputMediaFile(int type){
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyApplication");
/**Create the storage directory if it does not exist*/
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
return null;
}
}
/**Create a media file name*/
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == 1){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".png");
} else {
return null;
}
return mediaFile;
}
and finally,
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
Intent i;
switch (requestCode) {
case CAPTURE_IMAGE:
//THIS IS YOUR Uri
Uri uri=picUri;
break;
}
}
}
Cheers....:)
回答2:
For those who couldn't solve this issue with any of the answers here, here is the way.
You have a member picUri
in which you save the temporary image file URI before the startActivityForResult
is called for launching the Camera app.
When the app pauses, this information might get lost (as in my case) and you will find it as null
when you return to activity to use it to get the saved image from camera.
Then, you will get NullPointerException
.
The proper way to keep picUri
is to save it onSaveInstanceState(Bundle)
and restore it onRestoreInstanceState(Bundle)
to prevent information loss.
Here is how to do it:
// Save the activity state when it's going to stop.
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("picUri", picUri);
}
// Recover the saved state when the activity is recreated.
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
picUri= savedInstanceState.getParcelable("picUri");
}
Gave me a headache for two hours.
回答3:
replace
picUri = getIntent().getData();
with
picUri = data.getData();
and try once...
回答4:
You have to tell camera for saving image path like below:
Uri picUri;
Intent intentAmbil = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
String imageFilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/picture.jpg";
File imageFile = new File(imageFilePath);
picUri = Uri.fromFile(imageFile); // convert path to Uri
intentAmbil.putExtra( MediaStore.EXTRA_OUTPUT, picUri );
startActivityForResult(intentAmbil, REQUEST_MAKE_PHOTO);
@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_MAKE_PHOTO:
if (resultCode == Activity.RESULT_OK) {
// do something with mMakePhotoUri
}
return;
default: // do nothing
super.onActivityResult(requestCode, resultCode, data);
}
}
回答5:
Try this one
if (resultCode != RESULT_CANCELED) {
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
if (requestCode == CAMERA_REQUEST) {
if (data != null) {
Bitmap photo = (Bitmap) data.getExtras().get("data");
imageView.setImageBitmap(photo);
}
}
}
Drawable drawable = imageView.getDrawable();
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
bitmap1 = bitmapDrawable.getBitmap();
}
}
}
if (bitmap1 != null) {
bitmap1 = Bitmap.createScaledBitmap(bitmap1, 512, 512, false);
imageView.setImageBitmap(bitmap1);
@SuppressWarnings("unused")
String path = SaveImage_Sta(bitmap1, "stat");
} else {
Log.i("bitmap............", "bitmap1 is null");
}
回答6:
in some devices onActivityResult is called not on activity resume instead the activity is restarted after callback from camera intent, so picurl can be null again - we can use the application class to keep reference of the variable
We can create our own application class
1.in android manifest we have to Specify the application class we are going to use
<application android:name=".MyApplication"
>
<activity
........
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity>
....
</activity>
....
</application>
2.Create the Application Class
public class MyApplication extends Application {
private Uri picUri;
public void getPicUri()
{
return picUri;
}
public void setPictUri(Uri auri)
{
picUri = aUri;
}
}
3.Inside the Activity use
//call the camera intent and pass the created a tempfile uri and use the tempfile uri
MyApplication myApplication = (MyApplication)getApplication();
myApplication.setPictUri(aUri);
....
....
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_MAKE_PHOTO:
if (resultCode == Activity.RESULT_OK) {
// do something with mMakePhotoUri
MyApplication myApplication = (MyApplication)getApplication();
myApplication.getPicUri();// use the pic uri
}
return;
default: // do nothing
super.onActivityResult(requestCode, resultCode, data);
}
}
回答7:
I have the same issue in my app.
The problem is that when onActivityResult is executed, data is null so you can't get anything from the camera Activity.
There should be another way to solve this rather than using the Application class, because it gets really complicate when you handle more than one photo.
回答8:
See I've done one more thing may be it will save your time. The thing is that the data object in onActivityResult() is the main content to look upon. The data object is being null when it comes to operate the p=code for the next move. What you'll do is to just put if-else condition on that and run your project.
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(data !=null){
if(resultCode==RESULT_OK)
{
if(requestCode==CAMERA_CAPTURE)
{
Bitmap pictTaken = null ;
Bundle extras = data.getExtras();
if(extras.keySet().contains("data"))
{
pictTaken = (Bitmap) extras.get("data");
picUri = getIntent().getData();
}
else{
picUri = getIntent().getData();
try {
pictTaken = decodeUri(picUri);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Intent cropIntent= new Intent (this, Crop.class);
cropIntent.putExtra("data", picUri.toString());
cropIntent.putExtra("pict", pictTaken);
cropIntent.putExtra("code","camera");
startActivity(cropIntent);
}
}
}else{
//on cancel event or something else you want to do
}
}
Check this out, it is easy and will do your work in a go.