0 votes

Collect an Image together with some data that I upload to Firebase and display it in a RecyclerView

I have a program that collects the data of a Notice (Name, description and Location) then I would need to collect the photo that is uploaded to the Firebase Storage. How could I do to relate the image that I upload to when I show the data of the Notice? I leave the code of the files that I use, to see what I could change/add. Thank you very much. Up

Photo file for making and uploading images to Firebase

public class Fotos extends AppCompatActivity {

    //Controles para la camara/galeria
    private static String APP_DIRECTORY = "MyPictureApp/";
    private static String MEDIA_DIRECTORY = APP_DIRECTORY + "PictureApp";

    private final int PHOTO_CODE = 200;
    private final int SELECT_PICTURE = 300;

    private String mPath;
    private Bitmap imageBitmap;

    private StorageReference mStorage;

    ImageView foto;

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

        foto = (ImageView) findViewById(R.id.foto);

        mStorage = FirebaseStorage.getInstance().getReference();

        //Botones para abrir las Actividades (Camara/Galeria/Siguiente)
        Button camara = (Button) findViewById(R.id.camara1);
        camara.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openCamera();
            }
        });

        //Metodo para abrir la Galeria
        Button galeria = (Button) findViewById(R.id.galeria);
        galeria.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                openGaleria();
            }
        });

        //Metodo para pasar la foto a la Actividad MenuAvisos
        Button siguiente = (Button) findViewById(R.id.siguiente);
        siguiente.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view)
            {
                openSiguiente();
            }
        });
    }

    //Metodo para abrir la Camara de Fotos
    private void openCamera()
    {
        File file = new File(Environment.getExternalStorageDirectory(), MEDIA_DIRECTORY);
        boolean isDirectoryCreated = file.exists();

        if(!isDirectoryCreated)
            isDirectoryCreated = file.mkdirs();

        if(isDirectoryCreated)
        {
            Long timestamp = System.currentTimeMillis() / 1000;
            String imageName = timestamp.toString() + ".jpg";

            mPath = Environment.getExternalStorageDirectory() + File.separator + MEDIA_DIRECTORY + File.separator + imageName;

            File newFile = new File(mPath);

            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(newFile));

            startActivityForResult(intent, PHOTO_CODE);
        }
    }

    private Bitmap drawableToBitmap (Drawable drawable)
    {
        Bitmap bitmap = null;

        if(drawable instanceof BitmapDrawable)
        {
            BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
            if(bitmapDrawable.getBitmap() !=null)
            {
                return bitmapDrawable.getBitmap();
            }
        }

        if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0)
        {
            bitmap = Bitmap.createBitmap(1,1, Bitmap.Config.ARGB_8888);
        }
        else {
            bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        }

        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0,0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);

        return bitmap;
    }

    //Depende la seleccion de Camara/Galeria (Case) hace una cosa o otra para mostrar las imagenes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, final Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(resultCode == RESULT_OK){
            switch (requestCode){
                case PHOTO_CODE:
                    MediaScannerConnection.scanFile(this, new String[] { mPath }, null, new MediaScannerConnection.OnScanCompletedListener() {
                        @Override
                        public void onScanCompleted(String path, Uri uri) {
                            Log.i("ExternalStorage", "Scanned" + path + ":");
                            Log.i("ExternalStorage", "-> Uri = " + uri);
                        }
                    });
                    imageBitmap = BitmapFactory.decodeFile(mPath);
                    break;
                case SELECT_PICTURE:
                    //FireBase Storage
                    Uri path = data.getData();
                    StorageReference filePath = mStorage.child("Fotos Aviso").child(path.getLastPathSegment());
                    filePath.putFile(path).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                        @Override
                        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                            Toast.makeText(Fotos.this, "Se ha subido la foto a FireBase!", Toast.LENGTH_SHORT).show();
                        }
                    });
                    //Mostrar la imagen
                    foto.setImageURI(path);
                    imageBitmap = drawableToBitmap(foto.getDrawable());
                    break;
            }
        }
    }

    //Metodo para abrir la Galeria
    private void openGaleria()
    {
        Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        intent.setType("image/*");

        startActivityForResult(intent.createChooser(intent, "Selecciona app de imagen"), SELECT_PICTURE);
    }

    //Metodo para enviar la foto a la Actividad MenuAvisos*
    private void openSiguiente()
    {
        Intent intent=new Intent();
        imageBitmap = Bitmap.createScaledBitmap(imageBitmap, 200, 150, true);
        ByteArrayOutputStream bs = new ByteArrayOutputStream();
        imageBitmap.compress(Bitmap.CompressFormat.PNG,50,bs);
        intent.putExtra("MESSAGE",bs.toByteArray());
        setResult(RESULT_OK,intent);

        finish();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putString("file_path", mPath);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        mPath = savedInstanceState.getString("file_path");
    }
}

