6

I''m developing my first Android application and I'v run into a problem while trying to create a directory to save recorded video files.

I have a method in my main activity buttonOnClickRecord that invokes an intent to use the android camera, I'm also creating a file during this method call and I'm calling the mkdirs() method on it to create the directory to store the file.

I have also implemented <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> in my Manifest.

public void buttonOnClickRecord(View v){
        mediaFile =
                new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                        + "/NewDirectory/myvideo.mp4");
        mediaFile.mkdirs();

        Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
        if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {

            Uri videoUri = Uri.fromFile(mediaFile);
            takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri);
            startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE);
        }
    }

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_VIDEO_CAPTURE && resultCode == RESULT_OK) {

            Toast.makeText(this, "Video saved to:\n" +
                    data.getData(), Toast.LENGTH_LONG).show();
        } else if (resultCode == RESULT_CANCELED) {


  Toast.makeText(this, "Video recording cancelled.",
                Toast.LENGTH_LONG).show();
    } else {
        Toast.makeText(this, "Failed to record video",
                Toast.LENGTH_LONG).show();
    }
}

if I remove the /NewDirectory/ the video file is saved to the root of the sd card and I get a message to that affect from my onActivityResult method.

But with the /NewDirectory/ added I get video saved to: content:://media/external/video/media/15625

the mediaFile.mkdirs(); is not creating the directory.

Where have I gone wrong?

JTK
  • 1,359
  • 2
  • 18
  • 37
  • 1
    Apart from that `are trying to create a directory called myvideo.mp4` as mentioned before you are not checking the return value of mkdirs(). And you should firast check if the directory exists and only call mkdirs if not. You should also use File.canWrite() on that directory. Do not continue with your code when tjhe directory cannot be created or is not writable. – greenapps Mar 31 '15 at 14:34

2 Answers2

7

You are trying to create a directory called myvideo.mp4.

mediaFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                        + "/NewDirectory/myvideo.mp4");
mediaFile.mkdirs();

should be

File(Environment.getExternalStorageDirectory(), "NewDirectory");
mediaFile.mkdirs();

or better

mediaFile = new File(getExternalCacheDir(), "NewDirectory");
mediaFile.mkdirs();

Here you can find the documentation for getExternalCacheDir()

Be aware the from kitkat writing on the root of the sdcard is not allowed anymore.

Edit: the path to the file should be:

mediaFile = new File(getExternalCacheDir(), "NewDirectory");
File file = new File(mediaFile, "myvideo.mp4");
Uri videoUri = Uri.fromFile(file);
Blackbelt
  • 148,780
  • 26
  • 271
  • 285
  • Where should I write my files to instead? – JTK Mar 31 '15 at 14:18
  • What do you mean by that last comment? – weston Mar 31 '15 at 14:18
  • 2
    @weston, officially apps have not the permission to write on the `sdcard` root anymore. They can still have the possibility to write in `/sdcard/Android/data/app.packagename`. Some vendors are not enforcing this limitation – Blackbelt Mar 31 '15 at 14:21
  • @Johntk `Context` has a method to access `/sdcard/Android/data/app.packagename`. Your app should write there. Take a look to `getExternalCacheDir` – Blackbelt Mar 31 '15 at 14:22
  • OK, but you will still be able to request a location using `getExternalStorageDirectory` and write to it yes? It's never been guaranteed to be the sd card AFAIK. – weston Mar 31 '15 at 14:23
  • Oh you mean sd-card root, I just noticed that in your second comment. – weston Mar 31 '15 at 14:26
  • @weston yep I mean on the root. – Blackbelt Mar 31 '15 at 14:27
  • So what if it makes sense to want to write to DCIM, like for pics or video that's still allowed right? It wouldn't make sense for this app presumably to write to `/sdcard/Android/data/app.packagename` – weston Mar 31 '15 at 14:29
  • 2
    @weston, DCIM is accessible trough the context. Tbh I don't remember exactly which method returns the path to DCIM. Some thing for Download and some other directories – Blackbelt Mar 31 '15 at 14:34
  • @Blackbelt is weston right, is it better for me to write to DCIM? they will be video files, but they will only be stored on the phone for a short time before they are uploaded to a mySQL DB. – JTK Mar 31 '15 at 14:36
  • 1
    @Johntk if it's only temporary it makes sense to write to a cache area. The key difference is "these files will be deleted when the application is uninstalled" where as DCIM would be for pics/vids you would expect to keep after uninstall. – weston Mar 31 '15 at 14:55
  • @Johntk why would you write the video into a mySQL DB ? – Blackbelt Mar 31 '15 at 14:56
  • @ Blackbelt I wont It will be on a server with a pointer to it stored in the DB, i haven't got to that part yet, I'm not exactly sure how to implement it, but I'll cross that bridge when i come to it. – JTK Mar 31 '15 at 15:03
  • @Blackbelt, I've used your `getExternalCacheDir()` solution and it's created the directory for me, but not saving the file to it, I've tried a few things to get it to work, can I not just concatenate `+ mediaFile.mp4`? – JTK Mar 31 '15 at 15:30
  • @Blackbelt, perfect, you're a gent. – JTK Mar 31 '15 at 15:37
2

For create the directory use:

String rootDirectory = Environment.getExternalStorageDirectory().toString();
File myDir = new File(rootDirectory + "/NewDirectory");
myDir.mkdir();

You can save the file with:

recorder.setOutputFile(Environment.getExternalStorageDirectory().toString() + "/NewDirectory/" +fileName);

For find the video for share or reproduce:

File sdcard = Environment.getExternalStorageDirectory();
File directory = new File(sdcard.getAbsolutePath() + "/NewDirectory");
File video = new File(directory, fileName);
max
  • 5,014
  • 11
  • 37
  • 66
Santiago
  • 1,474
  • 13
  • 23
  • 1
    this worked for me. considerations regarding restrictions to write operations in certain folders depend on Android version (from kitKat 4.4 onwards they are significant). – tony gil Apr 27 '16 at 12:49