Creating a directory in /sdcard fails - android

I have been trying to create a directory in /sdcard programmatically, but it's not working. The code below always outputs directory not created.
boolean success = (new File("/sdcard/map")).mkdir();
if (!success) {
Log.i("directory not created", "directory not created");
} else {
Log.i("directory created", "directory created");
}

There are three things to consider here:
Don't assume that the sd card is mounted at /sdcard (May be true in the default case, but better not to hard code.). You can get the location of sdcard by querying the system:
Environment.getExternalStorageDirectory();
You have to inform Android that your application needs to write to external storage by adding a uses-permission entry in the AndroidManifest.xml file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
If this directory already exists, then mkdir is going to return false. So check for the existence of the directory, and then try creating it if it does not exist.
In your component, use something like:
File folder = new File(Environment.getExternalStorageDirectory() + "/map");
boolean success = true;
if (!folder.exists()) {
success = folder.mkdir();
}
if (success) {
// Do something on success
} else {
// Do something else on failure
}

I had same issue after I updated my Android phone to 6.0 (API level 23). The following solution works on me. Hopefully it helps you as well.
Please check your android version. If it is >= 6.0 (API level 23), you need to not only include
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
in your AndroidManifest.xml, but also request permission before calling mkdir().
Code snopshot.
public static final int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
public int mkFolder(String folderName){ // make a folder under Environment.DIRECTORY_DCIM
String state = Environment.getExternalStorageState();
if (!Environment.MEDIA_MOUNTED.equals(state)){
Log.d("myAppName", "Error: external storage is unavailable");
return 0;
}
if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
Log.d("myAppName", "Error: external storage is read only.");
return 0;
}
Log.d("myAppName", "External storage is not read only or unavailable");
if (ContextCompat.checkSelfPermission(this, // request permission when it is not granted.
Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
Log.d("myAppName", "permission:WRITE_EXTERNAL_STORAGE: NOT granted!");
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Show an expanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
// MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
// app-defined int constant. The callback method gets the
// result of the request.
}
}
File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),folderName);
int result = 0;
if (folder.exists()) {
Log.d("myAppName","folder exist:"+folder.toString());
result = 2; // folder exist
}else{
try {
if (folder.mkdir()) {
Log.d("myAppName", "folder created:" + folder.toString());
result = 1; // folder created
} else {
Log.d("myAppName", "creat folder fails:" + folder.toString());
result = 0; // creat folder fails
}
}catch (Exception ecp){
ecp.printStackTrace();
}
}
return result;
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
More information please read "Requesting Permissions at Run Time"

The correct path to the sdcard is
/mnt/sdcard/
but, as answered before, you shouldn't hardcode it. If you are on Android 2.1 or after, use
getExternalFilesDir(String type)
Otherwise:
Environment.getExternalStorageDirectory()
Read carefully https://developer.android.com/guide/topics/data/data-storage.html#filesExternal
Also, you'll need to use this method or something similar
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Something else is wrong. It may be one of many other states, but all we need
// to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
then check if you can access the sdcard. As said, read the official documentation.
Another option, maybe you need to use mkdirs instead of mkdir
file.mkdirs()
Creates the directory named by the trailing filename of this file, including the complete directory path required to create this directory.

Restart your Android device. Things started to work for me after I restarted the device.

If this is happening to you with Android 6 and compile target >= 23, don't forget that we are now using runtime permissions. So giving permissions in the manifest is not enough anymore.

use mkdirs() instead of mkdir()..it worked for me :)
File folder = new File(Environment.getExternalStorageDirectory()+"/Saved CGPA");
if(!folder.exists()){
if(folder.mkdirs())
Toast.makeText(this, "New Folder Created", Toast.LENGTH_SHORT).show();
}
File sdCardFile = new File(Environment.getExternalStorageDirectory()+"/Saved CGPA/cgpa.html");

in android api >= 23
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
instead of
<app:uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Do you have the right permissions to write to SD card in your manifest ?
Look for WRITE_EXTERNAL_STORAGE at http://developer.android.com/reference/android/Manifest.permission.html

Isn't it already created ? Mkdir returns false if the folder already exists too
mkdir

