I made an application where it is possible to take a photo and save its path in the database and then show it in a listView along with other information. All goes well when there are few images or small images to be displayed, but when reaching a certain amount of images, the application is very slow sometimes reaching to stop. This is the error that occurs:
FATAL EXCEPTION: main java.lang.OutOfMemoryError: Failed to allocate to 20155404 byte allocation with 16777120 free and 16MB until OOM.
class to capture or select the sd card image
public class InicialMy extends Activity {
private static final int SELECT_PICTURE = 1;
private static final int CAPTURAR_IMAGEM = 2;
private static final int REQUEST_IMAGE_PICK = 3;
private Uri uri;
private Button irParaLista;
private String caminho;
private TextView lugar;
private String imagePath;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inicial_my);
Button save = (Button)findViewById(R.id.button);
File imgFile = new File("/storage/emulated/0/Download/20150617-0013.jpeg");
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ImageView miImage = (ImageView) findViewById(R.id.imageCapa);
miImage.setImageBitmap(myBitmap);
}
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Controller dao = new Controller(getBaseContext());
irParaLista = (Button)findViewById(R.id.buttonLista);
EditText nome = (EditText)findViewById(R.id.editTextTitulo);
EditText dono = (EditText)findViewById(R.id.editTextAutor);
ImageView foto = (ImageView)findViewById(R.id.imageCapa);
String result;
result = dao.insereDado(nome.getText().toString(),dono.getText().toString(),caminho);
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
}
});
Button btn = (Button) findViewById(R.id.buttonImage);
btn.setOnClickListener(mOnClickListener);
}
//começo do button
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_PICK);
startActivityForResult(Intent.createChooser(intent, "Selecione a capa do livro"), REQUEST_IMAGE_PICK);
}
};
//fim do button
public void lista(View view){
if(view.getId() == R.id.buttonLista){
startActivity(new Intent(this, ListaCarros.class));
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent){
super.onActivityResult(requestCode, resultCode, intent);
switch (requestCode){
case REQUEST_IMAGE_PICK:
if(RESULT_OK == resultCode){
Uri imageUri = intent.getData();
ImageView imagemCapa = (ImageView) findViewById(R.id.imageCapa);
imagemCapa.setImageURI(imageUri);
imagePath = getImagePath(imageUri);
Toast.makeText(this, imagePath, Toast.LENGTH_LONG).show();
caminho = imagePath;
}
break;
case CAPTURAR_IMAGEM:
if(requestCode == CAPTURAR_IMAGEM){
mostrarMensagem("Imagem capturada");
adicionarNaGaleria();
}
}
}
public String getImagePath(Uri contentUri){
String [] campos = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(contentUri, campos, null, null, null);
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));
cursor.close();
return path;
}
private void adicionarNaGaleria(){
Intent intent = new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
);
intent.setData(uri);
this.sendBroadcast(intent);
}
private void mostrarMensagem(String msg){
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
public void capturarImagem(View view){
File diretorio = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
String nomeImagem = diretorio.getPath()+"/"+System.currentTimeMillis()+".jpg";
uri = Uri.fromFile(new File(nomeImagem));
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
startActivityForResult(intent, CAPTURAR_IMAGEM);
}
public void visualizarImagem(View view){
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "image/jpeg");
startActivity(intent);
}
}
class to show list:
public class ListaCarros extends ActionBarActivity {
private CarrosAdapter adaptador;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lista_carros);
List<Carro> lista;
ListView controle;
Controller dao = new Controller(getBaseContext());
Cursor cursor = dao.carregaDados();
lista = cursor2List(cursor);
adaptador = new CarrosAdapter(getApplication(),R.layout.layout_carros, lista);
controle = (ListView)findViewById(R.id.listView);
controle.setAdapter(adaptador);
}
protected List<Carro> cursor2List(Cursor cursor){
List<Carro> carros = new ArrayList<Carro>();
cursor.moveToFirst();
do{
Carro carro = new Carro();
carro.setNome(cursor.getString(cursor.getColumnIndex(DBHelper.NOME)));
carro.setDono(cursor.getString(cursor.getColumnIndex(DBHelper.DONO)));
carro.setFoto(cursor.getString(cursor.getColumnIndex(DBHelper.FOTO)));
carros.add(carro);
}while(cursor.moveToNext());
return carros;
}
}
class to control the insertion of data:
public class Controller {
private SQLiteDatabase db;
private DBHelper banco;
public Controller(Context context){
banco = new DBHelper(context);
}
public String insereDado(String nome, String dono, String caminho){
ContentValues valores;
long resultado;
db = banco.getWritableDatabase();
valores = new ContentValues();
valores.put(banco.NOME,nome);
valores.put(banco.DONO,dono);
valores.put(banco.FOTO,caminho);
resultado = db.insert(banco.TABELA,null,valores);
db.close();
if(resultado==-1){
return "ERRO";
}else{
return "Inserido com Sucesso";
}
}
public Cursor carregaDados(){
Cursor cursor;
String[] campos = {banco.ID,banco.NOME,banco.DONO,banco.FOTO};
db = banco.getReadableDatabase();
cursor = db.query(banco.TABELA, campos, null, null, null, null, null, null);
if(cursor!=null){
cursor.moveToFirst();
}
db.close();
return cursor;
}
}
car adapter:
public class CarrosAdapter extends ArrayAdapter<Carro>{
Context contexto;
int id;
List<Carro> lista;
public CarrosAdapter(Context contexto, int id, List<Carro> lista){
super(contexto,id,lista);
this.contexto = contexto;
this.lista = lista;
this.id = id;
}
public View getView(int position, View convertView, ViewGroup parent){
View view = convertView;
Carro carro;
ImageView foto;
TextView nome;
TextView dono;
Bitmap raw;
TextView caminho;
if(view == null){
LayoutInflater inflater = LayoutInflater.from(contexto);
view = inflater.inflate(id, parent, false);
}
nome = (TextView)view.findViewById(R.id.textView);
dono = (TextView)view.findViewById(R.id.textView3);
foto = (ImageView)view.findViewById(R.id.imageView);
caminho = (TextView)view.findViewById(R.id.textViewCaminho);
carro = lista.get(position);
nome.setText(carro.getNome());
dono.setText(carro.getDono());
File imgFile = new File(carro.getFoto());
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
foto.setImageBitmap(myBitmap);
caminho.setText(carro.getFoto());
return view;
}
}
Can anyone help me solve this memory problem?