Get onActivityResult not on the same class send startActivityForResult - android

I try to make the speech recognize as show in this link https://software.intel.com/en-us/articles/developing-android-applications-with-voice-recognition-features.
It uses a run() method to make it thread on the background, which I call it from the fragment like this SpeechRecognitionHelper.run(getActivity());
Then in show it use
ownerActivity.startActivityForResult(intent,SystemData.VOICE_RECOGNITION_REQUEST_CODE);
where the ownerActivity is the getActivity() I pass it on the run().
So I was thinking I can implement the onActivityResult(..) in the Fragment(which call the run() and get the result on the fly.
But it is showing me a mistake when trying so.
Can't I get the result in the Fragment if I specify it even I use it in anther class?
If not how can I get the result if I use the run() method? How get the result if I have to use also the startActivityForResult?

onActivityResult() is the only way you can get the speech recognition results from the recognizer activity.
If you invoke it from Activity.startActivityForResult(), you have to override Activity.onActivityResult() on that same Activity subclass to get the result.
If you invoke it from Fragment.startActivityForResult(), you have to override Fragment.onActivityResult() on that same Fragment subclass to get the result.

Can't I get the result in the Fragment if I specify it even I use it in anther class?
From the link you shared startRecognitionActivity method expected the Activity and uses the Activity context to start the Voice Recognition Activity , so the result will be passed to the activity. Modify the method to start the Activity from Fragment context.
private static void startRecognitionActivity(Fragment callerFragment) {
// create an Intent with “RecognizerIntent.ACTION_RECOGNIZE_SPEECH” action
// start Activity and wait for result on fragment
callerFragment.startActivityForResult(intent, SystemData.VOICE_RECOGNITION_REQUEST_CODE);
}
Now override the onActivityResult on Fragment class
// Fragment Results handler
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// handle the result
if (requestCode == SystemData.VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) {
// Do your stuff here
}
}

Related

Sending data to Activity without startActivityForResult

How can I send data to another Activity that did not startActivityForResult?
I Override the onActivityResult method in order to perform logic as soon as a result returns from another Activity. Specifically, from my EditItemActivity
Process:
Within my MainActivity,
when I click on an item in the ListView, I am redirected to another Activity called ToDoDetailActivity
When I click the Edit button I am redirector to another Activity called EditItemActivity"
As soon as I make my changes and press the Edit button on the EditItemActivity, I return back to the MainActivity
data = new Intent(EditItemActivity.this, MainActivity.class);
data.putExtra(EDITTEXT_VALUE, etValue);
setResult(123, data);
startActivity(data);
Within my MainActivity, I want to UPDATE the item I just edited with this logic within my onActivityResult method. However, I don't see any logs in LogCat meaning I do not believe this method is being used and therefore no logic is performed
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (data == null) {
return;
}
if (resultCode == 123) {
String editedItemValue = data.getStringExtra(EditItemActivity.EDITTEXT_VALUE);
todoItems.remove(editedPosition);
aToDoAdapter.insert(editedItemValue, editedPosition);
aToDoAdapter.notifyDataSetChanged();
}
}
In your code:
data = new Intent(EditItemActivity.this, MainActivity.class);
data.putExtra(EDITTEXT_VALUE, etValue);
setResult(123, data);
startActivity(data);
When you execute startActivity with MainActivity.class it is launching a new Activity so you are not going to find a result in "onActivityResult" method. It is because you are not returning to the main activity after finishing in a "child" activity.
What I have done in the past is use broadcast event to notify the "MainActivity" about updating the view.
Hope that helps.
We can use BroadcastReceiver or use database to store the result of your edit in EditItemActivity then update that result in onResume method of MainActivity

Returning to activity after onActivityResult?

