0

I think that my smartphone is a dumbphone. Trying to create a folder and it seems that it just wont get created. I am running CyanogenMod and dont know if this make it goes nuts.

This is what I have been testing:

File folder = new File(getFilesDir() + "theFolder");
if(!folder.exists()){
folder.mkdir();
}

And also this approac:

File folder = getDir("theFolder",Context.MODE_PRIVATE);
codemoonger
  • 613
  • 3
  • 11
  • 22
  • "it seems that it just wont get created" -- how are you determining this? – CommonsWare Feb 17 '16 at 23:22
  • When I look file explorer the app itself dont have an own folder and my application is generating a pdf that it want to get from this folder but its saying that its not possible to add the file because it does not have premission – codemoonger Feb 17 '16 at 23:31
  • "When I look file explorer" -- unless your device is rooted, you cannot view internal storage on a device by any file explorer. My guess is that you are confused between what the Android SDK terms [internal storage](https://commonsware.com/blog/2014/04/07/storage-situation-internal-storage.html) and [external storage](https://commonsware.com/blog/2014/04/08/storage-situation-external-storage.html). – CommonsWare Feb 17 '16 at 23:36

2 Answers2

3

This answer was old and I updated it. I included internal and external storage. I will explain it step by step.

Step 1 ) You should declare appropriate Manifest.xml permissions; for our case these 2 is enough. Also this step required both pre 6.0 and after 6.0 versions :

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Step 2 ) In this step we will check permission for writing external storage then will do whatever we want.

public static int STORAGE_WRITE_PERMISSION_BITMAP_SHARE =0x1;

public Uri saveBitmapToFileForShare(File file,Uri uri){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
    && ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            != PackageManager.PERMISSION_GRANTED) {

//in this side of if we don't have permission 
//so we can't do anything. just returning null and waiting user action

    requestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE,
   "permission required for writing external storage bla bla ..."
                REQUEST_STORAGE_WRITE_ACCESS_PERMISSION);
        return null;
    }else{
        //we have right about using external storage. do whatever u want.
        Uri returnUri=null;
        try{
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver() ,uri);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream);
            fileOutputStream.flush();
            fileOutputStream.close();
            returnUri=Uri.fromFile(file);
        }
        catch (IOException e){
            //can handle for io exceptions
        }

        return returnUri;
    }

}

Step 3 ) Handling permission rationale and showing dialog, please read comments for info

/**
 * Requests given permission.
 * If the permission has been denied previously, a Dialog will prompt the user to grant the
 * permission, otherwise it is requested directly.
 */
protected void requestPermission(final String permission, String rationale, final int requestCode) {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) {
        showAlertDialog("Permission required", rationale,
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions(BasePermissionActivity.this,
                                new String[]{permission}, requestCode);
                    }
                }, getString(android.R.string.ok), null, getString(android.R.string.cancel));
    } else {
        ActivityCompat.requestPermissions(this, new String[]{permission}, requestCode);
    }
}

/**
 * This method shows dialog with given title & content.
 * Also there is an option to pass onClickListener for positive & negative button.
 *
 * @param title                         - dialog title
 * @param message                       - dialog content
 * @param onPositiveButtonClickListener - listener for positive button
 * @param positiveText                  - positive button text
 * @param onNegativeButtonClickListener - listener for negative button
 * @param negativeText                  - negative button text
 */
protected void showAlertDialog(@Nullable String title, @Nullable String message,
                               @Nullable DialogInterface.OnClickListener onPositiveButtonClickListener,
                               @NonNull String positiveText,
                               @Nullable DialogInterface.OnClickListener onNegativeButtonClickListener,
                               @NonNull String negativeText) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.setPositiveButton(positiveText, onPositiveButtonClickListener);
    builder.setNegativeButton(negativeText, onNegativeButtonClickListener);
    mAlertDialog = builder.show();
}

Step 4 ) Getting permission result in Activity :

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case STORAGE_WRITE_PERMISSION_BITMAP_SHARE:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                shareImage();
            }else if(grantResults[0]==PackageManager.PERMISSION_DENIED){
                //this toast is calling when user press cancel. You can also use this logic on alertdialog's cancel listener too.
                Toast.makeText(getApplicationContext(),"you denied permission but you need to give permission for sharing image. "),Toast.LENGTH_SHORT).show();
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

