Android - MediaStore.Images.Media.insertImage - Unable to create file - android

I'm experiencing some weird problems related to Media.insertImage method
https://developer.android.com/reference/android/provider/MediaStore.Images.Media.html#insertImage(android.content.ContentResolver,%20android.graphics.Bitmap,%20java.lang.String,%20java.lang.String)
private Uri createTemporaryUri(Bitmap bitmap)
{
fixMediaDirForKitkat();
String savedPath = MediaStore.Images.Media.insertImage(requestTarget.getMyFragment().getActivity().getContentResolver(), bitmap, "someone_tmp", null);
return Uri.parse(savedPath);
}
private void fixMediaDirForKitkat()
{
File sdcard = Environment.getExternalStorageDirectory();
if(sdcard != null) {
File mediaDir = new File(sdcard, "DCIM/Camera");
if( !mediaDir.exists()) {
mediaDir.mkdirs();
}
}
}
For some kitkat devices (4.4 - 4.4.4) without using method fixMediaDirForKitkat insertImage function sometimes returns null. After adding method I'm experiencing:
Caused by java.lang.IllegalStateException: Unable to create new file: /storage/sdcard0/DCIM/Camera/1480524677437.jpg
android.provider.MediaStore$Images$Media.insertImage (MediaStore.java:1008)
some.one.PhotoUploader.createTemporaryUri (PhotoUploader.java:166)
some.one.PhotoUploader.beginImageUpload (PhotoUploader.java:145)
some.one.registration.RegisterFragment.onActivityResult (RegisterFragment.java:107)
Does anything else need to be initialized? Any hack or workaround here is available? Device doesn't have a SD card/space? Unable to create new file tells me nothing ;-)
Any suggestions highly appreciated

If you don't give permission then give permission to your android manifest file and if give ignore it.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You want to create directory then follow this code
public static String downloadPath = "/DCIM/Camera";
File fileDir = new File(downloadPath);
if (fileDir.isDirectory()) {
request.setDestinationInExternalPublicDir(downloadPath, filename);
} else {
fileDir.mkdirs();
request.setDestinationInExternalPublicDir(downloadPath, filename);
}
OR
Issue seems it be related with Android Runtime Permission introduced in Android 6.0
When your app targeting API Level 23, by default all the permission is false you have to request permission dialog and approve the permission before using that into your app.

Related

Access to the path ... is denied - Xamarin Android

I am trying to write an image to my android file system, however when trying to write the bytes, I get the above error.
I am running Visual Studio 2019 (as administrator) and targeting API Level 29
AndroidManifest.xml
My external storage permissions are present in my manifest file:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And as per another suggestion I have added android:requestLegacyExternalStorage="true" in my application tag:
<application android:label="App Name" android:icon="#mipmap/launcher_foreground" android:extractNativeLibs="true" android:requestLegacyExternalStorage="true">
MainActivity.cs
Here I am requesting the permissions when the app starts and pressing allow on both prompts:
int requestPermissions = 0;
string cameraPermission = Android.Manifest.Permission.Camera;
string filePermission = Android.Manifest.Permission.WriteExternalStorage;
if (!(ContextCompat.CheckSelfPermission(this, cameraPermission) == (int)Permission.Granted) || !(ContextCompat.CheckSelfPermission(this, filePermission) == (int)Permission.Granted))
{
ActivityCompat.RequestPermissions(this, new String[] { cameraPermission, filePermission
}, requestPermissions);
}
SaveMedia.cs
I get the error on File.WriteAllBytes:
public string SavePickedPhoto(Stream file, string fileName)
{
var bytes = GetBytesFromStream(file);
string path = Path.Combine(Android.App.Application.Context.GetExternalFilesDir("").AbsolutePath + "PhotoDirectoryForApp";
if (!Directory.Exists(path))
{
try
{
Directory.CreateDirectory(path);
}
catch (Exception e)
{
}
}
Path.Combine(path, fileName);
try
{
File.WriteAllBytes(path, bytes);
}
catch (Exception ex)
{
}
return path;
}
I am at a bit of a loss on what to try next as to me it seems that I should have the necessary permissions to write a file to a folder on the device. I have also tried various locations to save to and methods of saving with the same result.
Thanks in advance
You are trying to write to a directory as you are throwing away the return value from Path.Combine :
Path.Combine(path, fileName);
Try:
~~~
path = Path.Combine(path, fileName);
~~~

Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider requires android.permission.MANAGE_DOCUMENTS

Edit: This is not a duplicate question. No question I've seen answers how to solve this when you don't have control over the activity sending the intent (in my case, a browser app or maybe a file-browsing app is sending the intent to my app). And then more specifically, this is not dealing with photos/gallery.
This has been plaguing an app of mine for a while. I can't personally get it to happen with any device, but I can see from crashes it happens a lot to others.
My app receives an intent containing a ZIP file from an outside app. I catch it in either onCreate() or onNewIntent():
Intent intent = getIntent();
if (intent != null && intent.getData() != null)
beginZipIntent(intent);
In beginZipIntent():
Uri data = intent.getData();
String filename = data.toString();
// Open input stream to copy ZIP to a temporary directory.
Uri uri = Uri.parse(filename);
InputStream inputStream = null;
try
{
inputStream = getContentResolver().openInputStream(uri); // This fails
}
catch (Exception e)
{
//...
}
On the line above, some devices fail:
Permission Denial: reading com.android.providers.downloads.DownloadStorageProvider uri content://com.android.providers.downloads.documents/document/2772 from pid=26094, uid=10094 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
I have no control over the app/activity sending the intent. I thought by grabbing the file immediately and saving it to a temporary directory I could remedy this (as seen in other answers) - but nope.
I've also added android.permission.MANAGE_DOCUMENTS but as expected (from other answers) it doesn't work.
Anyone ever run into this? Seems to affect devices ranging from Android 4 to 7 so not specific to one OS version.
Well I faced this issue before, I was have an oppo device which run on android 7.1 and it's worked fine btw it's make a problem on samsung with the same version of android, so to solve this issue I asked for the read storage permission if needed, and it's worked.
Example for the people who love code:
public class CheckPermissions {
public static boolean hasPermission(int PERMISSION_REQUEST, String permission, Context context) {
if (ContextCompat.checkSelfPermission(context,
permission)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context,
permission) &&
ContextCompat.checkSelfPermission(context,
permission)
!= PackageManager.PERMISSION_GRANTED) {
return false;
} else {
ActivityCompat.requestPermissions((Activity) context,
new String[]{permission},
PERMISSION_REQUEST);
}
return false;
} else {
return true;
}
}
}
And to check the permission:
if (CheckPermissions.hasPermission(REQUEST_CODE,
Manifest.permission.READ_EXTERNAL_STORAGE, this))
// todo read the saved URI
Also I expected from you to add the permission to the manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
And use the write permission to write the file too.
You may need to add following runtime permissions in your code and manifest also
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
you can refer this link #save_zip_files
I hope it helps!!
Just add this line before get URI
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());

