How to save Image to external Storage in android? [duplicate] - java

This question already has answers here:
Android permission doesn't work even if I have declared it
(11 answers)
Closed 4 years ago.
I want to store Bitmap image in external storage but I am getting an error creating the file directory.
This is my code.
private void saveImage(Bitmap bitmap){
String root = Environment.getExternalStorageDirectory().toString();
File directory = new File(root + "/Wallpapers");
boolean wasSuccessful = directory.mkdirs();
if(!wasSuccessful){
Toast.makeText(context, "Error Creating directory", Toast.LENGTH_SHORT).show();
}
Random generator = new Random();
int n = 10000;
n = generator.nextInt();
String fname = "Wallpaper-"+n+".png";
File file = new File(directory, fname);
if (file.exists()){
file.delete();
}
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
Toast.makeText(context, "Wallpaper Saved Successfully", Toast.LENGTH_SHORT).show();
}catch (Exception e){
Toast.makeText(context, "Error Saving Wallpaper", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
I already write the permission in android manifest.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
I've already tried out many solutions but it cannot resolved my issue.

Writing simple example to store bitmapImage Image given as follows. please try it out ...
//Get file name and bitmapImage and call the method ()
//Bitmap bitmapImage = ImageUtil.getInstance().changeImageRotated(cameraUri, bitmapImage, ImageUtil.TypeMode.CAMERA);
//String fileName = String.valueOf(getCurrentTimeStamp());
//ImageUtil.getInstance().saveImage(bitmapImage, fileName);
//Here is function to save bitmap image to internal storage
public Boolean saveImage(Bitmap imageData, String fileName) {
String savePath = getFilePath(AppConst.getInstance().IMAGE_DIR_APPLY);
isPathMade(savePath);
File file = new File(savePath, fileName);
FileOutputStream fileOutputStream = null;
ObjectOutputStream objectOutputStream = null;
boolean keep = true;
try {
fileOutputStream = new FileOutputStream(file);
imageData.compress(Bitmap.CompressFormat.PNG, AppConst.getInstance().PARKING_APPLY_IMAGE_COMPRESS_QUALITY, fileOutputStream);
} catch (Exception e) {
keep = false;
} finally {
try {
if (objectOutputStream != null) {
objectOutputStream.close();
}
if (fileOutputStream != null){
fileOutputStream.close();
}
if (!keep) {
file.delete();
}
return true;
} catch (Exception e) {
Logger.e(TAG, "saveImageToCache Exception is " + e.toString());
}
}
return false;
}

Related

How to move/copy any type of file from asset file to scoped storage ANDROID Q in JAVA?

I have already succeeded with this operation with images, but I cannot do it with other type of file, in my case I try to insert a database.
Here is an example of the code for the images:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){
try {
try {
pictures = assetManager.list("photos/dataset1");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
if (pictures != null) {
for (String filename : pictures) {
InputStream in;
OutputStream out;
InputStream inputStream = assetManager.open("photos/dataset1/"+filename);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
saveImageToGallery(bitmap);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
This method below works for the images :
public void saveImageToGallery(Bitmap bitmap) {
OutputStream outputStream;
Context myContext = requireContext();
try {
if(Build.VERSION.SDK_INT >=Build.VERSION_CODES.Q){
ContentResolver contentResolver = requireContext().getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME,"Image_"+".jpg");
contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
Uri imageUri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
outputStream = contentResolver.openOutputStream(Objects.requireNonNull(imageUri));
bitmap.compress(Bitmap.CompressFormat.JPEG,100, outputStream);
Objects.requireNonNull(outputStream);
}
}catch (FileNotFoundException e) {
e.printStackTrace();
}
}
and there my try for the other type of file :
AssetManager assetManager = Objects.requireNonNull(requireContext()).getAssets();
Context myContext = requireContext();
//Essential for creating the external storage directory for the first launch
myContext.getExternalFilesDir(null);
File databasesFolder = new File(myContext.getExternalFilesDir(null).getParent(), "com.mydb.orca/databases");
databasesFolder.mkdirs();
if (files!= null) {
for (String filename : files) {
InputStream in;
OutputStream out;
try {
in = assetManager.open("database/test/" + filename);
File outFile = new File(databasesFolder, filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
out.flush();
out.close();
} catch (IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
}
} else {
Log.e("Error NPE", "files is null");
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
This code above is not working, I mean, I don't get any errors or the desired result. I want something like this or a function similary as the function for my images but for any type of file.
When I run my application I have no error however nothing happens
I finally find a solution, I pretty sure it's not the best way but it work.
I give me access to all files acccess by this way :
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R){
try {
Intent intentFiles = new Intent();
intentFiles.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
Uri uriFiles = Uri.fromParts("package", myContext.getPackageName(), null);
intentFiles.setData(uriFiles);
myContext.startActivity(intentFiles);
} catch (Exception e)
{
Intent intentFiles = new Intent();
intentFiles.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
myContext.startActivity(intentFiles);
}
add this line to your manifest:
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
after that, this code below work :
AssetManager assetManager = Objects.requireNonNull(requireContext()).getAssets();
Context myContext = requireContext();
//Essential for creating the external storage directory for the first launch
myContext.getExternalFilesDir(null);
File databasesFolder = new File(myContext.getExternalFilesDir(null).getParent(), "com.mydb.orca/databases");
databasesFolder.mkdirs();
if (files!= null) {
for (String filename : files) {
InputStream in;
OutputStream out;
try {
in = assetManager.open("database/test/" + filename);
File outFile = new File(databasesFolder, filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
out.flush();
out.close();
} catch (IOException e) {
Log.e("tag", "Failed to copy asset file: " + filename, e);
}
}
} else {
Log.e("Error NPE", "files is null");
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
}
if someone have a best solution it should be nice
I tested on android 11 and it work

save image file with increment at the end of file name

enter image description here
please someone help me "To save an image file with increment at end of file name" like("image 1.jpg , image 2.jpg , etc..")
here is my code
please some help me to make this,i am new learner to android-studio.
private File saveBitMap(Context context, View drawView) {
File pictureFileDir = new File(Environment.getExternalStorageDirectory()+"/"+"Frames");
if (!pictureFileDir.exists()) {
boolean isDirectoryCreated = pictureFileDir.mkdirs();
if(!isDirectoryCreated) {
Log.i("ATG", "Can't create directory to save the image");
}
return null;
}
String filename = pictureFileDir.getPath() +File.separator+"Frame"+ System.currentTimeMillis()+".jpg";
File pictureFile = new File(filename);
Bitmap bitmap =getBitmapFromView(drawView);
try {
pictureFile.createNewFile();
FileOutputStream oStream = new FileOutputStream(pictureFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, oStream);
oStream.flush();
oStream.close();
} catch (IOException e) {
e.printStackTrace();
Log.i("TAG", "There was an issue saving the image.");
}
scanGallery( context,pictureFile.getAbsolutePath());
return pictureFile;
}
If I have understood your question properly then, I assume you want your pictureFile name to be appended by an integer (in auto-incrementing fashion).
You could do that by maintaining a global variable as int imageCount = 1
and then appending it while creating fileName
int imageCount = 1;
private File saveBitMap(Context context, View drawView) {
File pictureFileDir = new File(Environment.getExternalStorageDirectory()+"/"+"Frames");
if (!pictureFileDir.exists()) {
boolean isDirectoryCreated = pictureFileDir.mkdirs();
if(!isDirectoryCreated) {
Log.i("ATG", "Can't create directory to save the image");
}
return null;
}
String filename = pictureFileDir.getPath() +File.separator+"Frame"+ System.currentTimeMillis()+""+(imageCount++)+".jpg";
File pictureFile = new File(filename);
Bitmap bitmap =getBitmapFromView(drawView);
try {
pictureFile.createNewFile();
FileOutputStream oStream = new FileOutputStream(pictureFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, oStream);
oStream.flush();
oStream.close();
} catch (IOException e) {
e.printStackTrace();
Log.i("TAG", "There was an issue saving the image.");
}
scanGallery( context,pictureFile.getAbsolutePath());
return pictureFile;
}

Opening a file present in assets folder using an intent

Hello I am tring to open a .pdf file present in a file using an intent but it is giving me 2 errors on the following line
File file = new File(getContext().getAssets().open("assets/test.pdf"));
Errors
1.Unhandled java.IO.Exception.
2.getAssets()may produce java.lang.NullPointerException
Here us the code in a fragment
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (position == 0) {
File file = new File(getContext().getAssets().open("assets/test.pdf"));
if (file .exists())
{
Uri path = Uri.fromFile(file );
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path , "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try
{
startActivity(pdfIntent ); }
catch (ActivityNotFoundException e)
{
Toast.makeText(getActivity(), "Please install a pdf file viewer",
Toast.LENGTH_LONG).show();
}
}
}
}
File fileBrochure = new File(Environment.getExternalStorageDirectory() + "/" + "abc.pdf");
if (!fileBrochure.exists())
{
CopyAssetsbrochure();
}
/** PDF reader code */
File file = new File(Environment.getExternalStorageDirectory() + "/" + "abc.pdf");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),"application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try
{
getApplicationContext().startActivity(intent);
}
catch (ActivityNotFoundException e)
{
Toast.makeText(SecondActivity.this, "NO Pdf Viewer", Toast.LENGTH_SHORT).show();
}
}
//method to write the PDFs file to sd card
private void CopyAssetsbrochure() {
AssetManager assetManager = getAssets();
String[] files = null;
try
{
files = assetManager.list("");
}
catch (IOException e)
{
Log.e("tag", e.getMessage());
}
for(int i=0; i<files.length; i++)
{
String fStr = files[i];
if(fStr.equalsIgnoreCase("abc.pdf"))
{
InputStream in = null;
OutputStream out = null;
try
{
in = assetManager.open(files[i]);
out = new FileOutputStream(Environment.getExternalStorageDirectory() + "/" + files[i]);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
break;
}
catch(Exception e)
{
Log.e("tag", e.getMessage());
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
You cannot open the pdf file directly from the assets folder.You first have to write the file to sd card from assets folder and then read it from sd card
try with the file provider
Intent intent = new Intent(Intent.ACTION_VIEW);
// set flag to give temporary permission to external app to use your FileProvider
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// generate URI, I defined authority as the application ID in the Manifest, the last param is file I want to open
String uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, file);
// I am opening a PDF file so I give it a valid MIME type
intent.setDataAndType(uri, "application/pdf");
// validate that the device can open your File!
PackageManager pm = getActivity().getPackageManager();
if (intent.resolveActivity(pm) != null) {
startActivity(intent);
}
To serve a file from assets to another app you need to use a provider.
Google for the StreamProvider of CommonsWare.

Cannot save image from Bitmap

I get a warning stating that the result of cachePath.createNewFile(); is ignored. Otherwise the following code does not save an image to my phone. What can I do?
holder.messageImage.setOnLongClickListener(v -> {
v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
Bitmap bitmap = ((BitmapDrawable) holder.messageImage.getDrawable()).getBitmap();
File root = Environment.getExternalStorageDirectory();
File cachePath = new File(root.getAbsolutePath() + "/DCIM/Camera/image.jpg");
try {
FileOutputStream ostream = new FileOutputStream(cachePath);
bitmap.compress(CompressFormat.JPEG, 100, ostream);
ostream.close();
Toast.makeText(mContext, "Image saved successfully", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Log.w(getClass().toString(), e);
Toast.makeText(mContext, "Failed saving image", Toast.LENGTH_SHORT).show();
}
return false;
});
I download the image from my back end this way:
private void downloadMessageImage(ViewHolder holder, int position) {
ParseQuery<ParseObject> query = new ParseQuery<>(ParseConstants.CLASS_YEET);
query.whereEqualTo(ParseConstants.KEY_OBJECT_ID, mYeets.get(position).getObjectId());
query.findInBackground((user, e) -> {
if (e == null) for (ParseObject userObject : user) {
if (userObject.getParseFile("image") != null) {
String imageURL = userObject.getParseFile("image").getUrl();
/*Log.w(getClass().toString(), imageURL);*/
if (imageURL != null) {
holder.messageImage.setVisibility(View.VISIBLE);
Picasso.with(mContext)
.load(imageURL)
.placeholder(R.color.placeholderblue)
.into(holder.messageImage);
} else {
holder.messageImage.setVisibility(View.GONE);
}
}
}
});
}
The bitmap certainly does not exist: android.graphics.Bitmap#12d9cc4
to save an image I use the following code:
try {
signature.setDrawingCacheEnabled(true);
Bitmap bm = Bitmap.createBitmap(signature.getDrawingCache());
// Define params for save
File f = new File(Environment.getExternalStorageDirectory() + "/Cassiopea/momomorez/" + File.separator + "signature.png");
f.createNewFile();
FileOutputStream os = new FileOutputStream(f);
os = new FileOutputStream(f);
//compress to specified format (PNG), quality - which is ignored for PNG, and out stream
bm.compress(Bitmap.CompressFormat.PNG, 100, os);
Toast.makeText(mContext, "Saving image OK", Toast.LENGTH_SHORT).show();
os.close();
}
catch (Exception e) {
Log.v("Gestures", e.getMessage());
e.printStackTrace();
}
Use this code to save a pattern in an image within an established folder.

"Invalid File" error when the images in sdcard are clicked

To share the image via Email and mms first step I need to save the image in sdcard but for me the saved image is not getting opened instead "Invalid File" error, I checked with the extension format everything is correct but don't know where I'm going wrong.
Below is the java code.
public class Share extends CordovaPlugin {
public static final String ACTION_POSITION = "ShareImage";
#Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext)
throws JSONException {
if (ACTION_POSITION.equals(action)) {
try {
JSONObject arg_object = args.getJSONObject(0);
Intent sendIntent = new Intent(android.content.Intent.ACTION_SEND);
sendIntent.setType("image/jpg");
sendIntent.putExtra(android.content.Intent.EXTRA_TEXT, arg_object.getString("image"));
String name = arg_object.getString("image");
String defType = "drawable";
String defPackage = "com.picsswipe";
int drawableId = this.cordova.getActivity().getResources().getIdentifier( name , defType, defPackage );
// Bitmap bbicon = BitmapFactory.decodeFile( arg_object.getString("image") );
Bitmap bbicon = BitmapFactory.decodeResource( this.cordova.getActivity().getResources(),drawableId );
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
OutputStream outStream = null;
File f = new File(extStorageDirectory + "/Download/",
"jj.jpg" );
try {
outStream = new FileOutputStream(f);
bbicon.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
} catch (Exception e) {
}
File r1 = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/Download/", "jj.jpg");
//RETRIEVING IMAGES FROM SDCARD
Uri uri1 = Uri.fromFile(r1);
sendIntent.putExtra(Intent.EXTRA_STREAM, uri1);
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(r1));
Uri uris = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "jj.jpg"));
this.cordova.getActivity().startActivity(sendIntent);
} catch (Exception e) {
System.err.println("Exception: " + e.getMessage());
callbackContext.error(e.getMessage());
return false;
}
}
return true;
}
}
File file;
File rootPath = android.os.Environment
.getExternalStorageDirectory();
File directory = new File(rootPath.getAbsolutePath()
+ "/Download");
if (!directory.exists())
directory.mkdir();
file = new File(directory, "filename.PNG");//.png/.jpg anything you want
try {
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.pincheck);
FileOutputStream outStream;
outStream = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
and you should add this permission in your manifest file..Then only file will copied to your external sd card.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Categories