【问题标题】:Android - create symbolic link in the appAndroid - 在应用程序中创建符号链接
【发布时间】:2016-01-05 09:32:10
【问题描述】:

我想在我的应用程序中以编程方式创建符号链接。 Android (4.4+) 可以吗?

在 Java 中我们可以使用:

Path newLink = ...;
Path target = ...;
try {
    Files.createSymbolicLink(newLink, target);
} catch (IOException x) {
    System.err.println(x);
} catch (UnsupportedOperationException x) {
    // Some file systems do not support symbolic links.
    System.err.println(x);
}

来自java.nio.file,但我应该在 Android 中使用什么?

https://docs.oracle.com/javase/tutorial/essential/io/links.html

编辑:

我使用reflection/native code/OS.symlink() method 进行了测试,但没有任何效果。我总是得到 Operation not allowed (EPERM)。我认为您必须拥有创建符号链接的 root 权限。

问题可能在于/mnt/sdcard 是一个包裹/data/media/xxx 的保险丝垫片。所以我开始使用/data/media/xxx,但我总是得到Permission denied

我认为是root权限的问题。

【问题讨论】:

  • 我尝试了反射,但它不起作用:android.system.ErrnoException: symlink failed: EPERM (Operation not permitted)。我会试试原生代码。
  • 你试过stackoverflow.com/questions/27726428/…上的其他答案吗?? Os.symlink(originalFilePath,symLinkFilePath); ?
  • 我在 Android 4.4(API 级别 19)中也需要它。
  • 我也尝试过Os.symlink(originalFilePath,symLinkFilePath);,但我在三星 Galaxy S5 上又得到了symlink failed: EPERM (Operation not permitted)

标签: java android android-ndk filesystems symlink


【解决方案1】:

这是一个对我有用的解决方案,如果成功则返回 true:

public static boolean createSymLink(String symLinkFilePath, String originalFilePath) {
    try {
        if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
            Os.symlink(originalFilePath, symLinkFilePath);
            return true;
        }
        final Class<?> libcore = Class.forName("libcore.io.Libcore");
        final java.lang.reflect.Field fOs = libcore.getDeclaredField("os");
        fOs.setAccessible(true);
        final Object os = fOs.get(null);
        final java.lang.reflect.Method method = os.getClass().getMethod("symlink", String.class, String.class);
        method.invoke(os, originalFilePath, symLinkFilePath);
        return true;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

或者在 Kotlin 中:

companion object {
    @JvmStatic
    fun createSymLink(symLinkFilePath: String, originalFilePath: String): Boolean {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                Os.symlink(originalFilePath, symLinkFilePath)
                return true
            }
            val libcore = Class.forName("libcore.io.Libcore")
            val fOs = libcore.getDeclaredField("os")
            fOs.isAccessible = true
            val os = fOs.get(null)
            val method = os.javaClass.getMethod("symlink", String::class.java, String::class.java)
            method.invoke(os, originalFilePath, symLinkFilePath)
            return true
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return false
    }
}

【讨论】:

    【解决方案2】:

    现在 Android 提供了可以使用的系统调用。 这里是android.system.Os.symlink

    https://developer.android.com/reference/android/system/Os#symlink(java.lang.String,%20java.lang.String)

    还有 java.nio.file.Files.createSymbolicLink方法

    https://developer.android.com/reference/java/nio/file/Files#createSymbolicLink(java.nio.file.Path,%20java.nio.file.Path,%20java.nio.file.attribute.FileAttribute%3C?%3E...)

    但我猜这对你并没有真正的工作

    【讨论】:

      猜你喜欢
      • 2018-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多