0

I'm struggling to find out what's going on with my code. This code snippet works on EVERY (apparently) phone, except motorola (Moto G, etc...):

private void createFolder(String folderPath) throws CantCreateFolderPathException {
    File folder = new File(folderPath);
    if (folder.mkdirs() || folder.isDirectory())
      return; //Everything ok! 

    throw new CantCreateFolderPathException(folderPath);
}

And I generate the folder path with this:

public String getFolderPath(Courseware courseware) {
    String path = getBestPath() + courseware.getSubject().getName() + File.separator;
    UnisantaApplication.Log_i("SAVE PATH:" + path);
    return path;
    //Result example: sd/unisantaapp/material/SUBJECT NAME/
}

private String getBestPath() {
    if (isExternalStorageWritable())
        return getExternalPath();
    return getInternalPath();
}

private String getExternalPath() {
    return Environment.getExternalStorageDirectory()
            .getAbsolutePath() + File.separator +
            "unisantaapp" + File.separator +
            "material" + File.separator;
}

private String getInternalPath() {
    return UnisantaApplication.getInstance().getApplicationContext()
            .getFilesDir().getAbsolutePath() + File.separator +
            "material" + File.separator;
}

folder.mkdirs keeps returning false, which causes CantCreateFolderPathException to be thrown. AGAIN, it works on all other phones that I've tested, so probably it's not a permission manifest missing:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="si.unisanta.tcc.unisantaapp" >

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

<application
      [...]

I asked for help from a friend of mine, since I don't have a motorola. I created a APK with some dialogs to help me understand the error, my steps were:

  1. Find out which path is the "best one" generated from my code: getBestPath returns ExternalStorageDirectory, but mkdirs keeps returning false

  2. Tried to change getBestPath to always returns internal path, then mkdirs returned true! At this path:

    Internal path returned (Note: Caminho: means Path:)

    But my friend claims that he can't open the file nor find it with another third-party file explorer. When he tries to open a PDF, it says:"Impossible to view PDF" and the file explorer says: "superuser not available".

  3. Frustrated with no clue of what's happening, I took a step back reverting my getBestPath method to work as expected and changed the call for folder.mkdirs() to Files.createParentDirs(folder) hoping for some more descriptive error, but instead I just received a simple:

    createParentDirs result

Well, why I can't create folder/file and open it JUST IN MOTOROLA PHONES? Anyone here already faced this? Any clues of what I'm doing wrong?

Latrova
  • 468
  • 6
  • 15
  • 1
    "But my friend claims that he can't open the file nor find it with another third-party file explorer" -- that is how [internal storage](https://commonsware.com/blog/2014/04/07/storage-situation-internal-storage.html) works. " When he tries to open a PDF, it says:"Impossible to view PDF"" -- third-party apps have no direct filesystem access to your app's internal storage. "Any clues of what I'm doing wrong?" -- you are pasting in images of dialogs, rather than Java stack traces for the exceptions that you are encountering. – CommonsWare Jul 01 '16 at 14:29
  • 1
    Also, perhaps your failing device happens to be the only Android 6.0 device that you are testing, in which case you should look into runtime permissions: https://stackoverflow.com/questions/32635704/android-permission-doesnt-work-even-if-i-have-declared-it – CommonsWare Jul 01 '16 at 14:31
  • @CommonsWare, I can't get him phone to debug locally, sorry for that :/ Therefore, `mkdirs` doesnt throw an exception, it just returns false. – Latrova Jul 01 '16 at 14:40
  • @CommonsWare I'll read this article and check this runtime permission stuff, after that I give you some feedback if it worked. – Latrova Jul 01 '16 at 14:48
  • You should edit your question, and fix the misleading title. I suggest something along "Cant create folders" – Bonatti Jul 05 '16 at 18:53
  • @Bonatti Agree with you. Done! (: – Latrova Jul 05 '16 at 19:27

1 Answers1

0

As @CommonsWare pointed, it's not a MOTOROLA issue, but an Android 6.0 one. I just added support to ask for permissions (runtime) and also read the article suggested (Great article, really worth it).

I just added the following in my activity:

private boolean hasPermissionToDownload() {
    int permissionResult = ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE);
    return permissionResult == PackageManager.PERMISSION_GRANTED;
}

private void explainOrAskPermission() {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        new AlertDialog.Builder(this)
            .setTitle(R.string.download_permission_explain_title)
            .setMessage(getString(R.string.download_permission_explain_message))
            .setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    askPermission();
                }
            })
            .show();
    }
    else {
        askPermission();
    }
}

private void askPermission() {
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
            PERMISSION_SAVE_DOWNLOAD_REQUEST);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    if (requestCode == PERMISSION_SAVE_DOWNLOAD_REQUEST) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            downloadCourseware(lastCoursewareClicked);
        }
        else {
            new AlertDialog.Builder(this)
                .setTitle(R.string.download_permission_denied_title)
                .setMessage(R.string.download_permission_denied_message)
                .setNeutralButton(R.string.ok, null)
                .show();
        }
    }
}
Latrova
  • 468
  • 6
  • 15