FileNotFoundException при насмешливом результате намерения камеры - PullRequest
0 голосов
/ 16 января 2019

Я пытаюсь улучшить интеграционный тест, который запускает приложение камеры.Тем не менее, я перехватываю намерение и хочу использовать фиктивное изображение в интеграционном тесте.

Поэтому у меня есть этот код в моем тесте (соответствующая часть):

@Test
public void runCameraTest() {
//...
IntentCallback intentCallback = intent -> {
            if (intent.getAction() != null && intent.getAction().equals("android.media.action.IMAGE_CAPTURE")) {
                try {
                    Uri imageUri = intent.getParcelableExtra(MediaStore.EXTRA_OUTPUT);
                    Log.d(TAG, "runCameraTest: imageUri: "+imageUri);
                    Context context = InstrumentationRegistry.getTargetContext();
                    Bitmap icon = BitmapFactory.decodeResource(
                            context.getResources(),
                            R.drawable.example_photo);
                    OutputStream out = InstrumentationRegistry.getTargetContext().getContentResolver().openOutputStream(imageUri);
                    icon.compress(Bitmap.CompressFormat.JPEG, 100, out);
                    out.flush();
                    out.close();
                } catch (IOException e) {
                    Log.e(TAG,"runCameraTest-Exception: " + e.getMessage(),e);
                }
            }
        };

        IntentMonitorRegistry.getInstance().addIntentCallback(intentCallback);

        Intents.intending(IntentMatchers.hasAction(MediaStore.ACTION_IMAGE_CAPTURE)).respondWith(
                new Instrumentation.ActivityResult(Activity.RESULT_OK, null));

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        cameraView.perform(click());

        Intents.release();

        Intents.init();
//...
}

Инамерение камеры строится с использованием следующего метода (не уверен, что нам нужны все предложения SDK if, это было написано другим разработчиком):

private Intent getCameraIntent() {
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {

            try {
                mTempImageFile = File.createTempFile(
                        TEMP_CAMERA_IMAGE_FILE_NAME,  /* prefix */
                        "." + TEMP_CAMERA_IMAGE_FILE_EXT,         /* suffix */
                        getCurrentContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES)      /* directory */
                );
            } catch (IOException ex) {
                // Error occurred while creating the File
                Crashlytics.logException(ex);
            }
            // Continue only if the File was successfully created
            if (mTempImageFile != null) {
                mTempImageUri = FileProvider.getUriForFile(getCurrentContext(),
                        getCurrentContext().getString(R.string.content_provider),
                        mTempImageFile);
            }

        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            ContentValues values = new ContentValues(1);
            values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpg");
            mTempImageUri = getCurrentContext().getContentResolver()
                    .insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        } else {
            File outputFile = new File(getStoragePath()
                    + File.separator + TEMP_CAMERA_IMAGE_FILE);

            mTempImageUri = Uri.fromFile(outputFile);
        }

        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mTempImageUri);
        return cameraIntent;
    }

Я запускаю этот тест в Amazon Device Farm, и это работаетдля некоторых устройств (Android 7, 8 и 9), но он не работает в Samsung Galaxy S6 (Android 6.0.1) и Samsung Galaxy Tab 4 (Android 4.4.2).

Ошибка: java.io.FileNotFoundException: No such file or directory в строке OutputStream out = InstrumentationRegistry.getTargetContext().getContentResolver().openOutputStream(imageUri);

Журнал показывает, что imageUri это content://media/external/images/media/8244

Кто-нибудь имеет представление о том, чтоможет быть проблема?Может ли это быть связано с тем, что на устройстве нет SD-карты?(не уверен, что это так)

1 Ответ

0 голосов
/ 16 января 2019

> = уровень API N, вам обычно приходится использовать FileProvider для разрешения Uri:

Uri uri = FileProvider.getUriForFile(context, "com.acme.fileprovider", outputFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);

когда <= API-уровень <code>M завершается ошибкой, это означает, что ветви elseif и else не могут разрешить Uri.

Отладка на локальных эмуляторах может быть полезна для определения, почему она не работает удаленно.

...