#android
#Android
Вопрос:
Я застрял на этой проблеме в течение нескольких дней. Если какой-либо небольшой комментарий, который поможет спасти одного программиста… У меня есть эти два действия A и B. Действие A — это действие, которое вызывает действие B в startActivityForResult(). Действие B — это действие камеры, к которому добавлена камера. И изображения, которые принимает действие B, должны быть отправлены обратно в действие A.
Фотографии, которые я делаю, принимаются с помощью байтовых данных с помощью PictureCallback. И вот в чем проблема. Я ожидаю, что пользователь сделает как минимум 2-3 (или более) снимка, поэтому я попытался придать этим массивам байтов форму списка.
-
Список Bitmap невозможен, потому что он вызывает ошибку НЕУДАЧНОЙ ТРАНЗАКЦИИ BINDER, когда она превышает 40 КБ.
-
ArrayList<byte[] > не подлежит разделению, поэтому невозможно ввести в намерение дополнительные данные.
-
Я попытался сохранить каждый байт [] данных фотографий в 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");