So, here's the scenario.
There is one EditText which has its own TextWatcher set, used for setting the word count.
I also have a Navigation Drawer, Sliding, and in that have an option which launches a new Activity for result.
The result I want is the Target number of words the user wants to achieve, and then get the result from the user input and calculate the perecentage of target recived and set it to the text of a TextView in the Main Activity.
Now, the problem is :
Navigation Drawer has it's own ItemClickListener, and it exists as an independent View in the Activity. (Hidden, mostly, that is.)
And the Main Activity is different view.
How can I implement a correct OnActivityResultMethod so that I can return to the Activity's oncreate Method, techinically speaking, to the TextWatcher so that the calculation can be made and percentage be set.
Because the OnActivityResult is called automatically, so I cannot do anything to override it.
It has the data the app needs, but it is not called progmatically, so it cannot return values.
You can try this:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
Intent i = getIntent();
i.putExtras(data.getExtras()); // pass result data to onCreate()
startActivity(i);
finish();
}
Restarting the Activity is the only way to get back to onCreate().
EDIT:
Now, in your onCreate(), make a check:
Intent i = getIntent();
Bundle args = i.getExtras();
if(args != null){
....
}
and handle the data in the EditText here.
If you launch the Activity with an startActivityForResult() you can get the result very easily with an onActivityResult().
Check the code in this post and try it out.
How to manage `startActivityForResult` on Android?

Send data to activity which is running in background

Having trouble passing data between activities.
ListActivity is collecting data and when back button is pressed returns to MainActivity and then want to get that data via onResume method but I don't get anything.
How can this problem be solved?
ListActivity.java
#Override
public void finish() {
i = new Intent(ArrayListActivity.this, MainActivity.class);
i.putParcelableArrayListExtra(Constants.TAG_SELECTED_PRODUCT_LIST, selected_list);
super.finish();
}
MainActivity.java
#Override
protected void onResume() {
super.onResume();
Bundle extras = getIntent().getExtras().getBundle(Constants.TAG_SELECTED_PRODUCT_LIST);
if(extras != null) {
selected_list = extras.getParcelableArrayList(Constants.TAG_SELECTED_PRODUCT_LIST);
myListView.setAdapter(new ProductAdapter(MainActivity.this,
R.layout.array_lisviewt_item_row, selected_list));
}
}
You probably want to start your second activity from the first one via the startActivityForResult(...) method.
This method allows you to transport results from a launched activity back to it's launching activity.
From the documentation:
Launch an activity for which you would like a result when it finished.
When this activity exits, your onActivityResult() method will be
called with the given requestCode. Using a negative requestCode is the
same as calling startActivity(Intent) (the activity is not launched as
a sub-activity).
You'll want to start the activity with startActivityForResult() and override onActivityResult() to handle the data you return from the second Activity.
Check out this article on the Android developers site for more info.
Perhaps you should
Call your ListActivity with startActivityForResult(), from your MainActivity.
Once you finished working on the ListActivity, you call setResult() to set the data, followed by finish().
This will bring you back to your previous MainActivity. So how do you retrieve the data set by your ListActivity?
In MainActivity, override onActivityResult().
There's a brief explanation of this mechanism in Starting Activities and Getting Results.

Interaction between activities

I start an activity from the main one using a Intent:
Intent i = new Intent(getApplicationContext(), InfoChiamata.class);
i.putExtra("codice_cliente", codice_cliente[tv_clicked_id]);
i.putExtra("descrizione_chiamata", descrizione_chiamata[tv_clicked_id]);
startActivity(i);
How can I edit the main activity ui from the activity started whit Intent?
How can I know when i return back from the second activity to the main one? I tried to Override the onResume and onStart method but the application doesn't even start. I tryed to override onRestart method when it get called the application crash.
#Override
protected void onRestart() {
if(call_back == 1)
Toast.makeText(getApplicationContext(), "asd", Toast.LENGTH_LONG).show();
}
call_back variable is set to 1 from the secondary activity, when it is launched.
Thanks, Mattia
try startActivityForResult instead which gives you a callback to your first activity. also don't use the application context, unless absolutely necessary, use the activity context instead. Also when you call certain methods from the activity class and override them like onRestart or onStop or onResume you have to do super.onResume() inside the method first, making sure that the app life cycle is not broken.
Try starting your new Activity with
startActivityForResult(i, 1);
Then, in your main activity, use this code to catch when the user leaves the second activity and returns to the first one:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//your request code will be 1 since you started the
//activity with result 1. Your result code will be detemined
//by if the activity ended properly.
}
It sounds like maybe you want to use startActivityForResult(Context, Intent) to call your second activity. When you do this, your second activity can return a value to the activity that called it, and you can decide what to do from there. When the second activity is finished your first activity will receive a callback. This tells your first activity that the second one is finished and it is passed the result of what happened in the second activity.
It is explained in the Android docs here: http://developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent,%20int)

Custom View calling startActivityForResult

