Created
November 6, 2021 18:28
-
-
Save codinginflow/634cacb6884f7a6b0bb14db51db228a1 to your computer and use it in GitHub Desktop.
Firebase Image Upload App Tutorial Part 8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
tools:context="com.codinginflow.firebaseuploadexample.ImagesActivity"> | |
<ProgressBar | |
android:id="@+id/progress_circle" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_centerInParent="true" /> | |
<android.support.v7.widget.RecyclerView | |
android:id="@+id/recycler_view" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" /> | |
</RelativeLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:padding="16dp" | |
tools:context="com.codinginflow.firebaseuploadexample.MainActivity"> | |
<Button | |
android:id="@+id/button_choose_image" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="Choose file" /> | |
<EditText | |
android:id="@+id/edit_text_file_name" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_marginStart="16dp" | |
android:layout_toEndOf="@+id/button_choose_image" | |
android:hint="Enter file name" /> | |
<ImageView | |
android:id="@+id/image_view" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_above="@id/progress_bar" | |
android:layout_below="@id/edit_text_file_name" | |
android:layout_marginTop="16dp" /> | |
<ProgressBar | |
android:id="@+id/progress_bar" | |
style="@style/Widget.AppCompat.ProgressBar.Horizontal" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_above="@+id/button_upload" | |
android:layout_alignParentStart="true" | |
android:layout_marginBottom="16dp" /> | |
<Button | |
android:id="@+id/button_upload" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_alignParentBottom="true" | |
android:layout_centerHorizontal="true" | |
android:text="Upload" /> | |
<TextView | |
android:id="@+id/text_view_show_uploads" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_alignBottom="@+id/button_upload" | |
android:layout_alignTop="@+id/button_upload" | |
android:layout_marginStart="25dp" | |
android:layout_toEndOf="@+id/button_upload" | |
android:gravity="center" | |
android:text="Show Uploads" | |
android:textSize="16sp" /> | |
</RelativeLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
package="com.codinginflow.firebaseuploadexample"> | |
<uses-permission android:name="android.permission.INTERNET" /> | |
<application | |
android:allowBackup="true" | |
android:icon="@mipmap/ic_launcher" | |
android:label="@string/app_name" | |
android:roundIcon="@mipmap/ic_launcher_round" | |
android:supportsRtl="true" | |
android:theme="@style/AppTheme"> | |
<activity android:name=".MainActivity"> | |
<intent-filter> | |
<action android:name="android.intent.action.MAIN" /> | |
<category android:name="android.intent.category.LAUNCHER" /> | |
</intent-filter> | |
</activity> | |
<activity android:name=".ImagesActivity"></activity> | |
</application> | |
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:layout_margin="8dp"> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:orientation="vertical"> | |
<TextView | |
android:id="@+id/text_view_name" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_gravity="center_horizontal" | |
android:layout_marginBottom="8dp" | |
android:layout_marginTop="8dp" | |
android:text="Name" | |
android:textColor="@android:color/black" | |
android:textSize="20sp" /> | |
<ImageView | |
android:id="@+id/image_view_upload" | |
android:layout_width="match_parent" | |
android:layout_height="200dp" /> | |
</LinearLayout> | |
</android.support.v7.widget.CardView> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.codinginflow.firebaseuploadexample; | |
import android.content.Context; | |
import android.support.v7.widget.RecyclerView; | |
import android.view.ContextMenu; | |
import android.view.LayoutInflater; | |
import android.view.Menu; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.ImageView; | |
import android.widget.TextView; | |
import com.squareup.picasso.Picasso; | |
import java.util.List; | |
public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageViewHolder> { | |
private Context mContext; | |
private List<Upload> mUploads; | |
private OnItemClickListener mListener; | |
public ImageAdapter(Context context, List<Upload> uploads) { | |
mContext = context; | |
mUploads = uploads; | |
} | |
@Override | |
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { | |
View v = LayoutInflater.from(mContext).inflate(R.layout.image_item, parent, false); | |
return new ImageViewHolder(v); | |
} | |
@Override | |
public void onBindViewHolder(ImageViewHolder holder, int position) { | |
Upload uploadCurrent = mUploads.get(position); | |
holder.textViewName.setText(uploadCurrent.getName()); | |
Picasso.with(mContext) | |
.load(uploadCurrent.getImageUrl()) | |
.placeholder(R.mipmap.ic_launcher) | |
.fit() | |
.centerCrop() | |
.into(holder.imageView); | |
} | |
@Override | |
public int getItemCount() { | |
return mUploads.size(); | |
} | |
public class ImageViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, | |
View.OnCreateContextMenuListener, MenuItem.OnMenuItemClickListener { | |
public TextView textViewName; | |
public ImageView imageView; | |
public ImageViewHolder(View itemView) { | |
super(itemView); | |
textViewName = itemView.findViewById(R.id.text_view_name); | |
imageView = itemView.findViewById(R.id.image_view_upload); | |
itemView.setOnClickListener(this); | |
itemView.setOnCreateContextMenuListener(this); | |
} | |
@Override | |
public void onClick(View v) { | |
if (mListener != null) { | |
int position = getAdapterPosition(); | |
if (position != RecyclerView.NO_POSITION) { | |
mListener.onItemClick(position); | |
} | |
} | |
} | |
@Override | |
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { | |
menu.setHeaderTitle("Select Action"); | |
MenuItem doWhatever = menu.add(Menu.NONE, 1, 1, "Do whatever"); | |
MenuItem delete = menu.add(Menu.NONE, 2, 2, "Delete"); | |
doWhatever.setOnMenuItemClickListener(this); | |
delete.setOnMenuItemClickListener(this); | |
} | |
@Override | |
public boolean onMenuItemClick(MenuItem item) { | |
if (mListener != null) { | |
int position = getAdapterPosition(); | |
if (position != RecyclerView.NO_POSITION) { | |
switch (item.getItemId()) { | |
case 1: | |
mListener.onWhatEverClick(position); | |
return true; | |
case 2: | |
mListener.onDeleteClick(position); | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
} | |
public interface OnItemClickListener { | |
void onItemClick(int position); | |
void onWhatEverClick(int position); | |
void onDeleteClick(int position); | |
} | |
public void setOnItemClickListener(OnItemClickListener listener) { | |
mListener = listener; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.codinginflow.firebaseuploadexample; | |
import android.support.v7.app.AppCompatActivity; | |
import android.os.Bundle; | |
import android.support.v7.widget.LinearLayoutManager; | |
import android.support.v7.widget.RecyclerView; | |
import android.view.View; | |
import android.widget.ProgressBar; | |
import android.widget.Toast; | |
import com.google.android.gms.tasks.OnSuccessListener; | |
import com.google.firebase.database.DataSnapshot; | |
import com.google.firebase.database.DatabaseError; | |
import com.google.firebase.database.DatabaseReference; | |
import com.google.firebase.database.FirebaseDatabase; | |
import com.google.firebase.database.ValueEventListener; | |
import com.google.firebase.storage.FirebaseStorage; | |
import com.google.firebase.storage.StorageReference; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class ImagesActivity extends AppCompatActivity implements ImageAdapter.OnItemClickListener { | |
private RecyclerView mRecyclerView; | |
private ImageAdapter mAdapter; | |
private ProgressBar mProgressCircle; | |
private FirebaseStorage mStorage; | |
private DatabaseReference mDatabaseRef; | |
private ValueEventListener mDBListener; | |
private List<Upload> mUploads; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_images); | |
mRecyclerView = findViewById(R.id.recycler_view); | |
mRecyclerView.setHasFixedSize(true); | |
mRecyclerView.setLayoutManager(new LinearLayoutManager(this)); | |
mProgressCircle = findViewById(R.id.progress_circle); | |
mUploads = new ArrayList<>(); | |
mAdapter = new ImageAdapter(ImagesActivity.this, mUploads); | |
mRecyclerView.setAdapter(mAdapter); | |
mAdapter.setOnItemClickListener(ImagesActivity.this); | |
mStorage = FirebaseStorage.getInstance(); | |
mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads"); | |
mDBListener = mDatabaseRef.addValueEventListener(new ValueEventListener() { | |
@Override | |
public void onDataChange(DataSnapshot dataSnapshot) { | |
mUploads.clear(); | |
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) { | |
Upload upload = postSnapshot.getValue(Upload.class); | |
upload.setKey(postSnapshot.getKey()); | |
mUploads.add(upload); | |
} | |
mAdapter.notifyDataSetChanged(); | |
mProgressCircle.setVisibility(View.INVISIBLE); | |
} | |
@Override | |
public void onCancelled(DatabaseError databaseError) { | |
Toast.makeText(ImagesActivity.this, databaseError.getMessage(), Toast.LENGTH_SHORT).show(); | |
mProgressCircle.setVisibility(View.INVISIBLE); | |
} | |
}); | |
} | |
@Override | |
public void onItemClick(int position) { | |
Toast.makeText(this, "Normal click at position: " + position, Toast.LENGTH_SHORT).show(); | |
} | |
@Override | |
public void onWhatEverClick(int position) { | |
Toast.makeText(this, "Whatever click at position: " + position, Toast.LENGTH_SHORT).show(); | |
} | |
@Override | |
public void onDeleteClick(int position) { | |
Upload selectedItem = mUploads.get(position); | |
final String selectedKey = selectedItem.getKey(); | |
StorageReference imageRef = mStorage.getReferenceFromUrl(selectedItem.getImageUrl()); | |
imageRef.delete().addOnSuccessListener(new OnSuccessListener<Void>() { | |
@Override | |
public void onSuccess(Void aVoid) { | |
mDatabaseRef.child(selectedKey).removeValue(); | |
Toast.makeText(ImagesActivity.this, "Item deleted", Toast.LENGTH_SHORT).show(); | |
} | |
}); | |
} | |
@Override | |
protected void onDestroy() { | |
super.onDestroy(); | |
mDatabaseRef.removeEventListener(mDBListener); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.codinginflow.firebaseuploadexample; | |
import android.content.ContentResolver; | |
import android.content.Intent; | |
import android.net.Uri; | |
import android.os.Handler; | |
import android.support.annotation.NonNull; | |
import android.support.v7.app.AppCompatActivity; | |
import android.os.Bundle; | |
import android.view.View; | |
import android.webkit.MimeTypeMap; | |
import android.widget.Button; | |
import android.widget.EditText; | |
import android.widget.ImageView; | |
import android.widget.ProgressBar; | |
import android.widget.TextView; | |
import android.widget.Toast; | |
import com.google.android.gms.tasks.OnFailureListener; | |
import com.google.android.gms.tasks.OnSuccessListener; | |
import com.google.firebase.database.DatabaseReference; | |
import com.google.firebase.database.FirebaseDatabase; | |
import com.google.firebase.storage.FirebaseStorage; | |
import com.google.firebase.storage.OnProgressListener; | |
import com.google.firebase.storage.StorageReference; | |
import com.google.firebase.storage.StorageTask; | |
import com.google.firebase.storage.UploadTask; | |
import com.squareup.picasso.Picasso; | |
public class MainActivity extends AppCompatActivity { | |
private static final int PICK_IMAGE_REQUEST = 1; | |
private Button mButtonChooseImage; | |
private Button mButtonUpload; | |
private TextView mTextViewShowUploads; | |
private EditText mEditTextFileName; | |
private ImageView mImageView; | |
private ProgressBar mProgressBar; | |
private Uri mImageUri; | |
private StorageReference mStorageRef; | |
private DatabaseReference mDatabaseRef; | |
private StorageTask mUploadTask; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
mButtonChooseImage = findViewById(R.id.button_choose_image); | |
mButtonUpload = findViewById(R.id.button_upload); | |
mTextViewShowUploads = findViewById(R.id.text_view_show_uploads); | |
mEditTextFileName = findViewById(R.id.edit_text_file_name); | |
mImageView = findViewById(R.id.image_view); | |
mProgressBar = findViewById(R.id.progress_bar); | |
mStorageRef = FirebaseStorage.getInstance().getReference("uploads"); | |
mDatabaseRef = FirebaseDatabase.getInstance().getReference("uploads"); | |
mButtonChooseImage.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
openFileChooser(); | |
} | |
}); | |
mButtonUpload.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
if (mUploadTask != null && mUploadTask.isInProgress()) { | |
Toast.makeText(MainActivity.this, "Upload in progress", Toast.LENGTH_SHORT).show(); | |
} else { | |
uploadFile(); | |
} | |
} | |
}); | |
mTextViewShowUploads.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
openImagesActivity(); | |
} | |
}); | |
} | |
private void openFileChooser() { | |
Intent intent = new Intent(); | |
intent.setType("image/*"); | |
intent.setAction(Intent.ACTION_GET_CONTENT); | |
startActivityForResult(intent, PICK_IMAGE_REQUEST); | |
} | |
@Override | |
protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
super.onActivityResult(requestCode, resultCode, data); | |
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK | |
&& data != null && data.getData() != null) { | |
mImageUri = data.getData(); | |
Picasso.with(this).load(mImageUri).into(mImageView); | |
} | |
} | |
private String getFileExtension(Uri uri) { | |
ContentResolver cR = getContentResolver(); | |
MimeTypeMap mime = MimeTypeMap.getSingleton(); | |
return mime.getExtensionFromMimeType(cR.getType(uri)); | |
} | |
private void uploadFile() { | |
if (mImageUri != null) { | |
StorageReference fileReference = mStorageRef.child(System.currentTimeMillis() | |
+ "." + getFileExtension(mImageUri)); | |
mUploadTask = fileReference.putFile(mImageUri) | |
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() { | |
@Override | |
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) { | |
Handler handler = new Handler(); | |
handler.postDelayed(new Runnable() { | |
@Override | |
public void run() { | |
mProgressBar.setProgress(0); | |
} | |
}, 500); | |
Toast.makeText(MainActivity.this, "Upload successful", Toast.LENGTH_LONG).show(); | |
Upload upload = new Upload(mEditTextFileName.getText().toString().trim(), | |
taskSnapshot.getDownloadUrl().toString()); | |
String uploadId = mDatabaseRef.push().getKey(); | |
mDatabaseRef.child(uploadId).setValue(upload); | |
} | |
}) | |
.addOnFailureListener(new OnFailureListener() { | |
@Override | |
public void onFailure(@NonNull Exception e) { | |
Toast.makeText(MainActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show(); | |
} | |
}) | |
.addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() { | |
@Override | |
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) { | |
double progress = (100.0 * taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount()); | |
mProgressBar.setProgress((int) progress); | |
} | |
}); | |
} else { | |
Toast.makeText(this, "No file selected", Toast.LENGTH_SHORT).show(); | |
} | |
} | |
private void openImagesActivity() { | |
Intent intent = new Intent(this, ImagesActivity.class); | |
startActivity(intent); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.codinginflow.firebaseuploadexample; | |
import com.google.firebase.database.Exclude; | |
public class Upload { | |
private String mName; | |
private String mImageUrl; | |
private String mKey; | |
public Upload() { | |
//empty constructor needed | |
} | |
public Upload(String name, String imageUrl) { | |
if (name.trim().equals("")) { | |
name = "No Name"; | |
} | |
mName = name; | |
mImageUrl = imageUrl; | |
} | |
public String getName() { | |
return mName; | |
} | |
public void setName(String name) { | |
mName = name; | |
} | |
public String getImageUrl() { | |
return mImageUrl; | |
} | |
public void setImageUrl(String imageUrl) { | |
mImageUrl = imageUrl; | |
} | |
@Exclude | |
public String getKey() { | |
return mKey; | |
} | |
@Exclude | |
public void setKey(String key) { | |
mKey = key; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment