java.io.FileNotFoundException Permission Denied when saving image - android

private void saveImage(Bitmap bitmap){
try {
String path = Environment.getExternalStorageDirectory().toString();
Toast.makeText(getActivity(), path, Toast.LENGTH_SHORT).show();
OutputStream fOut = null;
File file = new File(path, mWallpaper.getId().toString() + ".jpg");
fOut = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 85, fOut); // saving the Bitmap to a file compressed as a JPEG with 85% compression rate
fOut.flush();
fOut.close();
MediaStore.Images.Media.insertImage(getActivity().getContentResolver(),file.getAbsolutePath(),file.getName(),file.getName());
} catch (MalformedURLException e) {
Toast.makeText(getActivity(), "Error saving wallpaper. MAL", Toast.LENGTH_SHORT).show();
} catch (IOException e1) {
Toast.makeText(getActivity(), "Error saving wallpaper.", Toast.LENGTH_SHORT).show();
e1.printStackTrace();
}
}
I added this to my AndroidManifests:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I am trying to save an image to /storage/emulated/0/.
EDIT
int permissionCheck = ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(),
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
} else {
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
permissionCheck);
}
}
I've added this to onCreate() for my fragment but I still not a request.

if (Build.VERSION.SDK_INT >= 23) {
int permissionCheck = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
}
Do this if you are using >=api 23. After this add your code. With this code you ask run-time permission from the user.
Requesting Permissions at Run Time Documentation from official Android site

Another solution is to use
getApplicationContext().getFilesDir().getPath()
rather than
Environment.getExternalStorageDirectory()
If you implement this solution, you do not need to add any permission to Manifest because your files are saved in Application directory, not SD Card.

if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},23
);
}
}
try this also you can follow folling link
http://www.theappguruz.com/blog/runtime-permissions-in-android-marshmallow

Related

Android 10 code to allow external directory access and grant permissions

Good day everyone,
I would like to ask a few questions, if I may.
I have an app that works on pre-Android 10 phones, but I see that various code changes have been made when accessing external directories. I don't have access to an Android 10 phone, so I have come up with the following code after perusal of many pages on Stackoverflow. I don't know of a way to test it myself, so could someone please kindly let me know what they think of this code:
String imageFileName;
String timestamp; // creation of the value omitted here
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
imageFileName = getApplicationContext().getExternalFilesDir(null).getAbsolutePath() + "/" + timeStamp + ".jpg";
}
else
{
imageFileName = Environment.getExternalStorageDirectory()+ "/" + timeStamp + ".jpg";
}
OutputStream fout = null; // Now write out the image to external directory
File imageFile = new File(imageFileName);
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 95, fout);
fout.flush();
fout.close();
} catch (Exception e) {
// do stuff
}
// Now, "update" the directory using MediaScannerConnection.scanFile to refresh
// its contents when viewed on the device
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
MediaScannerConnection.scanFile(activityReference.get(), new String[]{getApplicationContext().getExternalFilesDir(null).getAbsolutePath().toString()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri)
{
}
});
}
else // Not Android 10
{
MediaScannerConnection.scanFile(activityReference.get(), new String[]{Environment.getExternalStorageDirectory().toString()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri)
{
}
});
}
The parts above that don't explicitly reference Android 10 work fine
The other questions are about permissions to access the filestore, which I would like to read/write to. I have these declared in the Manifest and currently my code, for pre-Android 10 is
if( (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
|| (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED))
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, PERMISSION_ALL);
}
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, PERMISSION_ALL);
}
I am loading an image file and, again pre-Android 10, I have
findbutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 7);
}
});
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
switch(requestCode){
case 7:
if(resultCode==RESULT_OK){
Uri PathHolder = data.getData();
try
{
img = BitmapFactory.decodeStream(getContentResolver().openInputStream(PathHolder));
}
catch(Exception e)
{
//
}
// Do more image related stuff here
}
break;
}
}
Is there anything here that needs to have an "if..then" statement to account for file access in Android 10?
Thanks in advance for any help given.

Permission denied but I have permission access

I already put a permission access on my manifest still not saving. I tried this yesterday and its saving my image and now I cant. I dont know what is the problem here. logcat says java.io.IOException: open failed: EACCES (Permission denied)
below is the code
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RelativeLayout content = (RelativeLayout) findViewById(R.id.dashBoard);
content.setDrawingCacheEnabled(true);
Bitmap bitmap = content.getDrawingCache();
File file = new File(Environment.getExternalStorageDirectory().getPath()+ imagename+ ".png");
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 10, ostream);
ostream.close();
content.invalidate();
Toast.makeText(getApplicationContext(), "SAVED", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
} finally {
content.setDrawingCacheEnabled(false);
}
}
});
here is the full logcat
https://www.dropbox.com/s/dlb6p5i1nd1kxua/Logcat.txt?dl=0
You need use real time permission after SDK API 23 required.
You can ask permission like this code.
if (Build.VERSION.SDK_INT >= 23) {
if (checkWritePermission()) {
// your code
} else {
requestStoragePermission();
}
} else {
// your code
}
You need to check permission and request put this method.
private boolean checkWritePermission() {
int result = ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
return false;
}
}
private void requestStoragePermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
Toast.makeText(MainActivity.this, "EXTERNAL STORAGE permission allows us to save image/video. Please allow this permission in App Settings.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_STORAGE_REQUEST_CODE);
}
}
Use onRequestPermissionsResult method for handle permission result
Don't forget to put permission on manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

How Android Saving Files?

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();
}
}

tess-two won't initialise, even with correct permissions

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.

android 6 - open failed: ENOENT (No such file or directory)

When creating a new file, I am getting the above error. This code works in Android 4.4 version . I am testing on a 6.0.1 device and getting this error. I have the write permission in the manifest file, tried to mkDirs() before creating the file, still the same issue. Here is the code snippet :
File newFile = new File(localFilePath);
try {
String abc = null;
abc = Environment.getExternalStorageState();
if(!newFile.exists()) {
newFile.mkdirs();
newFile.createNewFile();
}
} catch (IOException e1) {
e1.printStackTrace();
return false;
}
The externalStoragState comes back as 'mounted'. Storage location is /storage/emulated/0/testlocation/filename..
You have to give Run time permission for 6.0
private static final int MY_PERMISSIONS_REQUEST_STORAGE = 1;
private String[] storage_permissions =
{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
if ((int) Build.VERSION.SDK_INT >= 23) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE) && ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_EXTERNAL_STORAGE) && ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(this);
builder.setMessage("To get storage access you have to allow us access to your sd card content.");
builder.setTitle("Storage");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(OmniSalesHubDrawerActivity.this, storage_permissions, 0);
onContactsClick();
}
});
builder.show();
} else {
ActivityCompat.requestPermissions(this, storage_permissions, 0);
onContactsClick();
}
} else {
ActivityCompat.requestPermissions(DrawerActivity.this,
storage_permissions,
MY_PERMISSIONS_REQUEST_STORAGE);
onContactsClick();
}
}
}

Categories

Resources