In my ArrayAdapter I have an AlertDialog with a button. Now I want to use ActivityForResult for that. In this simple code I can use an Intent to view the other Activity but I can not get passed data from it in ArrayAdapter.
public class AdapterReceiveSMS extends ArrayAdapter<ReceivedItemStructure> {
private myDialog dialog;
public AdapterReceiveSMS(ArrayList<ReceivedItemStructure> array) {
super(G.context, R.layout.rsms, array);
}
/* ----- Clicking on Forward Button ----- */
forward_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(
G.activityDialogContext);
View vForward = G.inflater.inflate(R.layout.forward, null);
builder.setView(vForward);
final AlertDialog sms_dialog = builder.create();
sms_dialog.show();
from_file.setOnClickListener ( new View.OnClickListener () {
#Override
public void onClick (View v) {
Intent fileBrowser = new Intent(G.activity,ActivityFileBrwoser.class);
G.activity.startActivityForResult ( fileBrowser, 1 );
}
} );
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) {
}
}
onActivityResult in an overridden method of Activity class and called when an activity you launched exits, giving you the requestCode you started it with, the resultCode it returned, and any additional data from it.”
you started the activity using this code
G.activity.startActivityForResult ( fileBrowser, 1 );
you must put your onActivityResult method in your calling activity ( I mean activity in which you are creating the object of AdapterReceiveSMS class. )
You can't add a callback method to a class and hope that the system calls it. onActivityResult belongs to your Activity which then can pass the information to your adapter.
Related
I am trying to implement RecyclerView in a small project and ran into some problem. My adapter works fine for adding new elements, but doesn't do anything when I edit existing ones.
For creating a new element I use FloatingActionButton in my fragment and send an appropiate request code. For editing an element I tried implementing onClickListener() in onBindViewHolder(). Here's the code:
#Override
public void onBindViewHolder(RecyclerViewAdapter.EventViewHolder holder, int position) {
final Event event = mEvents.get(position);
holder.mLabel.setText(event.getLabel());
holder.mComment.setText(event.getComment());
holder.mStartTime.setText(DateFormat.format("HH:mm", event.getTime()));
holder.mDuration.setText(event.getDurationInFormat(mContext));
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(mContext.getApplicationContext(), EventCreatorActivity.class);
intent.putExtra(EX_EVENT_ID, event.getId());
intent.putExtra(EX_DAY_ID, event.getParent().getId());
((Activity) mContext).startActivityForResult(intent, DayViewFragment.RC_EDIT);
}
});
}
(itemView is where I keep the entire element view, and the Textviews are just components).
Here's where I initialize the RecyclerViewAdapter:
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// Restore data after app-configuration
if(savedInstanceState != null && !savedInstanceState.isEmpty())
mDay = Day.findDayById(UUID.fromString(savedInstanceState.getString(DAY_ID)));
else
mDay = new Day(Calendar.getInstance().getTime());
adapter = new RecyclerViewAdapter(getActivity(), new ArrayList<Event>());
adapter.updateDataSet(mDay.getEvents());
adapter.notifyDataSetChanged();
}
And here's where I recieve the results in the fragment:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(resultCode != Activity.RESULT_OK)
return;
UUID eventId = (UUID)data.getSerializableExtra(EventCreatorFragment.EX_EVENT_ID);
Event event = mDay.findEventById(eventId);
switch (requestCode){
case RC_EDIT:{
int previousPosition = adapter.getPreviousPosition(eventId);
if(previousPosition == mDay.getIndex(event))
adapter.notifyItemChanged(mDay.getIndex(event));
else {
adapter.updateDataSet(mDay.getEvents());
adapter.notifyItemMoved(previousPosition, mDay.getIndex(event));
}
} break;
case RC_ADD:{
adapter.updateDataSet(mDay.getEvents());
adapter.notifyItemInserted(mDay.getIndex(event));
} break;
}
}
Here's where I set the result, in the fragment of the activity which creates\edits new elements:
public void sendResult(){
Intent data = new Intent();
data.putExtra(EX_EVENT_ID, mThisEvent.getId());
getActivity().setResult(Activity.RESULT_OK, data);
}
A few things worth noting:
As I said, adding new elements work just fine.
When an element is clicked, it sends for the EvenetCreatorActivity just fine, and there it shows the data has been edited successfuly (The various values change).
I traced through the code, and onActivityResult() isn't called at all after editing an element.
I've read online that it's possible that the activity that's supposed to get the results is destroyed for some reason, but it isn't the case.
Would appreciate your help.
You will receive at onActivityResult at Fragment only if you used the fragment context for startActivityForResult but you are using Activity... the onActivityResult will get back to the Activity that is the context from the adapter.
I have created two Activities.
Main Activity.java(This is the activity that application launches with, user click on a button called "Show timer" which takes the user to the next activity)
displayTimer.java(This is the second activity which has a ListView, with data in each row. on item click users comes back to the main activity)
I'm trying to pass the string stored in that row to the main activity.
This is the main code from display timer activity
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.user_list_view);
listView = (ListView) findViewById(R.id.customtimer_listview);
customTimerAdapter = new CustomTimerAdapter(this, R.layout.row);
BackGroundTask backGroundTask = new BackGroundTask(this);
backGroundTask.execute("Get_info");
registerForContextMenu(listView);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
TextView textView = (TextView) view.findViewById(R.id.time_entered);
String timeRetrevied = textView.getText().toString();
//System.out.println(timeRetrevied);
Intent intentExtras = new Intent(displayTimer.this,MainActivity.class);
intentExtras.putExtra("TIME_DATA",timeRetrevied);
setResult(RESULT_OK, intentExtras);
//startActivityForResult(intentExtras,SECOND_ACTIVITY_REQUEST_CODE,null);
finish();
}
});
}
This is the code from the Main activity where i'm calling the method onActivityResult to get the data through intent from displaytimer. But i'm not able to get the data. Dont know what i'm doing wrong. Any input with be fine.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SECOND_ACTIVITY_REQUEST_CODE){
if (resultCode == RESULT_OK) {
int setTimer = Integer.parseInt(data.getDataString());
System.out.println(setTimer);
seekbar.setProgress(setTimer * 60);
updateTimer(setTimer);
}
else{
System.out.println("Not Ok");
}
}
System.out.println("RequestCode failed");
}
}
Instead of
data.getDataString()
use
data.getStringExtra("TIME_DATA")
getDataString returns the URI in the encoded String format, which is not what you require as you are not passing in the data.
As you are passing in the Sting text with ID=TIME_DATA, use the same ID to get the string back using the getStringExtra("TIME_DATA");
I am doing task in which I need to show a dialog after clicking on EditText. In that dialog I show contents with RadioButtons using RecyclerView.
Now, what I want to do is, after selecting RadioButton (content which is in the RecyclerView) from dialog, it should return value of that content and then dialog should be dismissed.
To generate a dialog I've used a DialogFragment.
As I'm new in android development, I am totally confused and unable to find the solution.
Because your dialog is a DialogFragment you can use two things
If you are starting the dialog from a Activity, you can use an interface
create an interface
public interface ISelectedData {
void onSelectedData(String string);
}
implement an interface in your Activity
public class MyActivity implements ISelectedData {
.....
#Override
public void onSelectedData(String myValue) {
// Use the returned value
}
}
in your Dialog, attach the interface to your Activity
private ISelectedData mCallback;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mCallback = (ISelectedData) activity;
}
catch (ClassCastException e) {
Log.d("MyDialog", "Activity doesn't implement the ISelectedData interface");
}
}
when returning the value to Activity, just call in your Dialog
mCallback.onSelectedData("myValue");
Check the example on the Android developer site.
If you are starting the dialog from a Fragment, you can use setTargetFragment(...)
starting the Dialog
MyDialog dialog = new MyDialog();
dialog.setTargetFragment(this, Constants.DIALOG_REQUEST_CODE);
dialog.show(fragmentManager, Constants.DIALOG);
returning the value from the Dialog
Bundle bundle = new Bundle();
bundle.putString(Constants.MY_VALUE, "MyValue");
Intent intent = new Intent().putExtras(bundle);
getTargetFragment().onActivityResult(getTargetRequestCode(), Activity.RESULT_OK, intent);
dismiss();
getting the value in Fragment
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Constants.DIALOG_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
if (data.getExtras().containsKey(Constants.MY_VALUE)) {
String myValue = data.getExtras().getString(Constants.MY_VALUE);
// Use the returned value
}
}
}
}
I am confused and have no idea on how to use the startActivityResults and setResults to get data from previous activity. I have a view class and a activity class.
Basically in my view class i have this dialog and it will actually start the activity class called the colorActivity class. When user selects yes also it will pass the name of the selected circle to the colorActivity class. At the colorActivity class, users are allowed to enter color code for a particular circle and i would like to pass the color code back to the view class. I have problems passing values from activity back to view using the startActivityForResult and setResult method. Adding on, how to make use of the fetched data afterthat?
my code are as follows
Ontouchevent code from my view class:
#Override
public boolean onTouchEvent(MotionEvent event) {
x = event.getX();
y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
for (int i = 0; i < circles.size(); i++) {
if (circles.get(i).contains(x, y)) {
circleID = i;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
AlertDialog.Builder builder = new Builder(
getContext());
final EditText text = new EditText(getContext());
builder.setTitle("Adding colors to circles").setMessage(
"Proceed to Enter color");
builder.setPositiveButton("Yes",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface di,
int i) {
Intent intent = new Intent(
getContext(),
colorActivity.class);
intent.putExtra("circlename", circleNameList.get(circleID));
startActivityForResults(intent, 1); // error incurred here : The method startActivityForResult(Intent, int) is undefined for the type new DialogInterface.OnClickListener(){}
}
});
builder.setNegativeButton("No",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface di,
int i) {
}
});
builder.create().show();
}
}, 3000);
break;
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) { // Please, use a final int instead of hardcoded
// int value
if (resultCode == RESULT_OK) {
ccode = (String) data.getExtras().getString("colorcode");
}
}
}
public static String getColorCode() {
return ccode;
}
In the colorActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_ecolor);
circlenametextview = (TextView)findViewById(R.id.circlenametextview);
String circlename = super.getIntent().getStringExtra("circlename");
circlenametextview.setText(circlename);//get the circle name
savebutton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
Intent intent = new Intent(colorActivity.this, ?????);//how to return back to the view class?
colorcode = colorEditText.getText().toString();// I am able to get value right up till this point
Intent resultIntent = new Intent();
resultIntent.putExtra("colorcode", colorcode );
setResult(Activity.RESULT_OK, resultIntent);
finish();
}// onclick
});
}
After correcting the other code so that you can run the program, you can retrieve parameters back from your activity colorActivity in this way:
Step1: return some value from colorActivity
Intent resultIntent = new Intent();
resultIntent.putExtra("NAME OF THE PARAMETER", valueOfParameter);
...
setResult(Activity.RESULT_OK, resultIntent);
finish();
Step 2: collect data from the Main Activity
Overriding #onActivityResult(...).
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1) { // Please, use a final int instead of hardcoded int value
if (resultCode == RESULT_OK) {
String value = (String) data.getExtras().getString("NAME OF THE PARAMETER");
References
http://developer.android.com/training/basics/intents/result.html
How to manage `startActivityForResult` on Android?
http://steveliles.github.io/returning_a_result_from_an_android_activity.html
STARTACTIVITYFORRESULT IS NOW DEPRECATED
Alternative to it and recommended solution is to use Activity Result API
You can use this code, written in Kotlin language:
Create ResultLauncher:
private var resultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data: Intent? = result.data
if (null != data && data.getBooleanExtra("REFRESH_PAGE", false)) {
//do your code here
}
}
}
start Activity by using above result launcher:
val intent = Intent(this, XYZActivity::class.java)
resultLauncher.launch(intent)
Return result from XYZActivity by
val resultIntent = Intent()
resultIntent.putExtra("REFRESH_PAGE", true)
setResult(Activity.RESULT_OK, resultIntent)
finish()
try using
ActivityName.this.startActivityForResult(intent,int)
Oh, and 1 small thing, in your code you have used
startActivityForResults(intent,int) ..replace that with
startActivityForResult(intent,int)
I have the following scenario in Fragment :
onCreateView(){
view = inflater.inflate(R.layout.mylayout, container, false);
ScrollView sc = (scrollView)view.findViewById(R.id.sc);
generateUI()
return view; }
public void generateUI() {
horizontalllayout = new LinearLayout(getActivity());
horizontalllayout.setOrientation(android.widget.LinearLayout.HORIZONTAL);
Button newbtn = new Button(getActivity());
newbtn.setId(1);
horizontalllayout.addView(newbtn);
newbtn.setOnClickListener(
public void onClick(View v) {
Intent CaputureIntent = new Intent(getActivity(), s.class);
startActivityForResult(CaputureIntent, 664);
} });
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == 1666){
populate("hi");
}
}
public void populate(String str) {
Button b = (Button)getActivity().findViewbyId(1); //Error
b.setText(str);
}
}
I am not able to receive the context. The text on the button is not changed in populate() method , when I call from onActivityResult(). If I call the same method from outside every thing is working fine. Can anyone help me in sorting out this issue.
assuming Button is deined inside your layout file and your code is typed correctly, set b to be accessible through whole your code by defining b in your class:
Button b;
and then access b inside onCreateView() like this:
b = (Button)view .findViewbyId(1);
inside onActivityResult just use b however you like it:
b.setText(str);