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

#android

#Android

Вопрос:

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

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

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

  2. ArrayList<byte[] > не подлежит разделению, поэтому невозможно ввести в намерение дополнительные данные.

  3. Я попытался сохранить каждый байт [] данных фотографий в intent 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;
}
  

}

Комментарии:

1. Я думаю, что использовать Fragment Фрагмент поможет вам в вашем случае.

2. вы имеете в виду фрагментацию обоих действий?

3. Действие B создает фрагмент.

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

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

Ответ №1:

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

Комментарии:

1. спасибо. Я просто подойду к проблеме по-другому. Спасибо!

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

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

4. получилось! Еще раз спасибо 🙂 Думаете, я поступал таким глупым образом

Ответ №2:

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

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

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

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