Я разрабатываю приложение для android устройств, таких как WhatsApp. Он уже в очень продвинутом состоянии, и я исправляю мелкие проблемы, с которыми я столкнулся. Но эту проблему мне, в частности, трудно решить.
Цель - сжать профиль и фотографию обложки, чтобы занять меньше места в Firebase Storage. Тогда сжатие должно работать как для профиля, так и для обложки.
private boolean checkStoragePermissions(){
//check if storage permission is enabled or not
//return true if enabled
//return false if not enabled
boolean result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
== (PackageManager.PERMISSION_GRANTED);
return result;
}
private void requestStoragePermission(){
//request runtime storage permission
requestPermissions(storagePermissions, STORAGE_REQUEST_CODE);
}
private boolean checkCameraPermissions(){
//check if storage permission is enabled or not
//return true if enabled
//return false if not enabled
boolean result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
== (PackageManager.PERMISSION_GRANTED);
boolean result1 = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
== (PackageManager.PERMISSION_GRANTED);
return result && result1;
}
private void requestCameraPermission(){
//request runtime storage permission
requestPermissions(cameraPermissions, CAMERA_REQUEST_CODE);
}
private void showEditProfileDialog() {
/*Show dialog containing options
* 1) Edit Profile Picture
* 2) Edit Cover Photo
* 3) Edit Name
* 4) Edit Profile Status*/
//options to show in dialog
String options[] = {"Edit Profile Picture", "Edit Cover Photo", "Edit Name", "Edit Profile Status"};
//alert dialog
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
//set title
builder.setTitle("Profile Settings");
//set items to dialog
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//handle dialog items clicks
if(which == 0){
//edit profile clicked
pd.setMessage("Updating Profile Picture");
profileOrCoverPhoto = "image"; //i.e. changing profile picture, make sure to assign same value
showImagePicDialog();
}
else if (which == 1){
//edit cover clicked
pd.setMessage("Updating Cover Image");
profileOrCoverPhoto = "cover"; //i.e. changing cover photo+, make sure to assign same value
showImagePicDialog();
}
else if (which == 2){
//edit name clicked
pd.setMessage("Updating Name");
//calling method and pass key "name" as parameter to update its value in database
showNameProfileStatusUpdateDialog("name");
}
else if (which == 3){
//edit phone clicked
pd.setMessage("Updating Profile Status");
showNameProfileStatusUpdateDialog("profileStatus");
}
}
});
//create and show dialog
builder.create().show();
}
private void showNameProfileStatusUpdateDialog(final String key) {
/*parameter "key" will contain value name and phone*/
//custom dialog
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme);
builder.setTitle("Update");
//set layout of dialog
LinearLayout linearLayout = new LinearLayout(getActivity());
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setPadding(10,10,10,10);
//add edit text
final EditText editText = new EditText(getActivity());
editText.setHint("Write here");
linearLayout.addView(editText);
builder.setView(linearLayout);
//add button to dialog to update
builder.setPositiveButton("Update", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//input text from edittext
final String value = editText.getText().toString().trim();
if (!TextUtils.isEmpty(value)){
pd.show();
HashMap<String, Object> result = new HashMap<>();
result.put(key, value);
databaseReference.child(user.getUid()).updateChildren(result)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
//updated, dismiss progress
pd.dismiss();
Toast.makeText(getActivity(), "Updated", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
//failed updating progress. dismiss progress and show error message
pd.dismiss();
Toast.makeText(getActivity(), ""+e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
//if user edit his name, also change it from hist posts
if (key.equals("name")){
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Posts");
Query query = ref.orderByChild("uid").equalTo(uid);
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
String child = ds.getKey();
dataSnapshot.getRef().child(child).child("uName").setValue(value);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
//update name in current users comments on posts
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
String child = ds.getKey();
if (dataSnapshot.child(child).hasChild("Comments")){
String child1 = ""+dataSnapshot.child(child).getKey();
Query child2 = FirebaseDatabase.getInstance().getReference("Posts").child(child1).child("Comments").orderByChild(uid).equalTo(uid);
child2.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
String child = ds.getKey();
dataSnapshot.getRef().child(child).child("uName").setValue(value);
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
else{
Toast.makeText(getActivity(), "Please enter"+key, Toast.LENGTH_SHORT).show();
}
}
});
//add button to dialog to cancel the update
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
//create and show dialog
builder.create().show();
}
private void showImagePicDialog() {
//show dialog containing options camera and gallery to pick the image
String options[] = {"Camera", "Gallery"};
//alert dialog
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
//set title
builder.setTitle("Pick Image From");
//set items to dialog
builder.setItems(options, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//handle dialog items clicks
if(which == 0){
//camera clicked
if (!checkCameraPermissions()){
requestCameraPermission();
}
else {
pickFromCamera();
}
}
else if (which == 1){
//gallery clicked
if (!checkStoragePermissions()){
requestStoragePermission();
}
else{
pickFromGallery();
}
}
}
});
//create and show dialog
builder.create().show();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
/*This method called when user press Allow or Deny from permission request dialog
* here we will handle permissions cases (allowed & denied)*/
switch (requestCode){
case CAMERA_REQUEST_CODE: {
//picking from camera, first check if camera and storage permission allowed or not
if (grantResults.length > 0){
boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean writeStorageAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
if (cameraAccepted && writeStorageAccepted){
//permissions enabled
pickFromCamera();
}
else{
//permission denied
Toast.makeText(getActivity(), "Please enable camera and storage permissions", Toast.LENGTH_SHORT).show();
}
}
}
break;
case STORAGE_REQUEST_CODE: {
//picking from gallery, first check if storage permission allowed or not
if (grantResults.length > 0){
boolean writeStorageAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (writeStorageAccepted){
//permissions enabled
pickFromGallery();
}
else{
//permission deniad
Toast.makeText(getActivity(), "Please enable storage permissions", Toast.LENGTH_SHORT).show();
}
}
}
break;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
/*this method will be called after picking image from camera or gallery*/
if (resultCode == RESULT_OK){
if (requestCode == IMAGE_PICK_GALLERY_CODE){
//image is picked from gallery, get uri of image
image_uri = data.getData();
uploadProfileCoverPhoto(image_uri);
}
if (requestCode == IMAGE_PICK_CAMERA_CODE){
//image is picked from camera, get uri of image
uploadProfileCoverPhoto(image_uri);
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void uploadProfileCoverPhoto(final Uri uri) {
//show progress
pd.show();
/*Instead of creating separate function for profile picture and cover photo this will work in the same function*/
//path and name of image to be stored in firebase storage
String filePathAndName = storagePath+ ""+ profileOrCoverPhoto +"_"+ user.getUid();
StorageReference storageReference2nd = storageReference.child(filePathAndName);
storageReference2nd.putFile(uri)
.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
@Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
//image uploaded to storage, now get its url and store in users database
Task<Uri> uriTask = taskSnapshot.getStorage().getDownloadUrl();
while (!uriTask.isSuccessful());
final Uri downloadUri = uriTask.getResult();
//check if image is uploading or not and url received
if (uriTask.isSuccessful()){
//image uploaded
//add/update url in users database
HashMap<String, Object> results = new HashMap<>();
/*first parameter is profileorcover photo thas has value "image" or "cover" which are keys in users database where url of the image
* be saved in of them
* Second parameter contains the url of the image stored in firebase storage, this url will be saved as value against key "image" or "cover"*/
results.put(profileOrCoverPhoto, downloadUri.toString());
databaseReference.child(user.getUid()).updateChildren(results)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
//URL IN DATA BASE of user is add succesfully
//dismiss progress bar
pd.dismiss();
Toast.makeText(getActivity(), "Image Updated.", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
//error adding url in database of user
//dismiss progress bar
pd.dismiss();
Toast.makeText(getActivity(), "An error occurred updating the image.", Toast.LENGTH_SHORT).show();
}
});
//if user edit his name, also change it from hist posts
if (profileOrCoverPhoto.equals("image")){
DatabaseReference ref = FirebaseDatabase.getInstance().getReference("Posts");
Query query = ref.orderByChild("uid").equalTo(uid);
query.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
String child = ds.getKey();
dataSnapshot.getRef().child(child).child("uDp").setValue(downloadUri.toString());
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
//update user image in current users comments on posts
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
String child = ds.getKey();
if (dataSnapshot.child(child).hasChild("Comments")){
String child1 = ""+dataSnapshot.child(child).getKey();
Query child2 = FirebaseDatabase.getInstance().getReference("Posts").child(child1).child("Comments").orderByChild(uid).equalTo(uid);
child2.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds: dataSnapshot.getChildren()){
String child = ds.getKey();
dataSnapshot.getRef().child(child).child("uDp").setValue(downloadUri.toString());
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
}
else{
//error
pd.dismiss();
Toast.makeText(getActivity(), "An error has occurred.", Toast.LENGTH_SHORT).show();
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
//there were some error, get and show error message, dismiss progress dialog
pd.dismiss();
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void pickFromCamera() {
//intent of picking image from device camera
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "Temp Pic");
values.put(MediaStore.Images.Media.DESCRIPTION, "Temp Description");
//put image uri
image_uri = getActivity().getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
//intent to start camera
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
}
private void pickFromGallery() {
//pick from gallery
Intent galleryIntent = new Intent(Intent.ACTION_PICK);
galleryIntent.setType("image/*");
startActivityForResult(galleryIntent, IMAGE_PICK_GALLERY_CODE);
}