【问题标题】:Native Subprocess Can't Create File in Application Folder or on SDcard本机子进程无法在应用程序文件夹或 SD 卡上创建文件
【发布时间】:2011-07-24 01:31:39
【问题描述】:

由于这被证明是一个长篇阅读,我将从一个非常截断的版本开​​始:

无论是否拥有适当的位置/权限/文件所有权,是否都不允许本机进程创建/编辑由其产生的 java 进程创建的文件?

完整的问题:

我的应用程序由一组使用 NDK 工具链编译的本机二进制文件和一个典型的 java Android 界面组成。原生程序打包在 /assets 文件夹中,并由 java 应用程序复制到 /data/data/com.domain.app/nativeApplication 文件夹中。

有两个本机应用程序有问题。一个修改由 java 层创建的 jpeg,另一个分析该 jpeg 并返回一个 int 作为输出。问题是这样的:当被java层调用时,jpeg修饰符不起作用。

我已经对其进行了大量的故障排除,所以我会尽量劝阻你不要从一些明显的潜在答案开始,从最明显的开始。

正确编译: 通过 adb shell,我可以按原样从手机磁盘调用这两个程序。如果我从 adb 手动执行中间步骤,则通过 adb 或软件中的设计调用第二个图像分析器程序时运行顺利。

权限:

JPG 权限 - 应用程序有权写入外部存储。我试图从 SDcard 和 /data/data/com.domain.app/nativeApp/img/name.jpg 中读取文件;没有喜悦。如前所述,当图像位于任一位置时,第二个程序按设计运行,如果我通过 adb 手动运行第一个程序。

文件/文件夹权限:~/nativeApplication/* 中的所有文件夹都是由 android 应用程序本身创建的,它是所有者,它已将所有子目录和文件更改为 777。

支持代码:

调用jpg转换器进程:

NativeSetup.changePermission("/data/data/com.domain.program/nativeApp/img/img1.jpg");

try {    
            Process jpegConvert = Runtime.getRuntime().exec("/data/data/com.domain.program/nativeApp/bin/jpegtransformer -opts /data/data/com.domain.program/nativeApp/img/img1.jpg > /data/data/com.domain.program/nativeApp/img/img2.jpg");
            jpegConvert.waitFor();          
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

用于在 ~/nativeApp/* 中创建文件的调用

private static void copyFile(String assetPath, String localPath, Context context) {

    try {
        InputStream in = context.getAssets().open(assetPath);
        FileOutputStream out = new FileOutputStream(localPath);
        int read;
        byte[] buffer = new byte[4096];
        while ((read = in.read(buffer)) > 0) {
            out.write(buffer, 0, read);
        }

chmod 调用:(根据 ls -l 通过 adb 工作)

static void changePermission(String localPath) {

    try {
        Process chmod = Runtime.getRuntime().exec("/system/bin/chmod 777 " +localPath);
        chmod.waitFor();
    } catch (IOException e) {
        throw new RuntimeException(e);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
}
        out.close();
        in.close();


    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

程序无法编辑的文件的权限,然后输出更改后的副本:

~/nativeApp/img $ ls -l
-rwxrwxrwx app_89   app_89      93061 2011-07-23 18:38 img1.jpg

无法编辑以上jpg的应用权限:

~/nativeApp/bin $ ls -l jpegtransformer
-rwxrwxrwx app_89   app_89      95268 2011-07-23 18:01 jpegtransformer

~/nativeApp/ 中文件夹的权限 ~/nativeApp $ ls -l drwxrwxrwx app_89 app_89 2011-07-23 17:57 bin drwxrwxrwx app_89 app_89 2011-07-23 18:27 img

理论:

在这一点上,我唯一可行的理论是有一些不受 chmod 控制的 android 策略,它会阻止 jpegtransformer 在被 java 层调用时编辑图像。由于图像分析器不会改变图像,我想它会绕过这个?不允许本机进程创建文件吗?任何想法都会很棒。抱歉读了这么久。

-SS

【问题讨论】:

    标签: android permissions native android-ndk


    【解决方案1】:

    当您从应用生成进程时,它会在与您相同的 uid 下运行,因此所有相同的 Android 和文件系统权限都适用。我认为您需要寻找其他原因,例如使用不良路径。

    如果您想验证,只需使用“adb shell ps”查看正在运行的进程,您应该会看到您的进程与您的主应用程序具有相同的 uid。

    也就是说……Android 确实不支持这样的生成过程,强烈建议不要这样做。请考虑通过将本机代码加载为共享库并使用 JNI 调用它来执行此操作。这也将更加高效,并且与您的本机代码的通信可能更简单,因为 JNI 是一种更丰富、更直接的调用方式。

    【讨论】:

      【解决方案2】:

      我认为您的问题与权限无关 - 您尝试使用 > 重定向输出,而这是一个 shell 运算符并且不适用于 java。获取进程输出流并使用 Java 标准文件 I/O API 将其写入文件。

      虽然我不确定这是否是问题所在,但修改应用文件夹中的文件应该没有问题,而且我描述的问题是我不止一次遇到的问题。

      【讨论】:

      • 啊!对于我今天浪费在这个问题上的时间,我几乎希望这是一个更复杂的答案。但是,我很高兴地说 > 是问题所在。谢谢。
      • 很高兴能帮上忙 :)。说实话,一旦我在你的问题中观察到Runtime.getRuntime().exec,我就直接去了。糟糕的经历最终会付出代价......
      猜你喜欢
      • 2018-05-18
      • 1970-01-01
      • 2012-10-02
      • 1970-01-01
      • 2012-09-20
      • 1970-01-01
      • 1970-01-01
      • 2016-04-18
      相关资源
      最近更新 更多