Skip to content

Latest commit

 

History

History

safs-android

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

safs-android

Download

Known limitations

There's sadly some Android issues which can't be worked around:

See safs-android-app for integration tests.

Getting started

Add to Gradle project dependencies:

implementation 'com.llamalab.safs:safs-android:0.2.0'

Add to AndroidManifest.xml:

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

Add to proguard-rules.pro:

-keep class com.llamalab.safs.spi.FileSystemProvider { *; }
-keep class * extends com.llamalab.safs.spi.FileSystemProvider { *; }
-keep class * extends com.llamalab.safs.spi.FileTypeDetector { *; }

Usage

Same as java.nio.file packages except located in com.llamalab.safs, and instead of java.nio.channels.SeekableByteChannel use com.llamalab.safs.channels.SeekableByteChannel.

In addition to the standard Files there's com.llamalab.safs.android.AndroidFiles with some convenience methods, and com.llamalab.safs.android.AndroidWatchEventKinds with Android specific WatchEvent.Kind.

Before use, safs-android need to be told to use the com.llamalab.safs.android.AndroidFileSystemProvider as default, otherwise it will use the safs-core provider. It also need a reference to a Context, assigned once, so it's easiest to do early in Application.

import com.llamalab.safs.FileSystems;
import com.llamalab.safs.android.AndroidFileSystem;

public class MyApplication extends Application {

  static {
    System.setProperty("com.llamalab.safs.spi.DefaultFileSystemProvider", AndroidFileSystemProvider.class.getName());
  }

  public void onCreate () {
    ((AndroidFileSystem)FileSystems.getDefault()).setContext(this);
    super.onCreate();
  }
}

Before accessing a secondary external storage volume, i.e. removable SD card, on Android 5.1+, the app has to be granted permission to it by the user, then safs-android has to be informed. That's done with a ACTION_OPEN_DOCUMENT_TREE intent.

public class MyActivity extends Activity {

  private static final int REQUEST_CODE_OPEN_DOCUMENT = 1;

  @Override
  protected void onCreate (Bundle state) {
    super.onCreate(state);
    // Ask user to grant permission to an storage volume, or subfolder thereof
    startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE), REQUEST_CODE_OPEN_DOCUMENT);
  }

  @Override
  protected void onActivityResult (int requestCode, int resultCode, Intent resultIntent) {
    if (REQUEST_CODE_OPEN_DOCUMENT != requestCode)
      super.onActivityResult(requestCode, resultCode, resultIntent);
    else if (RESULT_OK == resultCode) {
      // Take permission grant
      ((AndroidFileSystem)FileSystems.getDefault()).takePersistableUriPermission(resultIntent);
    }
  }
}