I am trying to save and retrieve a Bitmap from internal storage but everytime I try to load bitmap, BitMapFactory throws Exception:
BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: android.graphics.Bitmap#b35e414: open failed: ENOENT (No such file or directory)
I have tried nearly all solutions given by similar threads on this website, but none worked for me.
And this exception is thrown 4 times, though I am reading only one image.How?
And this is the code I am using to save and retrieve images from storage.
public static void saveFile(Context context, Bitmap b, String picName) {
FileOutputStream fos;
try {
fos = context.openFileOutput(picName, Context.MODE_PRIVATE);
b.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (IOException e) {
Log.e("store DRV image", e.getMessage());
e.printStackTrace();
}
}
public static Bitmap loadBitmap(Context context, String picName) {
Bitmap b = null;
FileInputStream fis;
try {
fis = context.openFileInput(picName);
b = BitmapFactory.decodeStream(fis);
fis.close();
} catch (IOException e) {
Log.e("get stored DRV image", e.getMessage());
e.printStackTrace();
}
return b;
}
I got this code from a thread on this website, and all comments were good. But its not working for me. I have added permissions in Manifest.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Lastly, I am using random generated UIDs as filename. The UIDs are generated using Firebase SDK. So the UID may contain numbers or other characters like
XXgKbRiS5ogQz1euqiyRsC1ggBS2. So is this a wrong way to name a file? and hence exception is thrown?
Add this code in onCreate() of your Activity:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
catch the result in same activity using:
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 0: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(getContext(), "Permission granted", Toast.LENGTH_SHORT).show();
//call your method
} else {
Toast.makeText(getContext(), "Permission denied", Toast.LENGTH_SHORT).show();
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
Learn more about Runtime Permission from HERE
You need to add user permission above 6.0:
Add library:
compile 'pub.devrel:easypermissions:0.2.1'
private String[] galleryPermissions = {Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (EasyPermissions.hasPermissions(this, galleryPermissions)) {
pickImageFromGallery();
} else {
EasyPermissions.requestPermissions(this, "Access for storage",
101, galleryPermissions);
}
//Make sure permission are granted
//For saving
File file=saveFile(contex,bitmap,picName);
//For fetching
File dir = new File(Environment.getExternalStorageDirectory(), picName);
BitmapFactory.decodeFile(file.getPath())
/**
* #param context
* #param b
* #param picName
*/
public static File saveFile(Context context, Bitmap b, String picName) {
FileOutputStream fos;
File dir = new File(Environment.getExternalStorageDirectory(), "My Images");
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, picName);
try {
fos = context.openFileOutput(file.getPath(), Context.MODE_PRIVATE);
b.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (IOException e) {
Log.e("store DRV image", e.getMessage());
e.printStackTrace();
}
return file;
}
Related
I'm trying to write/read a file into the external storage after requesting all permissions on runtime.
Manifest:
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
Runtime:
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE.
JavaCode:
public class FilesUtil {
public static String saveImageToFile(Bitmap image ,String employeeId){
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/AppName");
myDir.mkdirs();
String filename = String.format("EMPLOYEE_%s.png", employeeId);
File file = new File (myDir, filename);
if (file.exists()){
file.delete(); // here i'm checking if file exists and if yes then i'm deleting it but its not working
}
FileOutputStream out = null;
try {
out = new FileOutputStream(file,false);
image.compress(Bitmap.CompressFormat.PNG, 100, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return filename;
}
public static String getImagePath(String employeeId){
String result = Environment.getExternalStorageDirectory().toString() + "/AppName/";
String filename = String.format("EMPLOYEE_%s.png", employeeId);
return result + filename;
}
}
Load File:
private Bitmap getCurrentPhoto() {
File image = new File(FilesUtil.getImagePath(getCurrentEmployeeId()));
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(image.getAbsolutePath(), bmOptions);
return bitmap;
}
The first time that I run the app I get an open failed: EACCES (Permission denied) just on Android 6.0.1, However, in other versions of the Operative system, the feature is working fine. If I kill and Reopen the app on 6.0.1, the feature is working fine.
There is a bug on Android 6.0, the permissions are not being applied until all the application processes are killed. In other versions of the operating system when there is a change in the permissions settings, the App is Killed automatically and restarted from last Activity.
I avoid the bug using this on onRequestPermissionsResult and Restart the App.
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length == permissions.length){
if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.restart_message)
.setPositiveButton(R.string.restart_button, (dialog, id) -> {
restartApp();
});
builder.create().show();
}
}
}
I need to save some files into my Android phone.
So I used something like:
FileOutputStream os = null;
try{
os = new FileOutputStream("/root/sdcard/DCIM/1.jpg");
os.write(bytes);
os.close();
}catch(FileNotFoundException e){}
When I do this, it would say something like
java.io.FileNotFoundException: /root/sdcard/DCIM/1.jpg (Permission denied)
Btw, I already requestd permission in AndroidManifest.xml using something like:
<user-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I also tried
getFilesDir().getAbsolutePath();
And it actually refers to
/data/user/0/come.package.xxx/files
Which I have no idea where this path is because I could not find it on my phone.
When I use ASUS File Manager, I see the path is /root/sdcard/..., but I don't even have a sdcard in my phone, I have been using iPhone for many years now, so I don't know how the Android file system works now.
This is really confusing for me, could someone explain it to me how the Android file system works? Thank you all!
if you are using android 6.0 Marsh or higher android version u need to give run time permission to access.try below code
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
camera.setEnabled(false);
ActivityCompat.requestPermissions(getActivity(), new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 0) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
//permission will get success here
//do what you want
}
else {
//Permission not granted
Toast.makeText(getActivity(),"You need to grant camera permission to use camera",Toast.LENGTH_LONG).show();
}
}
}
To save image on Android:
private String saveToInternalStorage(String name, Bitmap bitmapImage){
ContextWrapper cw = new ContextWrapper(context);
// path to /data/data/yourapp/app_data/imageDir
File directory = cw.getDir(IMAGE_TAG, Context.MODE_PRIVATE);
// Create imageDir
File mypath = new File(directory, name + ".jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(mypath);
// Use the compress method on the BitMap object to write image to the OutputStream
bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return directory.getAbsolutePath();
}
To load image:
public void loadImage(ImageView imageView) {
// get path
ContextWrapper cw = new ContextWrapper(context);
File directory = cw.getDir(IMAGE_TAG, Context.MODE_PRIVATE);
String path = directory.getAbsolutePath();
// load image
try {
File f = new File(path, name + ".jpg");
Bitmap b = BitmapFactory.decodeStream(new FileInputStream(f));
imageView.setImageBitmap(b);
imageView.setVisibility(View.VISIBLE);
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.d("Image", "Image file not found.");
}
}
if your are using marshmallow or latest version of android so you need to provide permission at run time, on your buttom click than you need to call your code for saving file into sd card.
after than do like this,
public void onClick(View v) {
// write on SD card file data in the text box
try {
File myFile = new File("/sdcard/mysdfile.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter =
new OutputStreamWriter(fOut);
myOutWriter.append(txtData.getText());
myOutWriter.close();
fOut.close();
Toast.makeText(getBaseContext(),
"Done writing SD 'mysdfile.txt'",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
Here's what I'm currently doing:
tess-two is set up in my Android project
I have permissions specified in the AndroidManifest.xml of my main app (not the tess-two AndroidManifest.xml):
I also check for permissions explicitly in my code:
int readPermission = ActivityCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE);
int writePermission = ActivityCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE);
// Check we have both read and write permissions
if (readPermission != PackageManager.PERMISSION_GRANTED
|| writePermission != PackageManager.PERMISSION_GRANTED)
{
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
this,
new String[] {READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE},
REQUEST_EXTERNAL_STORAGE
);
}
else
{
Log.d(TAG, "Read and write external permissions granted");
initTess();
}
Try to initialise the TessBaseAPI:
private void initTess()
{
// Check we have the eng.traineddata file in the correct place
mTessDataPath = getFilesDir() + "/tesseract/";
checkTessFile(new File(mTessDataPath + "tessdata/"));
// Initialise TessBaseAPI
mTess = new TessBaseAPI();
mTess.init(mTessDataPath, "eng");
}
private void checkTessFile(File dir)
{
// Check if directory already exists
if (dir.exists())
{
// Check if file already exists
String dataFilePath = mTessDataPath + "tessdata/eng.traineddata";
File datafile = new File(dataFilePath);
if (!datafile.exists())
{
// If file doesn't exist, copy it over from assets folder
copyTessFiles();
}
}
else
{
if (dir.mkdirs())
{
// If directory doesn't exist, but we can create it, copy file from assets folder
copyTessFiles();
}
}
}
private void copyTessFiles()
{
try
{
// Location we want the file to be at
String filepath = mTessDataPath + "tessdata/eng.traineddata";
// Get access to AssetManager
AssetManager assetManager = getAssets();
// Open byte streams for reading/writing
InputStream instream = assetManager.open("tessdata/eng.traineddata");
OutputStream outstream = new FileOutputStream(filepath);
// Copy the file to the location specified by filepath
byte[] buffer = new byte[1024];
int read;
while ((read = instream.read(buffer)) != -1)
{
outstream.write(buffer, 0, read);
}
outstream.flush();
outstream.close();
instream.close();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
{
switch (requestCode)
{
case REQUEST_EXTERNAL_STORAGE:
{
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)
{
// Initialise Tesseract API
initTess();
}
return;
}
}
}
When I run the app, I get the following error in my logs:
E/Tesseract(native): Could not initialize Tesseract API with language=eng!
I have no idea where to go from here, so any help or advise would be hugely appreciated, thank you :)
Make sure you're using the right version of the training data files.
This code works correctly under 6.0.1 android version but if i run this application on 6.0.1 android devices , it will not save images to sd card.
What i need to update for 6.0.1 devices ?
public void SaveImages(int a ,String b)
{
Bitmap bitmap = null;
OutputStream output;
if(a==0)
{
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.image_0);
}
File filepath = Environment.getExternalStorageDirectory();
// Create a new folder in SD Card
File dir = new File(filepath.getAbsolutePath()
+ "/Wallpapers/");
dir.mkdirs();
// Create a name for the saved image
File file = new File(dir,b);
// Show a toast message on successful save
Toast.makeText(FullImageActivity.this, "Loading...",
Toast.LENGTH_SHORT).show();
Toast.makeText(FullImageActivity.this, "Image Saved to SD Card",
Toast.LENGTH_SHORT).show();
try {
output = new FileOutputStream(file);
// Compress into png format image from 0% - 100%
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, output);
output.flush();
output.close();
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
On Android 6.0+, you need to request runtime permission to write to external storage.
In order to request runtime permission to write to external storage:
public class MarshmallowPermission {
public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE = 2;
public MarshmallowPermission() {
}
public boolean checkPermissionForExternalStorage(Activity activity) {
if(Build.VERSION.SDK_INT >= 23) {
int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
} else {
return true;
}
}
public void requestPermissionForExternalStorage(Activity activity) {
if(ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(activity,
"External Storage permission needed. Please allow in App Settings for additional functionality.",
Toast.LENGTH_LONG).show();
// user has previously denied runtime permission to external storage
} else {
ActivityCompat.requestPermissions(activity,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE);
}
}
}
Then you can do
if(!marshmallowPermission.checkPermissionForExternalStorage(this)) {
marshmallowPermission.requestPermissionForExternalStorage(this);
} else {
// can write to external
}
And
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == MarshmallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE) {
if(marshmallowPermission.checkPermissionForExternalStorage(this)) {
// can write to external
} else {
// runtime permission denied, user must enable permission manually
}
}
}
Refer the following link,
How to save the image to SD card on button Click android. and
Saving image from image view to sd card : Android.
For detailed tutorial,
http://www.android-examples.com/save-store-image-to-external-storage-android-example-tutorial/
am trying to create a folder on sdcard and save all images there and not on internal memory.
public class CameraActivity extends Activity {
private static final int CAMERA_PIC_REQUEST = 1111;
private ImageView mImage;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImage = (ImageView) findViewById(R.id.result);
//1
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File image = new File(Environment.getExternalStorageDirectory()+File.separator +"mypics");
Uri fileUri = Uri.fromFile(image);
intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(intent, CAMERA_PIC_REQUEST);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST) {
//2
Bitmap thumbnail = (Bitmap) data.getExtras().get("data");
EditText etext = (EditText) findViewById(R.id.editTextLocation);
Toast.makeText(getBaseContext(), data.getExtras().get("data").toString(), Toast.LENGTH_LONG).show();
mImage.setImageBitmap(thumbnail);
etext.setText(data.getExtras().get("data").toString());
//3
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
thumbnail.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
//4
String state=Environment.getExternalStorageState();
Toast.makeText(getBaseContext(), state, Toast.LENGTH_LONG).show();
File file = new File(Environment.getExternalStorageDirectory()+File.separator +"mypics");
if(!file.exists())
if(file.mkdirs())
Log.v("Mobitracker","success");
if (Environment.MEDIA_MOUNTED.equals(state))
Toast.makeText(getBaseContext(), "Yes its read only", Toast.LENGTH_LONG).show();
if ( Environment.isExternalStorageRemovable ())
Toast.makeText(getBaseContext(), "Yes its internal card", Toast.LENGTH_LONG).show();
//Create New file and name it Image2.PNG
File file1 = new File(file, "Image2.PNG");
try {
file1.createNewFile();
FileOutputStream fo = new FileOutputStream(file1);
//5
fo.write(bytes.toByteArray());
fo.flush();
fo.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else
Toast.makeText(getBaseContext(), "Please take snap again", Toast.LENGTH_LONG).show();
}
}
This is my code for it, I tried many things but stillnot possible it is saving in internalmemory DCIM folder why?
Am getting output as
Mounted
Yes its read only
Am not connected to system but still same problem I even tried restarting phone and all but still same.
Am using sony xperia tipo mobile 4.0.4 os.
Please help me its frustrating I tried all threads.
can you guys help me please
My permissions are
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
And also I could see bitmap image in image view but
Toast.makeText(getBaseContext(), data.getExtras().get("data").toString(),Toast.LENGTH_LONG).show();
is returning some android.graphics#422020 some thing
You should use outputstream to write the content. Refer here for help.
Or do something like (see here the complete thread):
Button.OnClickListener buttonSaveOnClickListener
= new Button.OnClickListener(){
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
OutputStream outStream = null;
File file = new File(extStorageDirectory, "er.PNG");
try {
outStream = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
Toast.makeText(AndroidWebImage.this, "Saved", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(AndroidWebImage.this, e.toString(), Toast.LENGTH_LONG).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(AndroidWebImage.this, e.toString(), Toast.LENGTH_LONG).show();
}
}
};
Read this Android Training post carefully to figure things out. As the post says,
The Android Camera application saves a full-size photo if you give it a file to save into.
so if you did pass the Uri of a file,it will be stored in DCIM only and you should access the image using this Uri.
Check out similar thread