Reputation: 6079
I have an app that allow user to upload a photo on wall.
The code works well for the majority of users, but I have reported that the application crashes sometimes when uploading photo.
The problem is not in taking the pictures from the camera, but it is when you have to take the path of the picture.
The version of Android that is causing this problem is 4.4.2, but I do not understand how to fix it.
post some code:
activityResult:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == CAMERA_PIC_REQUEST) {
try {
//picUri is a global variable Uri
picUri = data.getData();
cropImage();
} catch (Exception e) {
e.printStackTrace();
}
}
else if(requestCode == PIC_CROP) {
try{
//thumbnail is a global variable Bitmap
thumbnail = MediaStore.Images.Media.getBitmap(context.getContentResolver(), cropImageUri);
setImage();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
hot to crop image:
public void cropImage() {
try {
Intent cropIntent = new Intent("com.android.camera.action.CROP");
//indicate image type and Uri
cropIntent.setDataAndType(picUri, "image/*");
//set crop properties
cropIntent.putExtra("crop", "true");
//indicate aspect of desired crop
cropIntent.putExtra("aspectX", 1);
cropIntent.putExtra("aspectY", 1);
cropIntent.putExtra("scale", true);
//indicate output X and Y
cropIntent.putExtra("outputX", 700);
cropIntent.putExtra("outputY", 700);
//retrieve data on return
cropIntent.putExtra("return-data", false);
File f = createNewFile("CROP_");
try{
f.createNewFile();
}
catch (IOException e) {
e.printStackTrace();
}
//cropImageUri is a global variable Uri
cropImageUri = Uri.fromFile(f);
cropIntent.putExtra(MediaStore.EXTRA_OUTPUT, cropImageUri);
//start the activity - we handle returning in onActivityResult
startActivityForResult(cropIntent, PIC_CROP);
}
catch(ActivityNotFoundException anfe){
anfe.printStackTrace();
}
}
create new File:
private File createNewFile(String prefix) {
if (prefix== null) {
prefix="IMG_";
}
else if("".equalsIgnoreCase(prefix)) {
prefix="IMG_";
}
File newDirectory = new File(Environment.getExternalStorageDirectory()+"/mypics/");
if (!newDirectory.exists()) {
if (newDirectory.mkdir()) {
}
}
File file = new File(newDirectory,(prefix+System.currentTimeMillis()+".jpg"));
if (file.exists()) {
file.delete();
try {
file.createNewFile();
}catch (IOException e) {
e.printStackTrace();
}
}
return file;
}
then when a user click on "send" method preUploadImage is called:
public void preUploadImage() {
UploadImage uploadImage = new UploadImage();
Uri newUri = getImageUri(thumbnail);
try{
// System.out.println("uri = "+picUri);
uploadImage.upload(getRealPathFromURI(newUri));
}
catch (IOException e) {
e.printStackTrace();
}
}
public Uri getImageUri(Bitmap inImage) {
String path = MediaStore.Images.Media.insertImage(context.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
and in the last row the error appears.
return Uri.parse(path);
this row cause a NullPointerException
java.lang.NullPointerException: uriString
at android.net.Uri$StringUri.<init>(Uri.java:468)
at android.net.Uri$StringUri.<init>(Uri.java:458)
at android.net.Uri.parse(Uri.java:430)
at com.delsorboilario.verdebio.ScriviDomanda.getImageUri(ScriviDomanda.java:584)
at com.delsorboilario.verdebio.ScriviDomanda.preUploadImage(ScriviDomanda.java:608)
at com.delsorboilario.verdebio.ScriviDomanda$6$4$2.run(ScriviDomanda.java:292)
Upvotes: 1
Views: 2235
Reputation: 1006779
I have not attempted to use insertImage()
, and in this case, it is not quite clear why you would need it.
Primarily, it seems like you are looking to upload the photo. For that, all you need is the File
that you created in createNewFile()
. If you are uploading it yourself (e.g., HttpUrlConnection
, some third-party library), you should be able to just use the File
or an InputStream
on it. Even if the upload code really needs a Uri
, you can try Uri.fromFile()
to get a Uri
from your File
and see if that works.
Where MediaStore
does come into play is making your file be indexed and therefore accessible to apps (ones that query the MediaStore
for images) and to users (via their MTP connection through their USB cable). MediaScannerConnection
and its static scanFile()
method are a fairly straightforward way to get the file indexed. Just make sure your file is fully written to disk first (e.g., if you are writing the file yourself, call getFD().sync()
on your FileOutputStream
after flush()
and before close()
).
Upvotes: 2
Reputation: 69440
Looks like MediaStore.Images.Media.insertImage(context.getContentResolver(), inImage, "Title", null);
return null.
Form the documentation of MediaStore.Images.Media
Insert an image and create a thumbnail for it.
Parameters
cr The content resolver to use
source The stream to use for the image
title The name of the image
description The description of the image
Returns The URL to the newly created image, or null if the image failed to be stored for any reason
Upvotes: 2