Reputation: 1531
I am working on a application in which I have to click the image from the camera and save it into directory.I am able to create directory named MyPersonalFolder and also images are going into it but when I am trying to open that image to see, it doesn't open and shows the message that that image cannot be opened. here is my code. Can anyone please tell me what mistake I am doing here.
I have also mentioned permissions in manifest .
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
public class Camera extends Activity{
private static final String TAG = "Camera";
private static final int CAMERA_PIC_REQUEST = 1111;
Button click , share;
ImageView image;
String to_send;
String filename;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera);
image = (ImageView)findViewById(R.id.image);
share = (Button)findViewById(R.id.share);
click = (Button)findViewById(R.id.click);
click.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
});
share.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
BitmapDrawable bitmapDrawable = (BitmapDrawable)image.getDrawable();
Bitmap bitmap = bitmapDrawable.getBitmap();
// Save this bitmap to a file.
File cache = getApplicationContext().getExternalCacheDir();
File sharefile = new File(cache, "toshare.png");
try {
FileOutputStream out = new FileOutputStream(sharefile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
} catch (IOException e) {
}
// Now send it out to share
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("image/*");
share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + sharefile.getAbsolutePath()));
try {
startActivity(Intent.createChooser(share, "Share photo"));
} catch (Exception e) {
}
/*Intent share = new Intent(Intent.ACTION_SEND);
share.setType("text/plain");
//String to_send = null;
share.putExtra(Intent.EXTRA_TEXT, to_send);
startActivity(Intent.createChooser(share, "Share using..."));*/
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
FileOutputStream outStream = null;
if (requestCode == CAMERA_PIC_REQUEST) {
//2
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
image.setImageBitmap(thumbnail);
//3
share.setVisibility(0);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
//4
try {
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/MyPersonalFolder");
dir.mkdirs();
String fileName = String.format("%d.jpg", System.currentTimeMillis());
File outFile = new File(dir, fileName);
outStream = new FileOutputStream(outFile);
//outStream.write(data[0]);
outStream.flush();
outStream.close();
//Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length + " to " + outFile.getAbsolutePath());
refreshGallery(outFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
/*try {
file.createNewFile();
FileOutputStream fo = new FileOutputStream(file);
//5
fo.write(bytes.toByteArray());
fo.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();*/
}
}
}
private void refreshGallery(File file) {
Intent mediaScanIntent = new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(Uri.fromFile(file));
sendBroadcast(mediaScanIntent);
}
}
Upvotes: 2
Views: 926
Reputation: 4593
You will need to use MediaScanner to notify the system of the new file/directory. You can try something like this after creating and saving the new file:
/**
* Adds the new photo/video to the device gallery, else it will remain only visible via sd card
*
* @param path
*/
public static void addToGallery(Context context, String path) {
MediaScanner scanner = new MediaScanner(path, null);
MediaScannerConnection connection = new MediaScannerConnection(context, scanner);
scanner.connection = connection;
connection.connect();
}
/**
* Scans the sd card for new videos/images and adds them to the gallery
*/
private static final class MediaScanner implements MediaScannerConnection.MediaScannerConnectionClient {
private final String path;
private final String mimeType;
MediaScannerConnection connection;
public MediaScanner(String path, String mimeType) {
this.path = path;
this.mimeType = mimeType;
}
@Override
public void onMediaScannerConnected() {
connection.scanFile(path, mimeType);
}
@Override
public void onScanCompleted(String path, Uri uri) {
connection.disconnect();
}
}
EDIT:
You are also forgetting to write the byte array to the file specified in the output stream, like in the code that you have commented out. Try this at the end just before you refresh the gallery:
outStream = new FileOutputStream(outFile);
outStream.write(bytes.toByteArray()); //this is the line you had missing
outStream.flush();
outStream.close();
Also take note that using Intent.ACTION_MEDIA_SCANNER_SCAN_FILE to refresh the gallery can also present you with some security issues on kitkat (cant remember exactly what the issues were). So just make sure you test it on kitkat device to confirm that it works correctly
Upvotes: 2