File where I collect all the Notice Data and upload it to the FireBase database.

public class MenuAvisos extends AppCompatActivity implements View.OnClickListener  {

    public static final int FOTO_KEY = 66;
    public static final int MAPS_KEY = 11;

    TextView aviso1;
    EditText textDes;
    Button ubicacion;
    TextView textubi;
    ImageButton addfoto;
    ImageView foto;
    Button guardar;

    public FirebaseAuth firebaseAuth;

    private DatabaseReference databaseReference;

    String nombre;
    String ubi;

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

        aviso1 = (TextView) findViewById(R.id.aviso);
        textDes = (EditText) findViewById(R.id.descripcion);
        ubicacion = (Button) findViewById(R.id.ubicacion);
        textubi = (TextView) findViewById(R.id.textUbi);
        addfoto = (ImageButton) findViewById(R.id.addfoto);
        foto = (ImageView) findViewById(R.id.foto);
        guardar = (Button) findViewById(R.id.guardar);

        databaseReference = FirebaseDatabase.getInstance().getReference();

        //Intent para recojer el nombre de la ListView
        Intent intent1 = getIntent();
        if(nombre!=null)
        {
            aviso1.setText(String.valueOf(nombre));
        }
        else
        {
            nombre = intent1.getStringExtra(ViewAviso.NOMBRE_KEY);
            aviso1.setText(String.valueOf(nombre));
        }