There are Many Things You Need to worry about
1.If you are using Android Bellow Marshmallow then you have to set permesions in Manifest File.
2. If you are using later Version of Android means from Marshmallow to Oreo now
Either you have to go to the App Info and Set there manually App permission for Storage.
if you want to Set it at Run Time you can do that by below code
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
return true;
} else {
Log.v(TAG,"Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}

File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/FoderName");
if (!f.exists()) {
f.mkdirs();
}

I made the mistake of including both:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
and:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
in the above order. So when I took out the second permission, (READ), the problem went away.

If the error happens with Android 6.0 and API >=23 ; Giving permission in the AndroidManifest.xml is not alone enough.
You have to give runtime permissions, you can refer more here
Runtime Permission
(or)
Google has a new feature on Android Q: filtered view for external storage. A quick fix for that is to add this code in the AndroidManifest.xml file:
<manifest ... >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- This attribute is "false" by default on apps targeting Android Q. -->
<application android:requestLegacyExternalStorage="true">
...
...
</application>
</manifest>
You can read more about it here: https://developer.android.com/training/data-storage/compatibility
Internal Storage vs Seconday Storage
The internal storage is referred to as "external storage" in the API ; not the "secondary storage"
Environment.getExternalStorageDirectory();
As mentioned in the Environment Documentation

Related

How to save files at the root of SD card (android 8.0+)?

I'm trying to create a folder at the root of an external SD Card (and to later put in there the files generated by my app).
I'm asking WRITE_EXTERNAL_STORAGE permission but I think it's not enough to actually write on the external SD card.
Here's my code :
private boolean authorized = false;
private final static int MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE = 1;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
long debut = System.currentTimeMillis();
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
debut = System.currentTimeMillis();
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_EXTERNAL_STORAGE);
} else {
authorized = true;
}
while (!authorized) {
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
authorized = true;
} else if (System.currentTimeMillis() - debut >= 5000) {
this.finish();
System.exit(0);
}
}
//SDCARD path = "/storage/9016-4EF8"
new File("/storage/9016-4EF8"+"/MyApp").mkdirs();
}
My code works on my phone (android 5.1), but not on my tablet (android 8.1). It seems like I only have a read permission on the latest versions of android.
How do i get the write permission on the SD card?
I'm using a File explorer App, Xplore, and this app seems to ask for another permission before being able to modify files on the SD Card :
"grant Xplore access to your data, including photos and videos, on sd card"
How can i ask for this permission (if it's even possible)?
You are correct! It is not enough if you want to access the SD card. You need to use a documentFile.
See my answer to an older question about SD cards to understand how to access your SD card here.

Has SD card writing been blocked?

I am trying to provide a functionality in my app that the media or storage files used in my application can be moved to SD card by the user.
I am trying to use the code as described in below link
http://www.java-samples.com/showtutorial.php?tutorialid=1523
But I get a permission exception. When I searched for getting that permission, I see that I have to root the device. I don't want to root my device, as it is illegal, no? Is there any android device model that comes rooted from the beginning itself from the manufacturer?
Earlier also I used to see a "Move To SD Card" option in the app settings, but I don't see that option any more. I also saw that most of the file browser applications installed in my device are unable to create a folder on the SD card,
Please share some light on what's the best recommended way to implement this feature. We are supporting android 4.4 to 8.0
Yes writing to the sd card is blocked in modern Android versions.
Mostly you have read acces to the whole sd card.
Writing only to one app specific directory which if you are lucky is available in the second item returned by getExternalFilesDirs().
If you want to write to the whole sd card then use the Storage Access Framework.
For instance Intent.ACTION_OPEN_DOCUMENT_TREE.
If you haven't done so already, you will need to give your app the correct permission to write to the SD Card by adding the line below to your Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Getting runtime permissions
You should be checking if the user has granted permission of external storage by using:
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
//File write logic here
return true;
}
If not, you need to ask the user to grant your app a permission:
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
Of course these are for marshmallow devices only so you need to check if your app is running on Marshmallow:
if (Build.VERSION.SDK_INT >= 23) {
//do your check here
}
Be also sure that your activity implements OnRequestPermissionResult
The entire permission looks like this:
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG,"Permission is granted");
return true;
} else {
Log.v(TAG,"Permission is revoked");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
Log.v(TAG,"Permission is granted");
return true;
}
}
Permission result callback:
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
Log.v(TAG,"Permission: "+permissions[0]+ "was "+grantResults[0]);
//resume tasks needing this permission
}
}
Also
SD Card directory is /sdcard but you shouldn't be hard coding it. Instead, make a call to Environment.getExternalStorageDirectory() to get the directory:
File sdDir = Environment.getExternalStorageDirectory();
Code to write into external storage
Source
/** Method to check whether external media available and writable. This is adapted from
http://developer.android.com/guide/topics/data/data-storage.html#filesExternal */
private void checkExternalMedia(){
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
// Can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// Can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Can't read or write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
}
/** Method to write ascii text characters to file on SD card. Note that you must add a
WRITE_EXTERNAL_STORAGE permission to the manifest file or this method will throw
a FileNotFound Exception because you won't have write permission. */
private void writeToSDFile(){
// Find the root of the external storage.
// See http://developer.android.com/guide/topics/data/data- storage.html#filesExternal
File root = android.os.Environment.getExternalStorageDirectory();
// See http://stackoverflow.com/questions/3551821/android-write-to-sd-card-folder
File dir = new File (root.getAbsolutePath() + "/download");
dir.mkdirs();
File file = new File(dir, "myData.txt");
try {
FileOutputStream f = new FileOutputStream(file);
PrintWriter pw = new PrintWriter(f);
pw.println("Hi , How are you");
pw.println("Hello");
pw.flush();
pw.close();
f.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.i(TAG, "******* File not found. Did you" +
" add a WRITE_EXTERNAL_STORAGE permission to the manifest?");
} catch (IOException e) {
e.printStackTrace();
}
}
/** Method to read in a text file placed in the res/raw directory of the application. The
method reads in all lines of the file sequentially. */
private void readRaw(){
InputStream is = this.getResources().openRawResource(R.raw.textfile);
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr, 8192); // 2nd arg is buffer size
// More efficient (less readable) implementation of above is the composite expression
/*BufferedReader br = new BufferedReader(new InputStreamReader(
this.getResources().openRawResource(R.raw.textfile)), 8192);*/
try {
String test;
while (true){
test = br.readLine();
// readLine() returns null if no more lines in the file
if(test == null) break;
}
isr.close();
is.close();
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In addition to that
Shared storage may not always be available, since removable media can be ejected by the user.
Media state can be checked using getExternalStorageState(File).
There is no security enforced with these files.

Android 6.0 Write to external SD Card

I tried everything to write on external SD card on Android 6.0, but I am not able to write on it.
I did research on stackoverflow and found lot of things but none works. Here is my code
String extPath = System.getenv("SECONDARY_STORAGE") + "/Android/data/com.gvm.externalstorage.externalstoragetest/";
File file = new File(extPath,"myFiles");
if (!file.exists()) {
boolean dirResult = file.mkdirs();
Log.e("Directory Exist", dirResult + " Directory created");
} else {
Log.e("Directory Exist", "Exist");
Log.e("Direcotry Path",file.getAbsolutePath());
}
//String displayname = fileName.replace("%20", " ");
File outputFile = new File(file, "mytest5.txt");
outputFile.createNewFile();
This code works on Android 5.0 but not on Android 6.0.
Then I tried this path as well, and that gives me permission error, I have set all permission and managed code for runtime permission as well.
/mnt/media_rw/6AC9-083B
File write failed: java.io.IOException: open failed: EACCES (Permission denied)
If anyone can help me it would be great as I am trying this since last 3 days.
Thanks,
Anvesh
After long hard work I figured out a solution. In Android 6.0 it's not going to give you SD Card path always using this:
System.getenv("SECONDARY_STORAGE")
or this
Environment.getExternalStorageDirectory()
So I retrieved external SD Card path using this
File[] fs = context.getExternalFilesDirs(null);
String extPath = "";
// at index 0 you have the internal storage and at index 1 the real external...
if (fs != null && fs.length >= 2)
{
extPath = fs[1].getAbsolutePath();
Log.e("SD Path",fs[1].getAbsolutePath());
}
Rest everything will remain same for permission and all.
Thanks to those who helped me.
From API 23+(6.0) you need to request the read/write permissions even if they are already in your manifest known as Requesting Permissions at Run Time.
from docs
Beginning in Android 6.0 (API level 23), users grant permissions to
apps while the app is running, not when they install the app. This
approach streamlines the app install process, since the user does not
need to grant permissions when they install or update the app. It also
gives the user more control over the app's functionality; for example,
a user could choose to give a camera app access to the camera but not
to the device location. The user can revoke the permissions at any
time, by going to the app's Settings screen.
java
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
/**
* Checks if the app has permission to write to device storage
*
* If the app does not has permission then the user will be prompted to grant permissions
*
* #param activity
*/
public static void verifyStoragePermissions(Activity activity) {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I think u should check your app permission first, to make sure your storage permission has been turned on.
If there's no storage permission:
Please check if u use this permission in your AndroidManifest
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
If the storage permission has been turned off:
Please check your runtime permission, maybe u can refer to this code
private void checkPermissions() {
if ( Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return;
}
final List<String> permissionsList = new ArrayList<String>();
permissionsList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
permissionsList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
permissionsList.add(Manifest.permission.WRITE_CALENDAR);
permissionsList.add(Manifest.permission.READ_PHONE_STATE);
int permissionCheckLocation = ContextCompat.checkSelfPermission(IntroductionActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION);
int permissionCheckStorage = ContextCompat.checkSelfPermission(IntroductionActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
int permissionCheckCalendar = ContextCompat.checkSelfPermission(IntroductionActivity.this, Manifest.permission.WRITE_CALENDAR);
int permissionCheckPhoneState = ContextCompat.checkSelfPermission(IntroductionActivity.this, Manifest.permission.READ_PHONE_STATE);
boolean locationPermission=permissionCheckLocation == PackageManager.PERMISSION_GRANTED?true:false;
boolean storagePermission=permissionCheckStorage == PackageManager.PERMISSION_GRANTED?true:false;
boolean calendarPermission=permissionCheckCalendar == PackageManager.PERMISSION_GRANTED?true:false;
boolean phoneStatePermission=permissionCheckPhoneState == PackageManager.PERMISSION_GRANTED?true:false;
boolean shouldShowLocationPermission=ActivityCompat.shouldShowRequestPermissionRationale(IntroductionActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION);
boolean shouldShowStoragePermission=ActivityCompat.shouldShowRequestPermissionRationale(IntroductionActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
boolean shouldShowCalendarPermission=ActivityCompat.shouldShowRequestPermissionRationale(IntroductionActivity.this, Manifest.permission.WRITE_CALENDAR);
boolean shouldShowPhoneStatePermission=ActivityCompat.shouldShowRequestPermissionRationale(IntroductionActivity.this, Manifest.permission.READ_PHONE_STATE);
if (permissionCheckLocation == PackageManager.PERMISSION_GRANTED && permissionCheckStorage == PackageManager.PERMISSION_GRANTED
&& permissionCheckCalendar == PackageManager.PERMISSION_GRANTED && permissionCheckPhoneState == PackageManager.PERMISSION_GRANTED){
return;
}else if(((!locationPermission&&!shouldShowLocationPermission)||(!storagePermission&&!shouldShowStoragePermission)
||(!calendarPermission&&!shouldShowCalendarPermission)||(!phoneStatePermission&&!shouldShowPhoneStatePermission))&&appContext.localCheckPermission){
showMessageOKCancel("You need to allow access these permissions",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 1);
}
});
}else{
ActivityCompat.requestPermissions(IntroductionActivity.this, permissionsList.toArray(new String[permissionsList.size()]), 0);
}
}
If still have problem, please try to change your file path :
String fileName="mytest5.txt";
File folder = new File(Environment.getExternalStorageDirectory().getPath() + "/com.gvm.externalstorage.externalstoragetest/");
if (!folder.exists()) {
try {
folder.mkdirs();
} catch (Exception e) {
e.printStackTrace();
System.out.println("Default Save Path Creation Error:" + folder);
}
}
File logFile = new File(folder, fileName);
if (!logFile.exists()) {
try {
logFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
System.out.println("Default Save Path Creation Error:" + logFile);
}
}
Best regards. I hope this can help u
#Anvesh Another reliable method i'm using:
/**
* Get external storage path use reflect on android 6.0 device.
* Source code:
* https://github.com/android/platform_frameworks_base/blob/master/core/java/android/os/storage/StorageVolume.java
*
* #param removable the sdcard can remove or not, true means external sdcard, false means
* internal sdcard.
* #return path of sdcard we want
*/
public static String getStoragePath(boolean removable) {
WinZipApplication application = WinZipApplication.getInstance();
Context mContext = application.getApplicationContext();
StorageManager mStorageManager = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE);
Class<?> storageVolumeClazz = null;
try {
storageVolumeClazz = Class.forName("android.os.storage.StorageVolume");
Method getVolumeList = mStorageManager.getClass().getMethod("getVolumeList");
Method getPath = storageVolumeClazz.getMethod("getPath");
Method isRemovable = storageVolumeClazz.getMethod("isRemovable");
Object result = getVolumeList.invoke(mStorageManager);
final int length = Array.getLength(result);
for (int i = 0; i < length; i++) {
Object storageVolumeElement = Array.get(result, i);
String path = (String) getPath.invoke(storageVolumeElement);
boolean mRemovable = (Boolean) isRemovable.invoke(storageVolumeElement);
if (removable == mRemovable) {
return path;
}
}
} catch (Exception e) {
return null;
}
return null;
}
After a lot of research I found ABSOLUTE SOLUTION. IT WORKS.
public boolean checkStorage() {
File[] fs = con.getExternalFilesDirs(null);
if (fs.length == 2)
return true;
else
return false;
}

