Olá, amigos. O caso é o seguinte, quero fazer o upload de fotos e vídeos tirados com a câmera do celular. Eu armazeno esses arquivos no sdcard e na hora de transmitir para um servidor eu os transformo em um array de bytes para passar um XML para o WebService; neste, tendo o array de bytes, já sabe o que fazer.
Tenho um método para isso, que faz o array de bytes para mim, sendo vídeo ou imagem. O problema é que em alguns arquivos o código tem lançado OutOfMemoryError, mesmo eu limitando o tamanho do vídeo em 5Mb no máximo.
O erro ocorre especificamente nesta linha:
// Transforma os bytes em string
bytesArquivo = Base64.encodeToString(arqData, Base64.DEFAULT);
Método para transformar o arquivo em bytes
/**
* Cria uma lista de arquivos de uma determinada vistoria pegando as informações
* que estão salvas no banco e adicionando os bytes do arquivo para ser passado
* pelo XML.
*
* @param context Contexto da aplicação.
* @param vis Vistoria para pesquisar os arquivos.
* @return Lista de arquivos com a informação dos bytes inclusa.
*/
public static List<Arquivos> converterArquivoEmBytes(Context context, Vistoria vis) {
byte[] arqData = null;
String bytesArquivo = "";
List<Arquivos> listaArquivos = new ArrayList<Arquivos>();
Arquivos arq;
ArquivosController dbArq = new ArquivosController(context);
Cursor cursor = dbArq.selectPorVistoria(vis.getCodVistoria());
while (cursor.moveToNext()) {
arq = new Arquivos();
arq = dbArq.montarObj(cursor);
listaArquivos.add(arq);
} // Fim do while
// Fecha o cursor
cursor.close();
dbArq.close();
for (int i = 0; i < listaArquivos.size(); i++) {
arq = listaArquivos.get(i);
// transforma a imagem em um byte[]
File file = new File(pegarCaminhoArquivos(context) + File.separator
+ arq.getNomeArq() + "." + arq.getExtArq());
if (arq.getTipoMidiaArq() == Arquivos.TIPO_MIDIA_IMAGEM) {
Bitmap bmTemp = BitmapFactory.decodeFile(file.getAbsolutePath());
bmTemp = Bitmap.createBitmap(bmTemp);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bmTemp.compress(Bitmap.CompressFormat.JPEG, 90, bos);
arqData = bos.toByteArray();
// Transforma os bytes em string
bytesArquivo = Base64.encodeToString(arqData, Base64.DEFAULT);
} else if (arq.getTipoMidiaArq() == Arquivos.TIPO_MIDIA_VIDEO) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(file);
byte[] buf = new byte[1024];
int n;
while (-1 != (n = fis.read(buf))) {
baos.write(buf, 0, n);
} // Fim do while
arqData = baos.toByteArray();
// Fecha o FileInputStream
fis.close();
// Transforma os bytes em string
bytesArquivo = Base64.encodeToString(arqData, Base64.DEFAULT);
} catch (OutOfMemoryError oomer) {
Log.e("ERRO", "Não foi possível converter o arquivo de vídeo para a transmissão. OutOfMemoryError. ", oomer);
} catch (Exception ex) {
UtilMsg.msgErro(context, "Não foi possível converter o arquivo de vídeo para a transmissão.",
"CONVERTER ARQUIVO", ex);
} // Fim do controle try/catch
} // Fim do else if
// Add os bytes da determinada foto no campo de bytes
listaArquivos.get(i).setBytesArquivo(bytesArquivo);
} // Fim do for
return listaArquivos;
} // Fim do método converterArquivoEmBytes
Exceção:
06-17 10:44:55.164: E/AndroidRuntime(10020): FATAL EXCEPTION: AsyncTask #1
06-17 10:44:55.164: E/AndroidRuntime(10020): java.lang.RuntimeException: An error occured while executing doInBackground()
06-17 10:44:55.164: E/AndroidRuntime(10020): at android.os.AsyncTask$3.done(AsyncTask.java:299)
06-17 10:44:55.164: E/AndroidRuntime(10020): at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
06-17 10:44:55.164: E/AndroidRuntime(10020): at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
06-17 10:44:55.164: E/AndroidRuntime(10020): at java.util.concurrent.FutureTask.run(FutureTask.java:239)
06-17 10:44:55.164: E/AndroidRuntime(10020): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
06-17 10:44:55.164: E/AndroidRuntime(10020): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
06-17 10:44:55.164: E/AndroidRuntime(10020): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
06-17 10:44:55.164: E/AndroidRuntime(10020): at java.lang.Thread.run(Thread.java:856)
06-17 10:44:55.164: E/AndroidRuntime(10020): Caused by: java.lang.OutOfMemoryError
06-17 10:44:55.164: E/AndroidRuntime(10020): at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:94)
06-17 10:44:55.164: E/AndroidRuntime(10020): at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:145)
06-17 10:44:55.164: E/AndroidRuntime(10020): at java.lang.StringBuilder.append(StringBuilder.java:216)
06-17 10:44:55.164: E/AndroidRuntime(10020): at br.com.gextecnologia.vistorya.thread.ThreadTransmissao.montarArquivoXML(ThreadTransmissao.java:783)
06-17 10:44:55.164: E/AndroidRuntime(10020): at br.com.gextecnologia.vistorya.thread.ThreadTransmissao.montarArquivosXML(ThreadTransmissao.java:824)
06-17 10:44:55.164: E/AndroidRuntime(10020): at br.com.gextecnologia.vistorya.thread.ThreadTransmissao.doInBackground(ThreadTransmissao.java:224)
06-17 10:44:55.164: E/AndroidRuntime(10020): at br.com.gextecnologia.vistorya.thread.ThreadTransmissao.doInBackground(ThreadTransmissao.java:1)
06-17 10:44:55.164: E/AndroidRuntime(10020): at android.os.AsyncTask$2.call(AsyncTask.java:287)
06-17 10:44:55.164: E/AndroidRuntime(10020): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
06-17 10:44:55.164: E/AndroidRuntime(10020): ... 4 more