Firebase 存储操作
通过此示例,你将能够执行以下操作:
- 连接到 Firebase 存储
- 创建一个名为
images
的目录 - 上传 images 目录中的文件
- 从 images 目录下载文件
- 从 images 目录中删除文件
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE_PICK_IMAGE = 1;
private static final int PERMISSION_READ_WRITE_EXTERNAL_STORAGE = 2;
private FirebaseStorage mFirebaseStorage;
private StorageReference mStorageReference;
private StorageReference mStorageReferenceImages;
private Uri mUri;
private ImageView mImageView;
private ProgressDialog mProgressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
mImageView = (ImageView) findViewById(R.id.imageView);
setSupportActionBar(toolbar);
// Create an instance of Firebase Storage
mFirebaseStorage = FirebaseStorage.getInstance();
}
private void pickImage() {
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_CODE_PICK_IMAGE) {
String filePath = FileUtil.getPath(this, data.getData());
mUri = Uri.fromFile(new File(filePath));
uploadFile(mUri);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_READ_WRITE_EXTERNAL_STORAGE) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
pickImage();
}
}
}
private void showProgressDialog(String title, String message) {
if (mProgressDialog != null && mProgressDialog.isShowing())
mProgressDialog.setMessage(message);
else
mProgressDialog = ProgressDialog.show(this, title, message, true, false);
}
private void hideProgressDialog() {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
}
private void showToast(String message) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
public void showHorizontalProgressDialog(String title, String body) {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.setTitle(title);
mProgressDialog.setMessage(body);
} else {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setTitle(title);
mProgressDialog.setMessage(body);
mProgressDialog.setIndeterminate(false);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setProgress(0);
mProgressDialog.setMax(100);
mProgressDialog.setCancelable(false);
mProgressDialog.show();
}
}
public void updateProgress(int progress) {
if (mProgressDialog != null && mProgressDialog.isShowing()) {
mProgressDialog.setProgress(progress);
}
}
/**
* Step 1: Create a Storage
*
* @param view
*/
public void onCreateReferenceClick(View view) {
mStorageReference = mFirebaseStorage.getReferenceFromUrl("gs://**something**.appspot.com");
showToast("Reference Created Successfully.");
findViewById(R.id.button_step_2).setEnabled(true);
}
/**
* Step 2: Create a directory named "Images"
*
* @param view
*/
public void onCreateDirectoryClick(View view) {
mStorageReferenceImages = mStorageReference.child("images");
showToast("Directory 'images' created Successfully.");
findViewById(R.id.button_step_3).setEnabled(true);
}
/**
* Step 3: Upload an Image File and display it on ImageView
*
* @param view
*/
public void onUploadFileClick(View view) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_READ_WRITE_EXTERNAL_STORAGE);
else {
pickImage();
}
}
/**
* Step 4: Download an Image File and display it on ImageView
*
* @param view
*/
public void onDownloadFileClick(View view) {
downloadFile(mUri);
}
/**
* Step 5: Delete am Image File and remove Image from ImageView
*
* @param view
*/
public void onDeleteFileClick(View view) {
deleteFile(mUri);
}
private void showAlertDialog(Context ctx, String title, String body, DialogInterface.OnClickListener okListener) {
if (okListener == null) {
okListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
};
}
AlertDialog.Builder builder = new AlertDialog.Builder(ctx).setMessage(body).setPositiveButton("OK", okListener).setCancelable(false);
if (!TextUtils.isEmpty(title)) {
builder.setTitle(title);
}
builder.show();
}
private void uploadFile(Uri uri) {
mImageView.setImageResource(R.drawable.placeholder_image);
StorageReference uploadStorageReference = mStorageReferenceImages.child(uri.getLastPathSegment());
final UploadTask uploadTask = uploadStorageReference.putFile(uri);
showHorizontalProgressDialog("Uploading", "Please wait...");
uploadTask
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
hideProgressDialog();
Uri downloadUrl = taskSnapshot.getDownloadUrl();
Log.d("MainActivity", downloadUrl.toString());
showAlertDialog(MainActivity.this, "Upload Complete", downloadUrl.toString(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
findViewById(R.id.button_step_3).setEnabled(false);
findViewById(R.id.button_step_4).setEnabled(true);
}
});
Glide.with(MainActivity.this)
.load(downloadUrl)
.into(mImageView);
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
exception.printStackTrace();
// Handle unsuccessful uploads
hideProgressDialog();
}
})
.addOnProgressListener(MainActivity.this, new OnProgressListener<UploadTask.TaskSnapshot>() {
@Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
int progress = (int) (100 * (float) taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount());
Log.i("Progress", progress + "");
updateProgress(progress);
}
});
}
private void downloadFile(Uri uri) {
mImageView.setImageResource(R.drawable.placeholder_image);
final StorageReference storageReferenceImage = mStorageReferenceImages.child(uri.getLastPathSegment());
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "Firebase Storage");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MainActivity", "failed to create Firebase Storage directory");
}
}
final File localFile = new File(mediaStorageDir, uri.getLastPathSegment());
try {
localFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
showHorizontalProgressDialog("Downloading", "Please wait...");
storageReferenceImage.getFile(localFile).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
@Override
public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
hideProgressDialog();
showAlertDialog(MainActivity.this, "Download Complete", localFile.getAbsolutePath(), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
findViewById(R.id.button_step_4).setEnabled(false);
findViewById(R.id.button_step_5).setEnabled(true);
}
});
Glide.with(MainActivity.this)
.load(localFile)
.into(mImageView);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
hideProgressDialog();
exception.printStackTrace();
}
}).addOnProgressListener(new OnProgressListener<FileDownloadTask.TaskSnapshot>() {
@Override
public void onProgress(FileDownloadTask.TaskSnapshot taskSnapshot) {
int progress = (int) (100 * (float) taskSnapshot.getBytesTransferred() / taskSnapshot.getTotalByteCount());
Log.i("Progress", progress + "");
updateProgress(progress);
}
});
}
private void deleteFile(Uri uri) {
showProgressDialog("Deleting", "Please wait...");
StorageReference storageReferenceImage = mStorageReferenceImages.child(uri.getLastPathSegment());
storageReferenceImage.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
hideProgressDialog();
showAlertDialog(MainActivity.this, "Success", "File deleted successfully.", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
mImageView.setImageResource(R.drawable.placeholder_image);
findViewById(R.id.button_step_3).setEnabled(true);
findViewById(R.id.button_step_4).setEnabled(false);
findViewById(R.id.button_step_5).setEnabled(false);
}
});
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "Firebase Storage");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MainActivity", "failed to create Firebase Storage directory");
}
}
deleteFiles(mediaStorageDir);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
hideProgressDialog();
exception.printStackTrace();
}
});
}
private void deleteFiles(File directory) {
if (directory.isDirectory())
for (File child : directory.listFiles())
child.delete();
}
}
默认情况下,Firebase 存储规则会应用身份验证限制。如果用户通过身份验证,那么他就可以对 Firebase 存储执行操作,否则他不能。我通过更新存储规则禁用了此演示中的身份验证部分。以前,规则看起来像:
service firebase.storage {
match /b/**something**.appspot.com/o {
match /{allPaths=**} {
allow read, write: if request.auth != null;
}
}
}
但我改为跳过身份验证:
service firebase.storage {
match /b/**something**.appspot.com/o {
match /{allPaths=**} {
allow read, write;
}
}
}