        //Metodo para abrir el mapa de la Ubicacion
        View.OnClickListener listener1 = new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                openMaps();
            }
        };
        ubicacion = (Button) findViewById(R.id.ubicacion);
        ubicacion.setOnClickListener(listener1);

        //Metodo para abrir la Class de Fotos *
        addfoto = (ImageButton) findViewById(R.id.addfoto);
        addfoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                openFotos();
            }
        });

        guardar.setOnClickListener(this);

    }

    //onActivity para mostrar la Imagen de la Actividad Fotos Y Para sacar el contenido del String ubi
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(requestCode==FOTO_KEY)
        {
            byte[] byteArray = data.getExtras().getByteArray("MESSAGE");
            if(byteArray != null)
            {
                Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
                foto.setImageBitmap(bmp);
            }
        }
        //Para mostrar la dni (String ubi de MapsActivity)
        if(requestCode==MAPS_KEY && resultCode==RESULT_OK)
        {

            ubi = data.getStringExtra(MapsActivity.UBICACION_KEY);
            textubi.setText(ubi);
        }

    }

    //Metodo para abrir la Class de Fotos (Camara/Galeria)
    private void openFotos()
    {
        Intent intent = new Intent(this, Fotos.class);

        startActivityForResult(intent, FOTO_KEY);
    }

    //Metodo para abrir la Class de Maps
    private void openMaps()
    {
        Intent intent = new Intent(this, MapsActivity.class);

        startActivityForResult(intent, MAPS_KEY);
    }

    //Metodo para abrir la Class de Revisar (Donde enviamos toda la informacion del ListaAvisos)
    private void openEnviar()
    {
        Intent intent = new Intent(this, Verificar.class);

        String aux1 = aviso1.getText().toString();
        String aux2 = textDes.getText().toString();
        String aux3 = textubi.getText().toString();

        intent.putExtra("aviso", aux1);
        intent.putExtra("apellidos", aux2);
        intent.putExtra("dni", aux3);

        startActivity(intent);
    }

    private void saveInformation()
    {
        //getting current user
        FirebaseUser user = firebaseAuth.getInstance().getCurrentUser();

        Aviso avisos = new Aviso();
        //Getting values from database
        avisos.setAviso(aviso1.getText().toString());
        avisos.setDescripcion(textDes.getText().toString());
        avisos.setUbicacion(textubi.getText().toString());

        //Creamos un objeto para guardar la informacion
        //Aviso avisoInformation = new Aviso(aviso,apellidos,dni,usuario);
        FirebaseDatabase database = FirebaseDatabase.getInstance();

        final DatabaseReference myRef = database.getReference("Aviso").child(user.getUid()); //Aviso + Uid del Usuario
        Aviso aviso2 = new Aviso(avisos.getAviso(),avisos.getDescripcion(),avisos.getUbicacion());
        myRef.push().setValue(aviso2); //Push crea un Uid para cada Aviso

        //displaying a success toast
        Toast.makeText(this, "Guardando informacion del aviso, espera...", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onClick(View view) {
        //if logout is pressed
        if (view == guardar)
        {
            saveInformation();
            openEnviar();
        }
    }
}

File that I use to display all the Aviso and its data

public class VerAvisos extends MenuAvisos
{

    FirebaseDatabase database = FirebaseDatabase.getInstance();
    FirebaseUser user = firebaseAuth.getInstance().getCurrentUser();

    List<Aviso> avisos;
    RecyclerView rv;
    AdaptadorAvisos adapter;

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

        avisos = new ArrayList<>();

        rv=(RecyclerView) findViewById(R.id.rvAvisos);
        rv.setLayoutManager(new LinearLayoutManager(this));
        adapter = new AdaptadorAvisos(this,avisos);
        rv.setAdapter(adapter);

        database.getReference("Aviso").child(user.getUid()).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                avisos.clear();
                for(DataSnapshot snapshot :
                        dataSnapshot.getChildren()){

                    Aviso aviso2 = snapshot.getValue(Aviso.class);
                    avisos.add(aviso2);

                }
                adapter.notifyDataSetChanged();
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });
    }

Warning Code

public class Aviso {

    String aviso;
    String descripcion;
    String ubicacion;

    public Aviso(){
    }

    public Aviso(String aviso, String descripcion, String ubicacion){
        this.aviso = aviso;
        this.descripcion = descripcion;
        this.ubicacion = ubicacion;
    }

    public String getAviso() {
        return aviso;
    }

    public void setAviso(String aviso) {
        this.aviso = aviso;
    }

    public String getDescripcion() {
        return descripcion;
    }

    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    public String getUbicacion() {
        return ubicacion;
    }

    public void setUbicacion(String ubicacion) {
        this.ubicacion = ubicacion;
    }

    @Override
    public String toString() {

        return  "Nombre Aviso: " +aviso+ " \n" +
                "Descripcion: " +descripcion + " \n" +
                "Ubicacion: " +ubicacion;

    }
}

0voto

jirungaray Points 807

That will depend a lot on what you plan to use those images for. When you upload a file to storage it is linked to a path within the same (ex: /photos/47259827.jpg ), this is the path you must use if you want to download the file through the storage API and you will be the only one who can access it.

If what you are going to do is to show those images in a list, my recommendation is that when you upload the file you request the direct link. storageRef.child("fotos/12345.jpg").getDownloadUrl() and that you save that link in your Notice object. The advantage of this is that this url (autogenerated, not guessable) is publishes and therefore can be used in frameworks like Picasso o Glide to do image management (recommended), the disadvantage is obviously that whoever gets that url will be able to access your image.

While it is possible to integrate these frameworks with the storage API, this creates a chaos of threads and parallelization that, believe me, will generate more headaches than it solves. Unless your content is sensitive, I suggest you do it with the direct link.

HolaDevs.com

HolaDevs is an online community of programmers and software lovers.
You can check other people responses or create a new question if you don't find a solution

Powered by:

X