Symbolic Link Creation in Android Within an Application's Asset Directory
Asked Answered
B

2

4

I can't seem to find a solid answer for this specific question.

I'm trying to create a symbolic link programmatically of a directory in my assets folder in another location within the same application's asset directory. Essentially, I'm looking to do the same thing as what the createSymbolicLink method of Java.nio.Files would do.

Is there an available way of doing this with the Android SDK? If not, is it possible in the NDK?

Balfour answered 31/12, 2014 at 21:23 Comment(1)
Are you referring to your "assets folder" on your development machine? Or are you referring to the assets when used at runtime? Please bear in mind that the assets packaged in your APK remain in the APK and are not unpacked, but are merely read out of the APK itself. Also note that an APK file is a ZIP archive, and AFAIK there is no symlink construct in ZIP archives.Boat
B
8

For Android API 21 and above, just use:

Os.symlink(originalFilePath,symLinkFilePath);
Burial answered 24/9, 2015 at 23:27 Comment(1)
For lower versions Runtime.getRuntime().exec("ln -s /path/to/file /path/to/symlink") from source.Fortuna
B
3

There is no public API to do this. You can however use some dirty reflection to create your symbolic link. I just tested the following code and it worked for me:

// static factory method to transfer a file from assets to package files directory
AssetUtils.transferAsset(this, "test.png");

// The file that was transferred
File file = new File(getFilesDir(), "test.png");
// The file that I want as my symlink
File symlink = new File(getFilesDir(), "symlink.png");

// do some dirty reflection to create the symbolic link
try {
    final Class<?> libcore = Class.forName("libcore.io.Libcore");
    final Field fOs = libcore.getDeclaredField("os");
    fOs.setAccessible(true);
    final Object os = fOs.get(null);
    final Method method = os.getClass().getMethod("symlink", String.class, String.class);
    method.invoke(os, file.getAbsolutePath(), symlink.getAbsolutePath());
} catch (Exception e) {
    // TODO handle the exception
}

A quick Google search showed this answer if you don't want to use reflection: http://androidwarzone.blogspot.com/2012/03/creating-symbolic-links-on-android-from.html

Borras answered 31/12, 2014 at 21:58 Comment(5)
Somehow I missed that link in my google searches. I'm already using some native code in this particular project, so that may serve my needs. Thanks.Balfour
This may be interesting for other purposes, but it doesn't actually address the question which was asked. Once you are copying the file from assets into an actual file-system file, what's the point of making a symlink rather than just giving the copy the desired name?Backflow
How come it accepts using only "getFilesDir" path for the symlinks files? I can't put it anywhere else but there. Not even in a sub-folder inside it (well it can create the file there, but it's not accessible for any other app).Burial
@androiddeveloper It is like any other unix-like system. The files you create have the same UID as your app. Other apps cannot access those files unless they have a shared UID. Also, creating symlinks on external storage is not permitted on Android.Borras
@JaredRummler The only path it works for both creating the symlink and sharing it is in the exact path of "getFilesDir". Why doesn't it work for other paths that are within this path (subfolders) ? Also, can I assume this method of creating symlinks work on all Android devices ? I've tested and it works on Android emulators since ICS (4.0.x) . Is there a more official way to do it? Would using the JNI option be safer? Sadly I never succeeded creating a library/project that uses JNI on Android-Studio.Burial

© 2022 - 2024 — McMap. All rights reserved.