gpt4 book ai didi

java - 在 AndroidTest 中编写外部存储

转载 作者:塔克拉玛干 更新时间:2023-11-02 22:35:01 26 4
gpt4 key购买 nike

我想为一个涉及写入外部存储的应用程序编写一个 AndroidTest,但不知何故我无法使其工作。 (在Pixel2、Lg G6、Huawai P8等多款设备上测试)

所以我简化了一切,只是为了测试是否可以写入外部存储。我试验了 GrantPermissionRule以及在 Granter 上写我的文章,但完全没有成功。

我可能最终做了太多不必要的事情,所以这是我所做的:

  1. AndroidStudio 中创建没有 Activity 的新项目>
  2. 添加对 list 的权限
  3. 添加了带有uses-permission标签的AndroidManifest
  4. 写了我自己的PermissionRequester
  5. 编写测试以尝试在/sdcard/Download 中添加一个文件夹并将其删除

以下是上面编号列表引用的 fragment

2.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.company.android.testpermissions">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="com.company.TestPermissions"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme" />
</manifest>

3.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.company.android.testpermissions.test">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

</manifest>

也试过

<manifest package="com.company.android.testpermissions">...

省略 'test' 后缀

4.

public class MyPermissionRequester {

public static final String TAG = MyPermissionRequester.class.getSimpleName();

public static void request(String... permissions) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
UiAutomation auto = InstrumentationRegistry.getInstrumentation().getUiAutomation();
String cmd = "pm grant " + InstrumentationRegistry.getTargetContext().getPackageName() + " %1$s";
String cmdTest = "pm grant " + InstrumentationRegistry.getContext().getPackageName() + " %1$s";
String currCmd;
for (String perm : permissions) {
execute(String.format(cmd, perm), auto);
execute(String.format(cmdTest, perm), auto);
}
}
GrantPermissionRule.grant(permissions);
}

private static void execute(String currCmd, UiAutomation auto){
Log.d(TAG, "exec cmd: " + currCmd);
auto.executeShellCommand(currCmd);
}
}

5.

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void sdcardTest(){

//check sdcard availability
Assert.assertEquals("Media is not mounted!", Environment.getExternalStorageState(), Environment.MEDIA_MOUNTED);
//get and check Permissions
MyPermissionRequester.request(Manifest.permission.WRITE_EXTERNAL_STORAGE);
int grantResult = ActivityCompat.checkSelfPermission(InstrumentationRegistry.getTargetContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
Assert.assertEquals(PackageManager.PERMISSION_GRANTED, grantResult);
grantResult = ActivityCompat.checkSelfPermission(InstrumentationRegistry.getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
Assert.assertEquals(PackageManager.PERMISSION_GRANTED, grantResult);

//finally try to create folder
File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "CompanyTest");
if (!f.exists()){
boolean mkdir = f.mkdirs();
Assert.assertTrue("Folder '"+f.getAbsolutePath() + "' not Present!", mkdir);
}
boolean delete = f.delete();
Assert.assertTrue("Folder '"+f.getAbsolutePath() + "' is Present!", delete);
}
}

测试的结果是:

junit.framework.AssertionFailedError: Folder ' /storage/emulated/0/Download/CompanyTest' not Present! at

junit.framework.Assert.fail(Assert.java:50) at

junit.framework.Assert.assertTrue(Assert.java:20) at

com.company.android.testpermissions.ExampleInstrumentedTest.sdcardTest(ExampleInstrumentedTest.java:69)

at java.lang.reflect.Method.invoke(Native Method) at ... (omitted rest coming from the TestRunner)

我在这里遗漏了什么或做错了什么?

最佳答案

经过大量痛苦尝试无效的东西后,我终于找到了解决方案:

谷歌声称

if your application already requests write access, it will automatically get read access as well.

https://developer.android.com/about/versions/android-4.1.html#Permissions

或在 WriteExternalStorage 文档中:

Note: If your app uses the WRITE_EXTERNAL_STORAGE permission, then it implicitly has permission to read the external storage as well.

https://developer.android.com/training/data-storage/files.html#WriteExternalStorage

或者在 list 权限中:

Any app that declares the WRITE_EXTERNAL_STORAGE permission is implicitly granted this permission.

https://developer.android.com/reference/android/Manifest.permission.html#READ_EXTERNAL_STORAGE

但事实并非如此!

如果我显式地将 READ_EXTERNAL_STORAGE 添加到我的 list 中并在运行时请求它,它会像我习惯的那样工作。

所以3.必须加上

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.company.android.testpermissions.test">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
</manifest>

测试应该是这样的:

@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void sdcardTest(){

//check sdcard availability
Assert.assertEquals("Media is not mounted!", Environment.getExternalStorageState(), Environment.MEDIA_MOUNTED);
//get and check Permissions
MyPermissionRequester.request(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE);
int grantResult = ActivityCompat.checkSelfPermission(InstrumentationRegistry.getTargetContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
Assert.assertEquals(PackageManager.PERMISSION_GRANTED, grantResult);
grantResult = ActivityCompat.checkSelfPermission(InstrumentationRegistry.getContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
Assert.assertEquals(PackageManager.PERMISSION_GRANTED, grantResult);

//finally try to create folder
File f = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "CompanyTest");
if (!f.exists()){
boolean mkdir = f.mkdirs();
Assert.assertTrue("Folder '"+f.getAbsolutePath() + "' not Present!", mkdir);
}
boolean delete = f.delete();
Assert.assertTrue("Folder '"+f.getAbsolutePath() + "' is Present!", delete);
}
}

一切正常。

唯一剩下的问题是这是否/为什么是自 Android 8.1 以来的预期行为

关于java - 在 AndroidTest 中编写外部存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49198675/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com