Как отправить данные массива байтов в другие действия?

Я застрял на этой проблеме в течение нескольких дней. Если какой-нибудь небольшой комментарий поможет спасти одного программиста... У меня есть два действия A и B. Действие — это действие, которое вызывает действие B в startActivityForResult(). Действие B — это действие камеры, к которому добавлена ​​камера. И изображения, которые делает действие B, должны быть отправлены обратно в действие A.

Фотографии, которые я делаю, получены байт [] данные через PictureCallback. И вот проблема. Я ожидаю, что пользователь сделает как минимум 2-3 (или более) изображения, поэтому я попытался сделать эти массивы байтов формой списка.

  1. Список растровых изображений невозможен, потому что он вызывает ошибку НЕУДАЧНАЯ ТРАНЗАКЦИЯ BINDER, когда его размер превышает 40 КБ.

  2. ArrayList<байт[]> не является Parcelable, поэтому его невозможно добавить в данные Intent Extra.

  3. Я попытался сохранить каждый байт [] данных фотографий в намерение Extra с помощью цикла for. Но из-за (я думаю) проблемы с емкостью приложение обновляется после завершения действия B. (Это не ловится на logcat, потому что это не приводит к сбою приложения)

Я не включал никаких кодов, потому что думаю, что это не нужно. Если вам интересно, я сразу же покажу вам любые коды, которые вам нравятся.

Если бы какие-то лучшие способы или небольшие отзывы о моих испытаниях много значили бы для меня. И будьте ОЧЕНЬ благодарны. Спасибо за прочтение!

Деятельность

public class A_Activity extends AppCompatActivity{

private static final int CAMERA_REQUEST_CODE = 101;

private FrameLayout accidentFrame;
private FragmentManager manager;

......

ArrayList< byte[] > sending_list; 


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_accident_record);


    sending_list = new ArrayList<>(); 
     ....


    // button that moves to B Activity
    findViewById(R.id.btnCamera).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent cameraIntent = new Intent(A_Activity.this, B_Activity.class);

            ........

            startActivityForResult(cameraIntent, CAMERA_REQUEST_CODE);
        }
    });

    //

  ....

}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {

    if (requestCode == CAMERA_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {

             int size = data.getExtras().getInt("array_size");
             for(int i = 0; i<size ; i++){
                 sending_list.add(data.getByteArrayExtra("byte_array" + i));
             }

        }
    }
}



private void sendResult() {

    // There is a reason using map!
    HashMap<String, ArrayList<byte[]>> thisMap = new HashMap<>();

    thisMap.put("0", sending_list);


    Intent picturesData = new Intent();
    picturesData.putExtra("data_map", thisMap);

    startActivity(new Intent(A_Activity.this, C_Activity.class));
}

}

B_Activity (активность камеры)

public class B_Activity extends AppCompatActivity{

 ....

Camera camera;
FrameLayout appCamera;

CameraSurfaceAdapter cameraAdapter;
Button btnCapture;
TextView btnFinish;


ArrayList<byte[]> byteArray;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_accident_camera);


    .....


    appCamera = findViewById(R.id.appCamera);

    if (camera == null) {

        camera = Camera.open();
    }


    cameraAdapter = new CameraSurfaceAdapter(getApplicationContext(), camera);
    appCamera.addView(cameraAdapter);


    // take picture 
    byteArray = new ArrayList<byte[]>();
    btnCapture = findViewById(R.id.btnCapture);
    btnCapture.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            takePicture();
        }
    });


    btnFinish = findViewById(R.id.btnFinish);
    btnFinish.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

         if (byteArray != null){

              Intent dataIntent = new Intent();
              dataIntent.putExtra("array_size", byteArray.size());
              for(int i = 0; i<byteArray.size() ; i++){

                  dataIntent.putExtra("byte_array" + i, byteArray.get(i)); 
              }

              setResult(RESULT_OK, dataIntent);
              finish();

        }
    });
}


private void takePicture() {

    if (camera != null) {

        camera.takePicture(null, null, mPictureCallback);

    } else {
    }

}


Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {


        byteArray.add(data);

        camera.startPreview();

        savePhoto(data);

    }
};


.......


@Override
public void onBackPressed() {


    btnFinish.performClick();

}


@Override
public void onDestroy() {
    super.onDestroy();

    camera.stopPreview();
    camera.release();

    camera = null;
}

}

Моя мысль состоит в том, чтобы использовать Фрагмент. Фрагмент поможет вам в вашем случае.

Akio Alex 09.04.2019 05:18

сделать оба фрагмента деятельности вы имеете в виду?

Silverion 09.04.2019 05:22

B деятельность сделать фрагмент.

Akio Alex 09.04.2019 05:24

Еще один простой, но довольно грязный подход, который я бы рассмотрел при обмене большими данными между действиями, — это просто хранить их в синглтоне.

Ricky Mo 09.04.2019 05:31

@AkioAlex загрузил код! Спасибо

Silverion 09.04.2019 05:56
1
5
1 089
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Не проходите мимо изображения. Это неэффективно, и вы довольно быстро достигнете пределов размера. Просто передайте ссылку, как вы получили в onActivityResult() от камеры. Или, если необходимо, сохраните этот файл изображения где-нибудь (SD-карта, личное хранилище) и передайте ему Uri. Не передавать двоичный BLOB-объект.

Спасибо. Я просто подойду к проблеме иначе. Спасибо!

Silverion 09.04.2019 05:51

но что вы имеете в виду, передавая ссылку?

Silverion 09.04.2019 05:55

Это означает, что просто временно сохраните изображение в локальном хранилище. затем отправьте его URL-адрес/путь к следующему действию. открыть изображение с этого URL. Поскольку передача изображения в массив байтов также замедляется при открытии новой активности.

Jigar 09.04.2019 06:23

сделал это ! Еще раз спасибо :) Думаю, я поступил так глупо

Silverion 09.04.2019 07:04

Передать массив байтов в намерение: -

Intent intent = new Intent(this, NextActivity.class);
intent.putExtra("picture", byteArray);
startActivity(intent);

Получить массив байтов из пакета и преобразовать в растровое изображение: -

Bundle extras = getIntent().getExtras();
byte[] byteArray = extras.getByteArray("picture");

Другие вопросы по теме