I have a fragment within an activity and I am using a button to select a notification sound using the ringtone picker:
selectSound.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_NOTIFICATION);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Select Tone");
if (notification != null) {
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, (Uri) notification);
}
Log.v("TASKS", "Starting Ringtone picker for reminders");
startActivityForResult(intent, 5001);
}
});
Here's my onActivityResult in the fragment:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.v("TASKS", "onActivityResult in ReminderSettings: " + requestCode);
if (resultCode == Activity.RESULT_OK && requestCode == 5001)
{
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
SharedPreferences settings =
mActivity.getSharedPreferences("SETTINGS", Context.MODE_PRIVATE);
Editor editor = settings.edit();
if (uri != null)
{
editor.putString("NOTIFICATION_SOUND", uri.toString());
}
else
{
editor.putString("NOTIFICATION_SOUND", null);
}
editor.commit();
}
}
My activity has an onActivityResult but it does make call for unhandled results:
#Override
protected void onActivityResult(
int requestCode, int resultCode, Intent data) {
...
super.onActivityResult(requestCode, resultCode, data);
}
The strange thing is after launching and selecting a ringtone neither onActivityResult in the fragment or the activity are called when I debug and the activity seems to finish - there is no force close or exception on the Logcat. I have tested this now on 2 different devices and I get the same result - I'm using ActionBarSherlock for fragments if thats relevant.
Related
I am trying to launch an activity after a user has selected a photo. I was trying to do this:
uploadImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent selectImageIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
selectImageIntent.setType("image/*");
startActivityForResult(selectImageIntent, 1);
Intent goToActivityIntent = new Intent(view.getContext(), SendPhotoChangeActivity.class);
goToActivityIntent.putExtra("email", email);
goToActivityIntent.putExtra("donorEmail", donorEmail);
goToActivityIntent.putExtra("orderId", orderId);
goToActivityIntent.putExtra("uriString", uriString);
view.getContext().startActivity(goToActivityIntent);
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && data != null) {
uriString = data.getData().toString();
}
}
But I realised that with this code, the code for launching the activity (SendPhotoChangeActivity) executes before the user selects the image, crashing the app because the uriString variable is null.
I tried simply copy/pasting the code into onActivityResult(), but the view variable (in view.getContext()) was, of course, not recognized in onActivityResult().
I am thinking of simply replacing view.getContext() by getApplicationContext() in onActivityResult(). Is this the right thing to do? If not, please tell me how I can start an activity in onActivityResult().
If you are in Activity then you can just use this as Context
Intent goToActivityIntent = new Intent(this, SendPhotoChangeActivity.class);
If you are in a Fragment then you can obtain Context by calling getContext()
Intent goToActivityIntent = new Intent(getContext(), SendPhotoChangeActivity.class);
And use that code inside onActivityResult() as you were trying to.
set an integer code for the act of selecting a picture like REQUEST_CODE_TAKE_PICTURE so you know that has happened, this works ok in Kotlin, I assume that works as well with java:
if (requestCode == REQUEST_CODE_TAKE_PICTURE && resultCode == Activity.RESULT_OK) {
Intent goToActivityIntent = new Intent(view.getContext(),SendPhotoChangeActivity.class);
goToActivityIntent.putExtra("email", email);
goToActivityIntent.putExtra("donorEmail", donorEmail);
goToActivityIntent.putExtra("orderId", orderId);
goToActivityIntent.putExtra("uriString", uriString);
view.getContext().startActivity(goToActivityIntent);
if (data == null) {
//Display an error
println("error accuered at onActivityResult ")
return
}
Have you tried this simpler one:
uploadImageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent selectImageIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
selectImageIntent.setType("image/*");
startActivityForResult(selectImageIntent, 1);
}
});
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && data != null) {
uriString = data.getData().toString();
Intent goToActivityIntent = new Intent(view.getContext(), SendPhotoChangeActivity.class);
goToActivityIntent.putExtra("email", email);
goToActivityIntent.putExtra("donorEmail", donorEmail);
goToActivityIntent.putExtra("orderId", orderId);
goToActivityIntent.putExtra("uriString", uriString);
startActivity(goToActivityIntent);
}
}
Just call
startActivity(goToActivityIntent);
to call the activity.
This assumes you are calling it from your activity or fragment. If this doesn't meet your requirements, let me know. There are other ways to implement this.
I am wondering if using a Chooser means you can't send extra custom data to the receiving intent?
I call a file selection intent like this
public static void receiveFiles(final AppCompatActivity activity, int which) {
Intent receiveIntent = new Intent(Intent.ACTION_GET_CONTENT);
receiveIntent.setType("text/comma-separated-values");
String[] mimetypes = {"text/csv", "text/comma-separated-values", "application/csv"};
receiveIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
receiveIntent.addCategory(Intent.CATEGORY_OPENABLE);
receiveIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, false);
receiveIntent.putExtra(IMPORT_OPTION_WHICH, which); //this line
activity.startActivityForResult(Intent.createChooser(receiveIntent, "Pick CSV"), REQUEST_IMPORT_CSV);
}
But then in onActivityResult after the user selects a file:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case REQUEST_IMPORT_CSV:
if (data != null) {
Uri uri = data.getData(); //is correct
int which = data.getIntExtra(IMPORT_OPTION_WHICH, -1);
//but this always -1!
}
break;
}
}
}
How can I get it to correctly extract the value I passed into the intent?
I know there are several questions about this, but I don't found a solution for my problem.
I have ActivityA which extends AppCompatActivity. It starts an ActivityB
Activity A
Intent intent = new Intent(this, ActivityB.class);
intent.putExtra("data", data);
startActivityForResult(intent, 1);
....
#Override
protected void onActivityResult(int requestCode, int result, Intent intent) {
super.onActivityResult(requestCode, result, intent);
if (requestCode != 1) { // check code
return;
}
if (intent == null) { // HERE INTENT IS NULL
return;
}
}
Activity B
// code called when an asynctask is done
Intent i = new Intent();
i.putExtra("dataone", "test");
i.putExtra("datatwo", objet);
setResult(RESULT_OK, i);
finish();
I don't understand why intent is null in onActivityResult() method.
Two things. I would refactor your code like the following:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
// example
// String myString = intent.getString("myStringFrom2ndActivity")
}
}
}
and also make sure that you are calling the right RESULT_OK. It should be something like Activity.RESULT_OK.
I try onActivityResult in fragment currently I am using v4 fragment.
my activity code
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.v(tag, "0000");
for (Fragment fragment : getSupportFragmentManager().getFragments()) {
fragment.onActivityResult(requestCode, resultCode, data);
}
super.onActivityResult(requestCode, resultCode, data);
}
My fragment code
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.v(getTag(), "in 0");
if (resultCode == Activity.RESULT_OK) {
Log.v(getTag(), "in 1");
if (requestCode == MY_INTENT_CLICK) {
Log.v(getTag(), "in 2");
if (null == data)
return;
Log.v(getTag(), "in 3");
Uri selectedImageUri = data.getData(); } } }
I call start Intent in
Log.v(getTag(), "in 00");
Intent intent = new Intent();
Log.v(getTag(), "in 01");
intent.setType("video/*");
Log.v(getTag(), "in 02");
intent.setAction(Intent.ACTION_GET_CONTENT);
Log.v(getTag(), "in 03");
fragment.startActivityForResult(Intent
.createChooser(intent,
"Select a file"),
MY_INTENT_CLICK);
I also try call intent in
getActivity().startActivityForResult(Intent
.createChooser(intent,
"Select a file"),
MY_INTENT_CLICK);
startActivityForResult(Intent
.createChooser(intent,
"Select a file"),
MY_INTENT_CLICK);
But noting is work. I also refer.
Fragment Compatability onActivityResult() Not Working
onActivityResult is not being called in Fragment
onActivityResult() not called in new nested fragment API
Refer below code
public class RegisterDeRegisterResponse {
private Vector<IResultResponse> _iCallBack = new Vector<IResultResponse>();
public static RegisterDeRegisterResponse ref = null;
public static RegisterDeRegisterResponse getInstance() {
if (ref == null) {
ref = new RegisterDeRegisterResponse();
}
return ref;
}
/**
* Register to recieve server response.
*/
public void registerForServerResponse(IResultResponse callback) {
_iCallBack.addElement(callback);
}
/**
* Notify all registered users about server response with corresponding
* process id.
*/
public void notifyRegisteredUser(int requestCode, int resultCode,
Intent data) {
Enumeration<IResultResponse> enumeration = _iCallBack.elements();
while (enumeration.hasMoreElements()) {
IResultResponse callback = enumeration.nextElement();
callback.onActivityResult(requestCode, resultCode, data);
}
}
/**
* Deregister to recieve server response
*/
public void deRegisterForServerResponse(IResultResponse callback) {
_iCallBack.removeElement(callback);
}
}
And also make Interface which have onActivityResult method declaration
public interface IResultResponse {
public void onActivityResult(int requestCode, int resultCode, Intent data);
}
Now in class in which you are calling startActivityForResult put this line before startActivityForResult and implement IresultResonse also
RegisterDeRegisterResponse register1 = RegisterDeRegisterResponse
.getInstance();
register1.registerForServerResponse(this);
and also deregister in onActivityResult
RegisterDeRegisterResponse
.getInstance().deRegisterForServerResponse((IResultResponse)this);
I'm doing a few dialogs pickers on my app and using a switch-case on my onClickListener but dialogs are calling for a onActivityResult{} but app is crashing if I add 2... Can I put them both in the same onActivityResult{} calling each by results codes? Code below:
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch(arg0.getId()){
case R.id.bContacts:
Intent i = new Intent(Intent.ACTION_PICK,
ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(i, PICK_CONTACT);
break;
case R.id.bRingtone:
String uri = null;
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "Select ringtone for notifications:");
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, false);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE,RingtoneManager.TYPE_NOTIFICATION);
startActivityForResult( intent, Set_Ringtone);
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent
data)
{
super.onActivityResult(requestCode, resultCode, data);
Cursor c = getContact(ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
if (c.moveToNext()) {
String name = c
.getString(c
.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME));
callName.setText(name);
String phoneNumber = c
.getString(c
.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER));
callNum.setText(phoneNumber);
Log.d("Cont", "name "+name+" no. " + phoneNumber);
}
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent intent)
{
if (resultCode == Activity.RESULT_OK && requestCode == 5)
{
Uri uri = intent.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
if (uri != null)
{
String ringTonePath = uri.toString();
Toast.makeText(this, "GOT IT" + ringTonePath, Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(this, "DIDNT", Toast.LENGTH_SHORT).show();
}
}
}
You can handle both intents in the same onActivityResult() method. That's why you send a request code with your intent when you call startActivityForResult(), you get it back when the result comes in to differentiate. Your method could look like this:
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode) {
case PICK_CONTACT:
// handle the contact result
break;
case Set_Ringtone:
// handle the ringtone result
break;
}
}
Your app most likely crashes because you try to work with details of the result that are not provided if you select the wrong intent (e.g. you try to read a contact name here, a ringtone result will not work with that).