问题描述
最近在开发鸿蒙单框架的应用,要跨进程分享图片,图片已经保存到应用1的沙箱目录下,并将路径分享给应用2,但应用2仍旧取读不到图片,显示权限失败。记录下此开发过程中的采坑过程。
方法尝试
方法一:公共目录
因为只是做demo,本来是想将图片保存到共有目录下即可,让hdc和应用均可以访问,比如/data/local/tmp目录,但是单框架应用暂时没有此目录,此方法不可行。
方法二:调用linux命令,直接mv文件到可读目录。
因为单框架的应用进程只能把文件保存在自己的沙箱目录下,所以想着调取linux命令手动拷贝文件到应用2的沙箱目录下。
1)arkts尝试调用shell命令
不可行,arkts虽然有executeShellCommand,可以执行shell命令,但是只能测试框架使用。
2)c++调用linux指令。
手写个用于拷贝文件的可执行文件,然后放在/system/bin目录下,给予s权限,在应用1的native层去调用(操作的具体步骤如下)。此方法也失败了,虽然日志显示执行成功,但不知道为什么拷贝动作没有生效
步骤:
- c++写可执行文件,给与s权限运行
1)cmake选项设置
-DCMAKE_TOOLCHAIN_FILE=“xxx\SDK\HarmonyOS-NEXT-DB1\base\native\build\cmake\ohos.toolchain.cmake”
-DOHOS_STL=c++_static
-DOHOS_ARCH=arm64-v8a
-DCMAKE_SYSTEM_NAME=OHOS
-B D:\ohos_clion\out\cmake-build-debug
-G Ninja - 可执行文件的拷贝代码
#include <iostream>
#include <fstream>
#include <iostream>
/**
* 拷贝文件
* @param src 原文件
* @param des 目标文件
* @return ture 拷贝成功, false 拷贝失败
*/
bool CopyFile(const char *src, const char *des)
{
FILE * fSrc = fopen(src, "rb");
if(!fSrc)
{
printf("打开文件`%s`失败", src);
return false;
}
FILE * fDes = fopen(des, "wb");
if(!fDes)
{
printf("创建文件`%s`失败", des);
return false;
}
unsigned char * buf;
unsigned int length;
fseek(fSrc, 0, SEEK_END);
length = ftell(fSrc);
buf = new unsigned char[length+1];
memset(buf, 0, length+1);
fseek(fSrc, 0, SEEK_SET);
fread(buf, length, 1, fSrc);
fwrite(buf, length, 1, fDes);
fclose(fSrc);
fclose(fDes);
delete [] buf;
return true;
}
int main() {
//这里需写实际目录,而非沙箱目录
std::string src = "/data/app/el1/100/base/com.huawei.hmos.xxx1/AOD_IMAGE.png";
std::string dest = "/data/app/el2/100/base/com.example.xxx2/files/AOD_IMAGE.png";
bool result = CopyFile(src.c_str(), dest.c_str());
if(result)
printf("Command executed sucessfully!");
else
printf("Command failed!");
return 0;
}
-
将生成的文件放在手机的/system/bin目录下。
hdc shell mount -o rw,remount /
hdc file send D:\codeTest\copyImageFile\cmake-build-debug\copyImageFile.exe /system/bin/
hdc shell chmod 777 -R /system/bin/copyImageFile
hdc shell chmod u+s /system/bin/copyImageFile //给文件设置s权限
hdc shell copyImageFile -
native层的调用代码如下
std::string command = "/system/bin/copyImageFile";
int result = system(command.c_str());
if (result == 0) {
TAG_LOGE(AceLogTag::ACE_TEXT, "Command executed sucessfully!");
} else {
TAG_LOGE(AceLogTag::ACE_TEXT, "Command failed!");
}
方法三 应用文件共享
参考openharmony文档的应用文件共享,我一开始也是用的此方法,但是demo2取读demo1共享过来的文件路径时,一直显示没有权限,以为需要申请什么权限,后来发现把selinux关闭即可。