Android mkdirs() doesn't work

I'm trying to generate a folder with my android application in my phone storage (not on the sdcard) but my mkdirs() is not working.
I have set the android.permission.WRITE_EXTERNAL_STORAGE in my manifest and use this basic code :
File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), "/MyDirName");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("App", "failed to create directory");
}
}
but it doesn't work ... The mkdirs is always at false and the folder is not created.
I have tried everything and looked at all the topics about it but nothing is working and I don't know why.
if you target and compile sdk is higher then lolipop then please refer this link
or
File sourcePath = Environment.getExternalStorageDirectory();
File path = new File(sourcePath + "/" + Constants.DIR_NAME + "/");
path.mkdir();
If you you the emulator and the Device File Explorer of Android Studio, be sure that you right-click over a folder of the emulator and then click on 'synchronize' to update the files displayed. The Device File Explorer doesn't update by itself in real time.
when writing code for android API 29 and above use the following permission in your application manifest (AndroidManifest.xml)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
Then in your java file add the following lines of code
`ActivityCompat.requestPermissions(this, new String[]
{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},
PackageManager.PERMISSION_GRANTED);
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
file = new File(Environment.getExternalStorageDirectory().getPath(), "MyDirName/");
if (!file.exists()) {
try {
file.mkdirs();
} catch (Exception e) {
e.printStackTrace();
}
}
`

android mkdirs not working