Not able to create the folder in external storage in marshmallow version

when I try to run this code in marshmallow the folder was not created..
the code is,I tried to run the same code its working fine except marshmallow
File folder = new File(Environment.getExternalStorageDirectory() + "/abcdefg");
boolean success = false;
if (!folder.exists()) {
success = folder.mkdir();
}
if (!success) {
Log.d("", "Folder not created.");
} else {
Log.d("", "Folder created!");
}
Try to add below code in your activity for requesting runtime permission.
Your need to require READ_EXTERNAL_STORAGE permission to create folder(directory) in external storage.
if (ActivityCompat.checkSelfPermission(YourActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_FOR_STORAGE);//REQUEST_FOR_STORAGE=1111
} else {
//Do your stuff here
}
...
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(requestCode == REQUEST_FOR_STORAGE){
//Do your stuff here
}
}
Hope its help you.
As marshmallow introduce Run time Permission you have to check for the permission
in run time. You can refer here
1.https://developer.android.com/training/permissions/requesting.html
2.https://www.youtube.com/watch?v=iZqDdvhTZj0
3.https://www.youtube.com/watch?v=C8lUdPVSzDk
You have to accept the STORAGE permission group from the user dynamically.
Go with the below link
http://developer.android.com/guide/topics/security/permissions.html

