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
}
}
}
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 some troubles to display images in OpenGL.
Actually I'm able to display images from gallery in opengl. The problem occurs when I try to show one from the camera.
For me, OpenGL have to display the image from the camera as it does with the gallery ones. Obviously I'm making something wrong.
Any help will be appreciated.
Intent from gallery:
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/");
startActivityForResult(intent, 2);
Intent from camera:
Intent takePic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePic.resolveActivity(getPackageManager()) != null) {
File imagen = controler.createPhotoFile(getExternalFilesDir(Environment.DIRECTORY_PICTURES));
if (imagen != null) {
photoUri = FileProvider.getUriForFile(this, "my.fileprovider", imagen);
takePic.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(takePic, 1);
}
}
This is my onActivityResult where I send the URI to a method which convert it to a bitmap and send it.
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case 1:
sendImagenPanel(photoUri);
break;
case 2:
sendImagenPanel(data.getData());
break;
}
}
}
private void sendImagenPanel(Uri uri) {
Bitmap bitmap = null;
try {
bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri);
} catch (IOException e) {
e.printStackTrace();
}
final Bitmap imagen = controler.getCroppedBitmap(controler.scaledBitmap(bitmap, 256));
final CasillaOG casilla = ((GLSurfacePanel) gLViewPanel).getRendererPanel().getCuboSelected();
gLViewPanel.queueEvent(new Runnable() {
#Override
public void run() {
casilla.loadNewTexture(imagen);
casilla.setImagen(imagen);
}
});
gLViewPanel.requestRender();
}
In case someone is interested. I realize that the problem is not on the method that calls OpenGL. If I run the same code on the onActivityResult works from the gallery requestCode but not on the camera one, in my Samsung Galaxy Tab A. Why I mention my device? because if I run the app on a Huawei P9 lite, the gallery images are not display either. In both cases appears the next problem on the console:
call to opengl es api with no current context (logged once per thread)
After search that problem, I suppose that the intents of the camera and gallery use OpenGL and its originate a conflict with my own OpenGL environment.
Finally, I opted to set a bitmap field and add the texture in on the onDrawFrame. Obviously, with a boolean to make it one time.
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.
}
}
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 am making an android album app where I can create an album and add photos and delete photos from the album. Adding a photo is a bit tricky where I need a photo filename with a file path. This was very easy using JFileChooser in java but this is android and I have no clue on getting the filename and file path. Is there any thing in the android api where I can get the same functionality as the JFileChooser.
I am looking for a solution to this problem either using a file chooser of some sort or an entire to new approach. Any help is appreciated..
Or is there any other approach I can implement to add a photo...
You may use Intent.ACTION_PICK to invoke an image picker. This intent may be caught by the default gallery app, or some other app installed on the device.
private static final int REQUEST_PICKER = 1;
private void invokePicker() {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
intent.setType("image/*");
startActivityForResult(Intent.createChooser(intent, "Complete action using"), REQUEST_PICKER);
}
Then receive the result on onActivityResult.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK)
return;
if (requestCode == PICK_FROM_FILE) {
// Get Uri of the file selected,
Uri theImageUri = data.getData();
// Or if you want a Bitmap,
Bitmap theBitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), theImageUri);
}
}
Edited:
Though in this way you don't need a real file path, you can get it from MediaStore if you need.