i need to save an image from camera on android.
i used the write external storage permission in manifest and i am using this code
File dir = new File(Environment.getExternalStorageDirectory(), "Test");
if (!dir.exists() || !dir.isDirectory())
dir.mkdirs();
String path = dir.getAbsolutePath();
Log.d(TAG, path); //log show the path
File file = new File(dir.getAbsolutePath() + "/Pic.jpg");
Log.d(TAG, file.getAbsolutePath()); //again path is shown here
outStream = new FileOutputStream(file);
outStream.write(bytes);
outStream.close();
Log.d(TAG, "onPictureTaken - wrote bytes: " + bytes.length); //fail here
} catch (FileNotFoundException e) {
Log.d(TAG, "not done"); //error is here (this exception is thrown)
} catch (IOException e) {
Log.d(TAG, "not");
} finally { }
i also tried mkdir() instead of mkdirs() same result.
any idea what went wrong in the code?
thanks
For those not as experienced like me. I fought this issue, lost hair for some time. I am targeting api 21 (for compatibility sake) and it worked on lollipop but on marshmallow it would not create the directory. I did have the "uses" permission in the manifest but it still would not work. Apparently in Marshmallow when you install with Android studio it never asks you if you should give it permission it just quietly fails, like you denied it. You must go into Settings, apps, select your application and flip the permission switch on.
Some one like me who was trying in Android10. Please use below API in manifest:
<application android:requestLegacyExternalStorage="true" ... >
...
</application>
Latest Update From Google:
After you update your app to target Android 11, the system ignores the requestLegacyExternalStorage flag.
Did you put
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in your AndroidManifest? If you are using android M you must request user permission to write on sd, look here an example
IDIOT ME! i have used the Manifest Permission but when installed the app on phone i didnt grant permission for storage!... i understand a negative on this question... but i hope if someone else face the same..check your phone permission. sorry all for inconvenience.
you have created directory, not file. Create new file with following code
File file = new File(dir.getAbsolutePath() + "/Pic.jpg");
file.createNewFile()
if you are testing on android M, you should probably check Settings > App > Permission to see if permission to access storage is granted. This saved me.
if you already allowed R/W permission(Runtime Permission too) and still doesn't work add this below mentioned line in your AndroidManifest.xml
<application
........
........
android:requestLegacyExternalStorage="true">
Note: this must required if you'r targeting Android 10+
Starting from API 30 you can only write in your app-specific files
File dir = new File(context.getFilesDir(), "YOUR_DIR");
dir.mkdirs();
or in the external storage of your app Android/data
File dir = new File(myContext.getExternalFilesDir("FolderName"),"YOUR_DIR");
UPDATE
this answer provided another solution https://stackoverflow.com/a/65744517/8195076
UPDATE
another way is to grant this permission in manifest
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
like this answer https://stackoverflow.com/a/66968986/8195076
Try this. Provide runtime permission for marshmallow it is perfectly work in my Application code :
private String getFilename(String strFileName) {
String filepath = Environment.getExternalStorageDirectory().getPath();
File fileBase = new File(filepath, "Test");
if (!fileBase.exists()) {
fileBase.mkdirs();
}
return (file.getAbsolutePath() + "/" + strFileName + file_exts[currentFormat]);
}
new File(getFilename(edt.getText().toString().trim()))
outputFile = new File(apkStorage + "/" + downloadFileName );
//Create Output file in Main File
//Create New File if not present
if (!outputFile.exists()) {
isExternalStorageWritable();
outputFile.getParentFile().mkdirs();
outputFile.createNewFile();
Log.e(TAG, "File Created");
OutputStream fos = new FileOutputStream(outputFile);//Get OutputStream for NewFile Location
InputStream fis = c.getInputStream();//Get InputStream for connection
byte[] buffer = new byte[1024];//Set buffer type
int len1 = 0;//init length
while ((len1 = fis.read(buffer)) >0) {
fos.write(buffer, 0, len1);//Write new file
}
//Close all connection after doing task
fos.close();
fis.close();
I wrote this code for creating a file, but it is not working in android 11
when writing code for android API 29 and above use the following permission in your application manifest (AndroidManifest.xml)
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
Adjust your code to read like the following
ActivityCompat.requestPermissions(this, new String[]
{
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
},
PackageManager.PERMISSION_GRANTED);
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
file = new File(Environment.getExternalStorageDirectory().getPath(), "TestDirectory/Document/");
if (!file.exists()) {
try {
file.mkdirs();
} catch (Exception e) {
e.printStackTrace();
}
}

permission denied on creating new file in external storage

I want to create a new file in external storage if that file doesn't exist already.
I've already read similar questions in SO and have WRITE_EXTERNAL_STORAGE permission in my manifest.
Testing on GenyMotion emulator with android 5.1 and xperia t with android 4.3 the result is same and I get "open failed: EACCES (Permission denied)" on file.createNewFile(). I checked in runtime and getExternalStorageState functoin return value is "MOUNTED".
Note: If I create the file manually, my code works perfectly and reads the content meaning that accessing to external storage is OK.
I although write to external storage another place in my code using getExternalPublicStorage for saving captured image and it works fine!
File f = Environment.getExternalStorageDirectory();
File config = new File(f, "poinila config" + ".txt");
if (!config.exists()) {
if (!config.createNewFile()) {
// toast that creating directory failed
} else {
writeDefaultIpPort();
}
}
Edit:
path string is "/storage/sdcard0/poinila config.txt"
well I think this is the new security feature introduced in android. Runtime permissions. You have to do something like this
int hasReadExternalStoragePermission = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_EXTERNAL_STORAGE);
if(hasReadExternalStoragePermission != PackageManager.PERMISSION_GRANTED)
if (shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE))
new AlertDialog.Builder(getContext())
.setMessage("You need to Allow access to Images to set a Company Logo")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
requestPermission();
}
}).show();
else
requestPermission();
else
callChooser();
Is your permission is right place in manifest file as
<application>
...
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
</manifest>
I had the same issue. I think it is a missing / in the path. Try this:
config = new File(Environment.getExternalStorageDirectory() + "/" + "poinila config.txt" );
Hope it helps

Categories

Resources