Can't write to external storage unless app is restarted after granting permission

App unable to write to external storage on Android 6.0 (I'm testing on emulator), even after WRITE_EXTERNAL_STORAGE has been granted at runtime; unless the app is killed and restarted.
Snippet from AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
build.gradle
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
......
minSdkVersion 15
targetSdkVersion 23
}
Whenever I need to write to external storage (for backup) I check whether or not I have permission.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
getActivity().getBaseContext().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_RW_EXTERNAL_STORAGE);
mPendingAction = PendingAction.Backup;
} else {
BackupRestoreService.startBackup(getActivity().getBaseContext());
}
I also have the following
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
Log.d("SettingsActivity", "grantResultsLength: " + grantResults.length);
if (requestCode == PERMISSION_REQUEST_RW_EXTERNAL_STORAGE) {
Log.d("SettingsActivity", "grantResultsLength: " + grantResults.length);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
switch (mPendingAction) {
case Backup:
BackupRestoreService.startBackup(getActivity().getBaseContext());
mPendingAction = PendingAction.None;
break;
case Restore:
break;
default:
}
} else {
Toast.makeText(getActivity(),
"Permission denied",
Toast.LENGTH_SHORT).show();
}
}
}
When the permission is granted by user, the following code
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), DIR_MY_PORTFOLIO);
if (!file.mkdirs())
Log.d("Backup", "Unable to create directories");
final String outputFilename = new SimpleDateFormat("'Backup'-yyyyMMdd-hhmmss'.mpb'", Locale.US).format(new Date());
File outputFile = new File(getBackupStorageDir(), outputFilename);
Log.d("Backup", "Can write to file: " + outputFile.canWrite());
Log.d("Backup", "File exists: " + outputFile.exists());
produces
in.whoopee.myportfolio D/Backup: Unable to create directories
in.whoopee.myportfolio D/Backup: Can write to file: false
in.whoopee.myportfolio D/Backup: File exists: false
in.whoopee.myportfolio W/System.err: java.io.FileNotFoundException: /storage/09FD-2F0C/Download/My Portfolio/Backup-20151011-051318.mpb: open failed: EACCES (Permission denied)
If, after the permission is granted, the app is killed and restarted, everything goes perfect and backup file is created in external storage.
Please suggest what I am doing wrong.
Add the following line in onRequestPermissionsResult() method after checking permission grant successfully.
android.os.Process.killProcess(android.os.Process.myPid());
Edit: Check you have set the target sdk version to 23.if You already have done that and it is not working(or you don't want to set it to 23) than you may go with this solution(killing the app process).
Try to emulate a new device (for example a 6.0 x86_64 with Google api's). I had the exact same problem and i resolved it by running on a different emulator.

Categories

Resources