I created custom compound view where I incorporate functionality to take pictures.
I'm calling it like this (from view):
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
((Activity)mContext).startActivityForResult(intent, index);
This part works good. What I don't know how to do is how do I implement onActivityResult inside my custom view?
Or should I catch this inside Activity and than re-route into my view? Doesn't look like very nice solution..
You actually can do it like this:
#Override
public void onClick(View v) {
final FragmentManager fm = ((FragmentActivity) getContext()).getSupportFragmentManager();
Fragment auxiliary = new Fragment() {
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
//DO WHATEVER YOU NEED
super.onActivityResult(requestCode, resultCode, data);
fm.beginTransaction().remove(this).commit();
}
};
fm.beginTransaction().add(auxiliary, "FRAGMENT_TAG").commit();
fm.executePendingTransactions();
auxiliary.startActivityForResult(new Intent(getContext(), ToStartActivity.class), 3333);
}
The trick is using an auxiliary temp fragment.
I'm having the same issue, as the initial question. I know that you all posted working solution, BUT, all the solutions lack one thing: encapsulation. What do I mean - If in one activity I have 10 views that should (on some event) start another activity it should be NORMAL to be able to start that new activity from the view that needs that activity. You all are trying to convince that is better to handle all new possible activites from the initial one - than why we added different logic in each view. We may want to RE-USE code, and create one custom view that can work INDEPENDENT to where we use it (work may include showing another activity to select something for example).
I know that this is not possible (or not yet), and is a clear proof that Android SDK is not ready yet to handle real big applications.
If you want an example:in any real business app that has for example, customer list (that should be a view) ,the view should be able to launch by itself addcustomer activity, edit customer activity and so on, independent from where you put that customer list view (control) - because in big apps you need to RE-use components (you may need to show the customer list control in a order product activity, in a timesheet activity and so on.).
One possible solution could be:
- start the new activity (using the view context (normally should be the parent activity).
- on the new activity closing event, either call directly a method in the calling view (depending on the case, and posibilities: either static that is handling the code that you normally would run on activityresult, either try to pass the instance of the calling view to the new activity, and do the same. In this way, you can handle your new activity, without letting the containing activity to know anything about it.
You need to catch this from your activity. The startActivityForResult is called on your activity, so it'll be the one launching the Intent and getting the result. I'd say that it's overall bad to launch it directly from the view's code. A better solution would be with a clickListener (or checkChangeListener, or whatever you want), set by your activity, and calling a method like "openImageCapture".
When the Intent returns, your activity will take care of the result and update your views as needed.
Views are there just for displaying stuff on the screen and getting user input, the activity is there to do the actual work.
Here's a static function to implementing #riwnodennyk's solution, while overcoming the Fragment must be static and not in anonymous class error:
public static void myStartActivityForResult(FragmentActivity act, Intent in, int requestCode, OnActivityResult cb) {
Fragment aux = new FragmentForResult(cb);
FragmentManager fm = act.getSupportFragmentManager();
fm.beginTransaction().add(aux, "FRAGMENT_TAG").commit();
fm.executePendingTransactions();
aux.startActivityForResult(in, requestCode);
}
public interface OnActivityResult {
void onActivityResult(int requestCode, int resultCode, Intent data);
}
#SuppressLint("ValidFragment")
public static class FragmentForResult extends Fragment {
private OnActivityResult cb;
public FragmentForResult(OnActivityResult cb) {
this.cb = cb;
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (cb != null)
cb.onActivityResult(requestCode, resultCode, data);
super.onActivityResult(requestCode, resultCode, data);
getActivity().getSupportFragmentManager().beginTransaction().remove(this).commit();
}
}
Usage example:
Intent inPhonebook = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
myStartActivityForResult((FragmentActivity) getContext(),
inPhonebook, REQUEST_CODE_PICK_CONTACT, this::onContacts);
There is no way to catch onActivityResult from your view, only from Activity.
And its not safe to assume that's Context object is Activity. In general you should not rely on this fact. Even if it seems reasonable in case with views, you still should use only methods available trough Context interface. That's because your can't predict all side-effects on the Activity, when you're calling Activity specific functions.
Just make the same method inside your custom view
And inside the activitys onActivityResult call yourView.onActivityResult(...) and process the result inside your view..
Also as guys mentioned you must not always end up with Context being of Activity class. Usually when it is from inflated view.
But if you construct your view only in code and always use the activity instance you are good.

Categories

Resources