Step 5 ) In case of using internal storage. You don't need to check runtime permissions for using internal storage.

//this creates a png file in internal folder
//the directory is like : ......data/sketches/my_sketch_437657436.png
File mFileTemp = new File(getFilesDir() + File.separator
                + "sketches"
                , "my_sketch_"
                + System.currentTimeMillis() + ".png");
        mFileTemp.getParentFile().mkdirs();

You can read this page for information about runtime permissions : runtime permission requesting

My advice : You can create an Activity which responsible of this permissions like BasePermissionActivity and declare methods @Step 3 in it. Then you can extend it and call your request permission where you want.

Also I searched a bit and found the Github link of codes @Step 3 in case of you want to check : yalantis/ucrop/sample/BaseActivity.java

Yasin Kaçmaz
  • 6,573
  • 5
  • 40
  • 58
  • Thanks. I will test this – codemoonger Feb 18 '16 at 01:22
  • tell me result if not work i can give advices for you. – Yasin Kaçmaz Feb 18 '16 at 01:27
  • So now its working. Maybe a combo of your code and that for some reason I needed to allow app to use storage. Why is not the permission enough – codemoonger Feb 18 '16 at 13:35
  • Sorry i dont get it . Maybe explain a bit more. If you using Android 6.0 Marshmallow you must check permission , if no permission you must handle it and get permissions. I think this guide will help you : http://developer.android.com/training/permissions/requesting.html – Yasin Kaçmaz Feb 18 '16 at 13:42
  • The application is made for 5.1 but runs now on 6.0. Is it possible to make the permission check with code – codemoonger Feb 18 '16 at 13:46
  • In android 6.0 android has changed permissions. You will find explaination on link . Of course you can check. – Yasin Kaçmaz Feb 18 '16 at 13:59
  • I think this answer is for external storage but the question is about internal storage. – Yirga Mar 30 '17 at 07:42
  • 1
    @Yirga yes but strategy is same. I mentioned manifest permissions and runtime permissions and showed a working code piece. With a small search he can do whatever he wants. – Yasin Kaçmaz Mar 30 '17 at 10:54
  • Ok i want to create folder in android internal storage like this File file= context.getDir("nameOfTheFile",Context.MODE_PRIVATE); do you think this going to work – Yirga Mar 30 '17 at 11:31
  • 1
    @Yirga I've edited my answer including permissions for external and internal storage. Please check it. If you have problems please let me know. – Yasin Kaçmaz Mar 30 '17 at 13:59
  • 1
    @YasinKaçmaz thank you i really appreciate your help! – Yirga Mar 30 '17 at 18:04
1

You forgot to add the "/" before adding the file name so your path is compiled like this:

/data/data/com.myPackageNametheFolder

File folder = new File(getFilesDir() + "/" + "theFolder");

OR

File folder = new File(getFilesDir(),"theFolder");

You'll get this instead

/data/data/com.myPackageName/theFolder

PS : There is no dumb phone all phones are Smart Phones 'Bad dum tss'

Boukharist
  • 1,219
  • 11
  • 19
  • Have added "/" and I still dont get any folder that name is "theFolder" – codemoonger Feb 17 '16 at 23:38
  • It is there but you can't see it, it's only readable by your application. You can check it by logging the result of `file.exists()`. In order to see your files you need to copy them to your external storage programatically. – Boukharist Feb 18 '16 at 00:05
  • Yes I have try this to. And the strange thing is that I still dont get any visible files or folders. Have added permission in the manifest also. – codemoonger Feb 18 '16 at 00:09
  • This is me try to use External Storage, it was working in earliner versions, (kitkat), http://pastebin.com/fWwHvYHC – codemoonger Feb 18 '16 at 00:17
  • After you created the File object, you also need to call `folder.mkdir()`. This will create the folder within /data/data/com.myPackageName/file/ – Franklin84 Dec 26 '20 at 11:45