I can't get the normal taken picture by my phone in java. Everything is working while I choose picture from the gallery which is screenshot but when It's normal taken picture it's not returning anything. I will give you some parts of the code where u can see how I'm getting picture.
#Override
public void onActivityResult(int reqCode, int resultCode, final Intent data) {
super.onActivityResult(reqCode, resultCode, data);
if (reqCode == PICK_IMAGE && resultCode == Activity.RESULT_OK) {
final Uri imageUri = data.getData();
final String path = getPath(getActivity(), imageUri);
if (path != null) {
try {
File f1 = new File(path);
final AsyncHttpClient client = new AsyncHttpClient(true, 80, 443);
client.addHeader("accept", "application/json");
final RequestParams params = new RequestParams();
params.put("id", id);
params.put("token", token);
params.put("avatar", f1);
And also this
add_avatar.setOnClickListener(new View.OnClickListener() {
#TargetApi(Build.VERSION_CODES.M)
#Override
public void onClick(View view) {
// filePickUtils.requestImageGallery(STORAGE_PERMISSION_IMAGE, true, true);
if (getActivity().checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(
android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
// Explain to the user why we need to read the contacts
}
requestPermissions(new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
1);
// MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
// app-defined int constant that should be quite unique
return;
}
if (getActivity().checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (shouldShowRequestPermissionRationale(
android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
// Explain to the user why we need to read the contacts
}
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
1);
// MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
// app-defined int constant that should be quite unique
return;
}
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
photoPickerIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
photoPickerIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, PICK_IMAGE);
}
});
What would you suggest?
Thanks for your help
Given that you only need to read the image, and upload the data to your backend server, I'd suggest if you use Intent.ACTION_GET_CONTENT instead of Intent.ACTION_PICK.
Why
Your problem might related to what Intent.ACTION_PICK needs to have. The documentation stated:
Input: getData() is URI containing a directory of data (vnd.android.cursor.dir/*) from which to pick an item.
So it means, if you want to use Intent.ACTION_PICK, you need to provide the directory of the data.
Meanwhile if you use Intent.ACTION_GET_CONTENT, you can just set the MIME type of the file that you want to search (just as what you are doing now), and use Context.startActivity(intent).
Additional note from the documentation that you might want to read:
Input: getType() is the desired MIME type to retrieve. Note that no URI is supplied in the intent, as there are no constraints on where the returned data originally comes from. You may also include the CATEGORY_OPENABLE if you can only accept data that can be opened as a stream. You may use EXTRA_LOCAL_ONLY to limit content selection to local data. You may use EXTRA_ALLOW_MULTIPLE to allow the user to select multiple items.
Output: The URI of the item that was picked. This must be a content: URI so that any receiver can access it.
Add a comment here, if you need further information.
Sample Code:
In your activity
private searchImageFile() {
Intent intent = new Intent(Intent.GET_CONTENT);
// Filter to only show results that can be "opened"
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Filter to show only images, using the image MIME data type.
// it would be "*/*".
intent.setType("image/*");
startActivityForResult(intent, READ_REQUEST_CODE);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
final Uri imageUri = resultData.getData();
//Do something with your Uri.
}
}
Related
I'm currently learning how to use android studio in java and am trying to make a social media app. I am currently creating an edit profile page where the user would update their details and upload a profile picture.
I have been following tutorials online and all of the ones I have come across use the startActivityForResult method. It has been crossed out and wont call the method as it is deprecated. But I don't know what to use instead.
`ProfileImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//open gallery
Intent OpenGalleryIntent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(OpenGalleryIntent, 1000);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #androidx.annotation.Nullable Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1000){
if(resultCode == Activity.RESULT_OK){
Uri imageUri = data.getData();
ProfileImage.setImageURI(imageUri);
UploadImageToFirebase(imageUri);
}
}
}
private void UploadImageToFirebase(Uri image){
StorageReference fileRef = storageReference.child("Profile.jpg");
fileRef.putFile(image).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(Edit_Profile.this, "Image Uploaded", Toast.LENGTH_SHORT).show();
}
});![enter image description here](https://i.stack.imgur.com/padRc.jpg)`
I know there is an alternative but I don't understand how it works.
startActivityForResult is indeed deprecated in later versions of AndroidX Activity and Fragment APIs (while I believe you can still use it despite of warning). New way to get result from activity is registerForActivityResult.
In your code you would need to create a launcher, which will handle result (selected image)
private final ActivityResultLauncher<Intent> launcher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == Activity.RESULT_OK
&& result.getData() != null) {
Uri photoUri = result.getData().getData();
//use photoUri here
}
}
);
and then launch this launcher in onClickListener
profileImage.setOnClickListener(view -> {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
launcher.launch(intent);
});
Yes startActivityForeResult is deprecated.
Now you can use ActivityResultLauncher for the callbacks
https://developer.android.com/training/basics/intents/result#java
I have an app where it is possible to create an user and this work perfectly and I am happy!
In a simple way, here is a method that adds the user to the Firebase database:
public void addUserInfoToDatabase(){
String user_id = mAuth.getCurrentUser().getUid();
final DatabaseReference the_user_database = FirebaseDatabase.getInstance().getReference().child("UserRegistraion").child(user_id);
Map userAttributes = new HashMap();
userAttributes.put("user_id", user_id);
userAttributes.put("username", userName);
userAttributes.put("name", name);
userAttributes.put("e-mail", email);
the_user_database.setValue(userAttributes);
if (mRegistrationListener != null)
mRegistrationListener.onRegistrationComplete(true); // Assumes success
}
And here is how the table looks when the user is registered:
What I want to do now is that I want the possibility to add a profile picture which belongs to each user: e,g a profile picture, family-picture etc.
The question is: how can i do this in Firebase? I am not asking anyone to do this for me, but just to give me a good tip or provide a guide/video for how to do this.
Thank you.
I usually create a separate activity for setting up a profile photo. Maybe instead of calling onRegistrationComplete call an onCompleteListener after setValue(userAttributes) like this:
the_user_database.setValue(userAttributes).addOnCompleteListener(new OnCompleteListener...){
Intent intent = new Intent(context, AddProfileActivity.class);
startActivity(intent);
In the next activity it could be a simple XML layout with a button and an ImageView.
This code can open your gallery, select an image, and place it in your imageview in the onActivityResult method:
private void selectPhotoFromGallery(){
Log.d(TAG, "selectPhotoFromGallery: started");
Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, GALLERY_PICK);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == GALLERY_PICK){
if (resultCode == RESULT_OK && data != null){
contentUri = data.getData();
try{
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), contentUri);
profile_photo.setImageBitmap(bitmap);
}catch (IOException e){
Toast.makeText(mContext, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
}
You would then need a method to upload your image to FirebaseStorage and capture the downloadUrl to add to the desired node. In this case because you are adding to an existing node you call updateChildren() when adding the profile photo. I use a method like this:
private void uploadProfileImage(){
Log.d(TAG, "uploadProfileImage: uploading image....");
if (contentUri != null){
//from gallery
final StorageReference reference = FirebaseStorage.getInstance().getReference().child(currentUserID).child("profile_photo");
reference.putFile(contentUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
reference.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
String profilePhotoUri = uri.toString();
DatabaseReference publicUserReference = FirebaseDatabase.getInstance().getReference().child("public_user")
.child(currentUserID);
HashMap hashMap = new HashMap();
hashMap.put("profile_photo", profilePhotoUri);
publicUserReference.updateChildren(hashMap).addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
if (task.isSuccessful()){
Intent intent = new Intent(mContext, CompleteProfileActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
}
});
}
});
}
});
}
}
You would need to adjust this for your specific needs obviously. The thing you are really trying to do is to save an image to Storage and get the http://... string location where it is stored and then insert that information into the same location as the previous information you provided.
I hope this counts as a helpful tip. https://www.youtube.com/watch?v=mPOhnTnLcSY That's a link to a video about uploading images to Firebase storage for more information if you need it. Good luck!
I am trying to fetch a file this way:
final Intent chooseFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
String[] mimetypes = {"application/pdf"};
chooseFileIntent.setType("*/*");
chooseFileIntent.addCategory(Intent.CATEGORY_OPENABLE);
if (chooseFileIntent.resolveActivity(activity
.getApplicationContext().getPackageManager()) != null) {
chooseFileIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
activity.startActivityForResult(chooseFileIntent, Uploader.PDF);
}
Then in onActivityResult :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
According to many threads I'm supposed to fetch the file name from the intent with data.getData().getPath(), the file name I'm expecting is my_file.pdf, but instead I'm getting this :
/document/acc=1;doc=28
So what to do? Thanks for your help.
I am trying to fetch a file
Not with that code. That code is asking the user to pick a piece of content. This may or may not be a file.
According to many threads I'm supposed to fetch the file name from the intent with data.getData().getPath()
That was never correct, though it tended to work on older versions of Android.
So what to do?
Well, that depends.
If you wish to only accept files, integrate a file chooser library instead of using ACTION_GET_CONTENT. (UPDATE 2019-04-06: since Android Q is banning most filesystem access, this solution is no longer practical)
If you are willing to allow the user to pick a piece of content using ACTION_GET_CONTENT, please understand that it does not have to be a file and it does not have to have something that resembles a filename. The closest that you will get:
If getScheme() of the Uri returns file, your original algorithm will work
If getScheme() of the Uri returns content, use DocumentFile.fromSingleUri() to create a DocumentFile, then call getName() on that DocumentFile — this should return a "display name" which should be recognizable to the user
To get the real name and to avoid getting a name that looks like "image: 4431" or even just a number, you can write code as recommended by CommonsWare.
The following is an example of a code that selects a single pdf file, prints its name and path to the log, and then sends the file by email using its uri.
private static final int FILEPICKER_RESULT_CODE = 1;
private static final int SEND_EMAIL_RESULT_CODE = 2;
private Uri fileUri;
private void chooseFile() {
Intent fileChooser = new Intent(Intent.ACTION_GET_CONTENT);
fileChooser.setType("application/pdf");
startActivityForResult(Intent.createChooser(fileChooser, "Choose one pdf file"), FILEPICKER_RESULT_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILEPICKER_RESULT_CODE) {
if (resultCode == RESULT_OK) {
fileUri = data != null ? data.getData() : null;
if (fileUri != null) {
DocumentFile d = DocumentFile.fromSingleUri(this, fileUri);
if (d != null) {
Log.d("TAG", "file name: " + d.getName());
Log.d("TAG", "file path: " + d.getUri().getPath());
sendEmail(fileUri);
}
}
}
}
}
private void sendEmail(Uri path) {
String email = "example#gmail.com";
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("application/octet-stream");
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "PDF file");
String[] to = { email };
intent.putExtra(Intent.EXTRA_EMAIL, to);
intent.putExtra(Intent.EXTRA_TEXT, "This is the pdf file...");
intent.putExtra(Intent.EXTRA_STREAM, path);
startActivityForResult(Intent.createChooser(intent, "Send mail..."), SEND_EMAIL_RESULT_CODE);
}
hope it helps.
I'm trying to allow a user to select an image from their gallery to replace an existing one in my activity (which was programatically added based on DB values). Here's the portion of my code that's causing some issues:
public void requestImage(int imageID){
Intent intent = new Intent();
intent.putExtra("imageID",imageID);
intent.setType("image/*");
Log.v("requestImage",Integer.toString(intent.getIntExtra("imageID",0)));
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), 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) {
Uri uri = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
int imageID = data.getIntExtra("imageID",0);
Log.v("onactivityresult",Integer.toString(imageID));
} catch (IOException e) {
e.printStackTrace();
}
}
}
The goal is to get the ID of the image that was selected for this function, which I'm passing in to requestImage, through to onActivityResult. onActivityResult contains the code for setting the image's bitmap based on the image selected by the user (omitted from code sample for conciseness).
Note the two logging statements, which result in:
05-27 15:51:31.756 7769-7769/com.praytoday.app.praytoday V/requestImage: 12
05-27 15:45:55.511 2037-2037/com.praytoday.app.praytoday V/onactivityresult: 0
As you'll notice in the logging statements, the first log is actually getting the int from the intent itself, so I am certain it's being set correctly (and there aren't any type issues here).
It seems to me that data must not be the same intent (please excuse my lack of knowledge on the subject of intents - this is pretty new to me).
Things that I have tried:
Using getIntent() instead of data
Not using the createChooser, and instead just using the plain intent
Looking at every question/answer about this I could find
Any help in determining why this extra value is not in the data argument would be much appreciated! Thanks in advance.
I went ahead and just set a global variable to store which image is currently set for replacement. requestImage sets it to the current image ID, and then onActivityResult uses that variable. Not very elegant, but it works!
I'm trying to get a program to let the user to import a custom background.
Here's where I'm at:
I have the getDrawable function taking another function as an argument:
mDrawableBg = getResources().getDrawable(getImage());
getImage() is suppose to return a integer referencing the selected image, here is the code (so far) for that function:
public int getImage(){
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 10);
}
This is suppose to open the gallery and let the user select an image. I would then use mDrawableBg to set the background. I'm not sure how to return a reference ID to that selected image though. Any suggestions?
Try this:
String pathName = "selected Image path";
Resources res = getResources();
Bitmap bitmap = BitmapFactory.decodeFile(pathName);
BitmapDrawable bd = new BitmapDrawable(res, bitmap);
View view = findViewById(R.id.container);
view.setBackgroundDrawable(bd);
The way you're attempting to do it is not possible, I'm afraid. One of the things you'll want to learn as a new Android developer is how the cycle between activities works. In your case, you're running an Activity that calls upon an Intent to get data from it. However, in the Android API, an Intent can only be referenced on its own time. This means you can't use your getImage() method the way you had tried.
There is hope, though!
What you first need to do is call the Intent. You will do this through the code you have now in getImage():
public void getImage() { // This has to be a void!
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 10);
}
This method will now start the Image Picker that you want users to select from. Next, you have to catch what is returned. This cannot be returned from your getImage() method, but instead must be collected from elsewhere.
You must implement the below method:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
final int SELECT_PICTURE = 1; // Hardcoded from API
if (requestCode == SELECT_PICTURE) {
String pathToImage = data.getData().getPath(); // Get path to image, returned by the image picker Intent
mDrawableBg = Drawable.createFromPath(pathToImage); // Get a Drawable from the path
}
}
}
Lastly, instead of calling mDrawableBg = getResources().getDrawable(getImage());, just call getImage();. This will initialize the Image Picker.
Some reading:
Android Activity (notably stuff about Intents and getting a result back)
Android Drawable
Getting a Drawable from a path
More on the Image Picker Intent
Good luck!
I'm not sure, but if you mean you don't know how to receive results from that intent, you can use :
#Override
protected void onActivityResult(int requestCode,int resultCode,Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK)
{
if (requestCode == 10)
{
// DoSomething
}
}
}