【问题标题】:cause = {ErrnoException@5190} "android.system.ErrnoException: open failed: EACCES (Permission denied)"原因 = {ErrnoException@5190} “android.system.ErrnoException:打开失败:EACCES(权限被拒绝)”
【发布时间】:2016-07-10 17:34:49
【问题描述】:

我是测试团队的一员,正在探索使用 espresso 测试我们的 Android 应用程序的测试记录器。

计划在 AWS Device Farm 上运行测试。

按照他们的 3 部分教程 @http://mobile.awsblog.com/post/Tx20RGXMTYT2ZGZ%20/Getting-started-with-Android-testing-on-AWS-Device-Farm-using-Espresso-Part-3

但是我被卡住了,因为我无法获取测试的屏幕截图。 将此配置作为 androidmanifest.xml 的一部分

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

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

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

我正在使用下面链接中的源代码来获取屏幕截图

https://github.com/awslabs/aws-device-farm-sample-app-for-android/tree/master/app/src/androidTest/java/com/amazonaws/devicefarm/android/referenceapp/Util

但是,我在运行测试时仍然被拒绝。

使用模拟器运行这些测试, 从 Nexus 5 (API 23) 和 Nexus 6 (API 23) 开始

【问题讨论】:

    标签: android android-testing permission-denied android-espresso aws-device-farm


    【解决方案1】:

    当权限弹出窗口出现在测试环境中时,您将需要使用UIAutomator 框架按yes。以下sn-p取自this medium post,请务必查看。

    private void allowPermissionsIfNeeded()  {
        if (Build.VERSION.SDK_INT >= 23) {
            UiObject allowPermissions = mDevice.findObject(new UiSelector().text("Allow"));
            if (allowPermissions.exists()) {
                try {
                    allowPermissions.click();
                } catch (UiObjectNotFoundException e) {
                    Timber.e(e, "There is no permissions dialog to interact with ");
                }
            }
        }
    }
    

    您可能需要在运行时请求权限,因为您在使用 API 23 的 Android 设备上运行它。

    查看this link 以查看有关如何操作的完整文档。


    以下是一个小示例,展示了如何请求权限以读取设备中的通话记录。您必须稍微更改逻辑以请求 WRITE_EXTERNAL_STORAGE 而不是 READ_CALL_LOG 权限。

    public class MainActivity extends AppCompatActivity {
    
        private static final String TAG = "MainActivityTAG_";
    
        private static final int CODE_CALL_LOG = 10;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CALL_LOG)) {
                    Log.d(TAG, "onCreate: " + "Show explanation");
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CALL_LOG}, CODE_CALL_LOG);
                } else {
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_CALL_LOG}, CODE_CALL_LOG);
                }
            } else {
                Log.d(TAG, "onCreate: " + "Permission already granted!");
                printCallLog();
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
            switch (requestCode) {
                case CODE_CALL_LOG: {
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        Log.d(TAG, "onRequestPermissionsResult: Good to go!");
                        printCallLog();
                    } else {
                        Log.d(TAG, "onRequestPermissionsResult: Bad user");
                    }
                }
            }
        }
    
        private void printCallLog() {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) == PackageManager.PERMISSION_GRANTED) {
                Cursor cursor = getContentResolver().query(CallLog.Calls.CONTENT_URI,
                        null,
                        null,
                        null,
                        null);
    
                while (cursor.moveToNext()) {
                    final long dateDialed = cursor.getLong(cursor.getColumnIndex(CallLog.Calls.DATE));
                    final String numberDialed = cursor.getString(cursor.getColumnIndex(CallLog.Calls.NUMBER));
                    Log.d(TAG, "Call to number: " + numberDialed + "\t registered at: " + new Date(dateDialed).toString());
                }
    
                cursor.close();
            }
        }
    }
    

    This is the link 包含完整的 GitHub 项目。

    【讨论】:

    • 这是否显示一个弹出窗口来授予或拒绝该操作?就我而言,访问该文件夹仅用于测试,并且将在设备场上运行。我从这里的这个 SO 问题中尝试了这个@stackoverflow.com/questions/8854359/… 但这对我也不起作用。
    • 是的,您还必须模拟点击弹出窗口,您可以使用 UI Automator。我用其他一些建议编辑了我的答案。 medium.com/exploring-android/…
    猜你喜欢
    • 2019-03-17
    • 2022-01-16
    • 1970-01-01
    • 2017-07-10
    • 2012-09-07
    • 2020-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多