I am developing a simple gallery app in which I search for folders which contains images and then show images of that particular folder. First I am using Environment.getExternalStorageDirectory() and then recursively search for folders having images. It is working fine simulator and devices. When my client installed app on Nexus 4, nothing is being loaded. I have seen some posts which says that Nexus series don't have any external SD slot. I don't have Nexus 4 for debugging and client is also non-technical. He can troubleshoot on his own to find the cause of problem. Can anybody help in this regard? I think the problem is in Environment.getExternalStorageDirectory() call which is not applicable in Nexus. Any idea how I can tackle this issue?
Here is the code snipped I am using:
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File cacheDir = null;
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
cacheDir=new File(android.os.Environment.getExternalStorageDirectory().getAbsolutePath(), "MyImages");
}
else {
cacheDir = getCacheDir();
}
if(!cacheDir.exists()) {
cacheDir.mkdir();
}
// File storageDir = Environment.getExternalStoragePublicDirectory(
// Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
cacheDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "" + image.getAbsolutePath();
return image;
}
public void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
ex.printStackTrace();
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
And here the permissions I have added manifest:
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-feature
android:name="android.hardware.camera"
android:required="true" />
Thanks!
I think you should give a try to the MediaStore.Images component. Load the images using a cursor. See documentation: http://developer.android.com/reference/android/provider/MediaStore.html
Related
In my app I have created a option for taking Photo and Viewing taken Photos.
For taking Photos I am using default camera of mobile.
I am using below code for passing intent
public void intentForTakePicture() {
Intent picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (picIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
ex.printStackTrace();
Log.e(LOG_TAG,"Exception while trying to create image file!!");
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.app.photo.fileprovider",
photoFile);
picIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(picIntent, TAKE_PHOTO);
Log.d(LOG_TAG,"request code is: "+TAKE_PHOTO);
}
}
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir("Pictures/photo/");
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
Log.d(LOG_TAG, "currentPhotoPath: " + currentPhotoPath);
return image;
}
In onActivityResult I am setting imageview whatever photos comes there
But the issue is, I am able to take photos but taken Photo is not getting back in onActivityResult.
Note: Getting this issue only for ASUS_X01BDA mobile.
I also checked the mobile camera permissions for my app. Got camera permission for my app.
I doesn't know the problem.
Please Anybody help me to find the cause and to solve it
Google introduced Scoped Storage on Android 10, according to the document, we can write to the public directories without requesting permission by using MediaStore API.
Before Android 10, when we need to take a photo and save it to Pictures, code is like below:
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
...
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
}
}
}
String currentPhotoPath;
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = image.getAbsolutePath();
return image;
}
We create the file directly in the Pictures, and put the file uri into the takePhotoIntent extra, while we start the intent and take a photo, original-size photo will be saved into the Pictures directory.
But now we are targeting android 10, according to the doc, it is not nessasary to request the WRITE_EXTERNAL_STORAGE permission to save a photo into the Pictures directory.
Without the permission, we can't create the file and then get the uri of the file, put it into the intent extra. So how can we save the original-size photo?
I am developing an application that captures photo and saves it in internal device folder named "photo".I need to load the photo from "photo" folder to imageview.There is only one photo present in the folder.How to do this?
Please help me.Thank you in advance.
Below is the code that I have tried which loads photo from folder only if name of photo is displayed.
String path = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/GeoPark/final_photo/20180504_002754.jpg";
File imgFile = new File(path);
if (imgFile.exists()) {
imageView.setImageBitmap(decodeFile(imgFile));
}
else
Toast.makeText(ViewActivity.this,"No Image File Present ",Toast.LENGTH_SHORT).show();
Try this method .. in below method give proper file path.
private void loadImageFromStorage(String path)
{
try {
File f=new File(path, "profile.jpg");
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
ImageView img=(ImageView)findViewById(R.id.imgPicker);
img.setImageBitmap(b);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
Second things ..
File file = ....
Uri uri = Uri.fromFile(file);
imageView.setImageURI(uri);
alos i hope you add below permission into android manifest file ..
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
You could simply do a search about this, guaranteed results.
Anyway, Glide will help you with that
EDIT :
Taking picture using camera:
private void dispatchTakePictureIntent(Context context) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(context.getPackageManager()) != null) {
// Create the File where the photo should go
File photoFile = null;
try {
photoFile = createImageFile(context);
} catch (IOException ex) {
// Error occurred while creating the File
Snackbar.make(btn_open_camera, "Couldn't create a file for your picture!", Snackbar.LENGTH_LONG);
}
// Continue only if the File was successfully created
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(context,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(takePictureIntent, MY_PERMISSIONS_REQUEST_CAMERA);
}
}
}
private File createImageFile(Context context) throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = context.getFilesDir();
Log.i(TAG, "StorageDir : " + storageDir);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
Log.i(TAG, "mCurrentPhotoPath : " + mCurrentPhotoPath);
return image;
}
Now you have the image path stored in mCurrentPhotoPath which is a String declared in current activity. As you said, you will need this in next activity, to do that you can take a look at this answer
I am trying to save an image by taking the picture then load it into my application. But the problem I am facing is the picture always saved with different names so I failed to load it. (I check my file manager and i saw the picture I took saved with different names.)
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
// Error occurred while creating the File
}
// Continue only if the File was successfully created
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, RESULT_TAKE_PHOTO);
}
}
private File createImageFile() throws IOException {
// Create an image file name
String imageFileName = "puzzle";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = "file:" + image.getAbsolutePath();
return image;
}
I cant identify why it always save with different names.
I cant identify why it always save with different names.
Because you told it to, by using createTempFile(). The point behind using createTempFile() is to create a File with a unique filename. If you do not want a unique filename, do not use createTempFile().
I am adding a photo from the phones camera to a Fragment. I am including the file path to where I would like the pic to get saved in the camera intent(MediaStore.ACTION_IMAGE_CAPTURE).
My problem is that after launching the camera and taking the pic the I am not able to get back to my app. The screen stays in the part where the user gets the option to accept the pic or take another one. The phone doesn't hang or crash and I am able to get back to my app by hitting the back button, but when I get back to the app it is without the pic.
I hope I have made my problem clear, if not let me know and I will try to explain better. I have attached (what I think) are the relevant bits of code.Let me know if you need to see anymore of the code.
Launching the camera intent:
void takePic()
{
if(isExternalStorageWritable() && isExternalStorageReadable())
{
Log.w("Rakshak", "in the take pic");
File file = getPicStoragePath();
Uri uriSavedImage=Uri.fromFile(file);
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
startActivityForResult(intent, CAMERA_IMAGE_ACTIVITY_REQUEST_CODE);
}
}
public File getPicStoragePath() {
Log.w("Rakshak", "in the get pic file");
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File (root.getAbsolutePath() + File.separator +"YAN");
if(!dir.exists())
dir.mkdirs();
File file = new File(dir,getPicName());
return file;
}
public String getPicName()
{
Log.w("Rakshak", "in the get pic name");
if(title.getText().toString().trim().length() == 0)
{
Log.w("Rakshak", "no title");
Calendar cal=Calendar.getInstance();//get an instance of the calendar
return String.format("%1$te %1$tB %1$tY,%1$tI:%1$tM:%1$tS %1$Tp",cal);// get the data/time when the note was created
}
else
{
return title.getText().toString().trim();
}
}
I have these permissions in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
The relavent bits from the onActivityResult:
case CAMERA_IMAGE_ACTIVITY_REQUEST_CODE:
Log.w("Rakshak", "in the camera case");
myBitmap = data.getExtras().getParcelable("data");
photo.setVisibility(View.VISIBLE);
photo.setImageBitmap(myBitmap);
update_pic = true;
return;
There are no error messages in the LogCat. And I could not find anything of note in there.
I get the pic inserted onto the image view just fine if I dont add a file path to the camera intent. It is only when I add the file path that the stays in the "accept pic" bit of the camera.
Your getPicStoragePath() might be the issue. Try something like this:
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}