lundi 18 juin 2018

Permission declared in Android instrumental test manifest can't be granted

I'm automating UI in androd and have faced with the next problem: I have Android Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="ru.me.widgets"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.INTERNET"/>

    ...

</manifest>

And Android Test Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest package="ru.me.widgets.test"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round">
    </application>
</manifest>

I have saveScreenshot method that uses external memory:

protected final void saveScreenshot() {

    Bitmap bitmap = InstrumentationRegistry.getInstrumentation().getUiAutomation().takeScreenshot();

    File screenshotFile = getScreenshotFile();

    try (FileOutputStream outputStream = new FileOutputStream(screenshotFile)) {
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
        Log.i(mTag, "Saved screenshot: " + screenshotFile.getAbsolutePath());
    } catch (IOException e) {
        Log.e(mTag, "Could not save screenshot", e);
    }
}

private File getScreenshotFile() {

    String path = isExternalWritable(InstrumentationRegistry.getContext())
            ? Environment.getExternalStorageDirectory().toString()
            : Environment.getDataDirectory().toString();

    Date thisMoment = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
    String filename = "screen-" + mTag + "-" + sdf.format(thisMoment) + SCREENSHOT_EXTENSION;

    return new File(path + "/" + filename);
}

private boolean isExternalWritable(Context context) {

    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
        if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == 0) {
            return true;
        }

        Log.i(mTag, "No rights for writing to external storage!");
        return false;
    }

    else if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
        Log.i(mTag, "External storage is in ONLY_READ mode!");
        return false;
    }

    Log.i(mTag, "External storage is not mounted!");
    return false;
}

After installing application I run UI-tests and I can find extra application for tests in device settings. I grant permissions for EXTERNAL_WRITE, but still get error:

06-18 12:22:19.998 5566-5582/ru.me.widgets I/DemoActivityTest: No rights for writing to external storage!
06-18 12:22:20.001 5566-5582/ru.me.widgets E/DemoActivityTest: Could not save screenshot
    java.io.FileNotFoundException: /data/screen-DemoActivityTest-2018-06-18_12:22:19.png (Permission denied)

How can I save screenshot in my UI-tests? Why after granting permission for external write in settings "Permission denied" error occures? If I set sharedUserId in manifest, all works, but I think that this is a wrong way of solving problem.

Also, in future, I will need to grant permissions automatically, using GrandPermissionRule. But it works only if I set permission in App Manifest, not in Android Test Manifest.

Aucun commentaire:

Enregistrer un commentaire