andbook!.pdf - Learning Android Get an anddev.org - Android-Shirt Back to index
anddev.org Header Logo
FAQ Search Top rated articles Browse Feeds anddev.org - Authors Contact Details Register Log in

SubActivites with return value - The InputBox

Goto page 1, 2  Next
 
       anddev.org - Android Development Community | Android Tutorials | Index -> Novice Tutorials
Author Message
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2655
Location: College Park, MD

PostPosted: Sat Nov 24, 2007 1:35 pm    Post subject: SubActivites with return value - The InputBox Reply with quote

SubActivites with return value - The InputBox


What you learn: You will learn how to start a SubActivity, that will return a String (+ extra Data), what is in the end exactly like an InputBox.

Question Problems/Questions: Write them right below...

Difficulty: 1 of 5 Smile

What it will look like:


Description
This has been a very common question, as in "normal" Java you can make a blocking a MessageBox was displayed with code like:
Java:
public static String JOptionPane.showInputDialog(Component parentComponent, Object message);
// Example implementation:
String retString = JOptionPane.showInputDialog(this,"Enter your name:");

in Android you can't really do fully blocking Dialogs, imagine what should happen if there is an incoming phone-call Question
showAlert, will not help us, as it is a non-blocking dialog. Remember:
Java:
showAlert("A funny title", "MessageBoxes rule extremely!", "Hit Me!", false);


But there is a pretty easy workaround for doing so...

0. Lets quickly define the Strings we are going to use
XML:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="main_app_name">MainActivity - anddev.org</string>
    <string name="main_cmd_opensub">Open SubActivity</string>
    <string name="sub_app_name">SubActivity returning Result - anddev.org</string>
    <string name="subactivity_cmd_return">Return to MainActivity</string>
</resources>


1. What we need to do is the follwoing:
  1. Override the onActivityResult(...)-method coming from Activity to react on a Activity we opened, that returned sth. .
  2. Start that Activity that will return sth. to us, using: startSubActivity(...)
  3. Call setResult(int resultCode, String data) within our (sub)Activity and close it.

Arrow The onActivityResult(...)-method in our MainActivity will be called Exclamation

2. So this is the layout-file of the MainActivity (we simply need a button, nothing more):
We need to add the id-attribute to the Button, because we need to add an OnClickListener to it.
For basic information about XML-Layouting, take a look Arrow here.


"/res/layout/main.xml"
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
>

     <Button  id="@+id/mainactivity_cmd_opensub"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:text="@string/main_cmd_opensub"
    />

</LinearLayout>


"/src/your_package_structure/MainActivity.java"
Java:
package org.anddev.android.subactivitywithresult;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
    protected static final int SUB_ACTIVITY_REQUEST_CODE = 1337;

     /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        // Apply our main.xml-Layout
        setContentView(R.layout.main);
       
        // Find the button defined in the main.xml
        Button cmd_opensub = (Button)findViewById(R.id.mainactivity_cmd_opensub);
        // Add an OnClickListener to it, that will open the SubActivity
        cmd_opensub.setOnClickListener(new OnClickListener(){
               // @Override
               public void onClick(View arg0) {
                    Intent i = new Intent(MainActivity.this,
                                             SubActivityWithResult.class);
                    // We use SUB_ACTIVITY_REQUEST_CODE as an 'identifier'
                    startSubActivity(i, SUB_ACTIVITY_REQUEST_CODE);
               }
        });        
    }
   
     @Override
     protected void onActivityResult(int requestCode, int resultCode,
                                        String data, Bundle extras) {
          super.onActivityResult(requestCode, resultCode, data, extras);
          // Here We identify the subActivity we starte
          if(requestCode == SUB_ACTIVITY_REQUEST_CODE){
               // And show its result
               showAlert("SubActivity returned", "ReturnValue: " + data,
                                   "OK", false);
          }
     }
}


3.Now lets take a look at the SubActivity.xml (provides an EditText to enter the return-String and a "Return to Main"-Button and the SubActivityWithResult-Class, which is also well commented:

"/res/layout/subactivity.xml"
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

    <EditText id="@+id/subactivity_edit_returnvalue"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:background="@android:drawable/editbox_background"
         android:singleLine="true"
    />

     <Button id="@+id/subactivity_cmd_return"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
         android:text="@string/subactivity_cmd_return"
    />

</LinearLayout>


"/src/your_package_structure/SubActivityWithResult.java"
Java:
package org.anddev.android.subactivitywithresult;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;


public class SubActivityWithResult extends Activity{
     
     protected final int SUCCESS_RETURN_CODE = 1;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
     // Apply our subactivity.xml-Layout
        setContentView(R.layout.subactivity);
       
        // Find the button defined in the subactivity.xml
        Button cmd_return = (Button)findViewById(R.id.subactivity_cmd_return);
        /* Add an OnClickListener to it, that will
         * read out the text in the EditBox set it
         * as retrn-data and close this activity */

        cmd_return.setOnClickListener(new OnClickListener(){
               // @Override
               public void onClick(View arg0) {
                    // Find the edittext defined in the subactivity.xml
                    EditText edit_returvalue = (EditText)findViewById(
                              R.id.subactivity_edit_returnvalue);
                    SubActivityWithResult.this.setResult(SUCCESS_RETURN_CODE,
                              edit_returvalue.getText().toString());
                    // Close this Activity
                    SubActivityWithResult.this.finish();
               }
        });      
    }
}


4. And finally the AndroidManifets.xml which was has to be altered like the following:
XML:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.anddev.android.subactivitywithresult">

    <application android:icon="@drawable/icon">
        <activity class=".MainActivity" android:label="@string/main_app_name">
            <intent-filter>
                <action android:value="android.intent.action.MAIN" />
                <category android:value="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity class=".SubActivityWithResult" android:label="@string/sub_app_name">
            <intent-filter>
                <action android:value="android.intent.action.VIEW" />
                <category android:value="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>


Arrow Thats it, you can easily transform this into a generic InputBox, or just use it somewhere it fits.

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials


Last edited by plusminus on Mon Dec 17, 2007 7:06 pm; edited 3 times in total
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Nitinkcv
Developer
Developer


Joined: 29 Nov 2007
Posts: 29

PostPosted: Mon Dec 03, 2007 10:03 am    Post subject: Can we do it the other way round Reply with quote

Hi,

My query goes something like this.
1)
My first screen contains the textbox and the button. Next i input some code into the textbox and click on the button.
It opens up another activity which actually displays or shows an alert of whatever i had inputted in my first screen(activity)

2)
Also i require to send back an array of strings back to the calling intent. But the current method only allows me to send a string param.

Thanks,
Nitin
Back to top
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2655
Location: College Park, MD

PostPosted: Mon Dec 03, 2007 3:43 pm    Post subject: Reply with quote

Hey Nitinkcv,

the setResult(..) got another Overload, with a Bundle (what is just like a pimped HashMap):
Java:
Activity.setResult(int, java.lang.String, android.os.Bundle);


The Bundle you had filled somewhere in the SubActivity from above gets passed to the onActivityResult(...)-method of the calling Activity:
Java:
protected void onActivityResult(int requestCode, int resultCode,
                String data, Bundle extras)


You can easily put/get various Types to a Bundle, even StringArrays:
Java:
Bundle.putStringArray(java.lang.String, java.lang.String[])
Bundle.getStringArray(java.lang.String)

See Googles JavaDoc for Bundle: android.os.Bundle

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Nitinkcv
Developer
Developer


Joined: 29 Nov 2007
Posts: 29

PostPosted: Mon Dec 03, 2007 6:42 pm    Post subject: ClassCastException!! Reply with quote

Hi,

How silly of me.. i should have searched for the overloaded methods. thanks a lot.

Right now i have a main class(main.java) which extends activity and another class(sub.java) which extends
ListActivity. I pass a value from my main.java to the sub.java by using the Intent along with Bundle class.
Now in my sub.java based on the value passed i populate a listview:

one of the methods in the sub.java having the problem:

Java:

protected void SearchForText(String searchText){
     
     for (Iterator iterator = codeEntries.iterator(); iterator.hasNext();) {
               String type = (String) iterator.next();
               if(type.contains(searchText)){
                    searchEntries.add(searchText);
               }
          }
     ArrayAdapter<String> SearchList = new ArrayAdapter<String>(this,
                R.layout.filesearchlayout, this.searchEntries);
     
     this.setListAdapter(SearchList);
    }

/*where*/
    private List<String> codeEntries = new ArrayList<String>();
    private List<String> searchEntries = new ArrayList<String>();
   



However on running the app i find that an classcastexception in thrown in the sub.java.
i debugged and everthing seemed ok till the line where searchList was being assigned. All the search entries were getting populated in the List searchEntries.

But after the line this.setListAdapter(SearchList), on hitting F6 it went into some source files and then the ClassCastException was being hit.

What could be the reason? Sad is it because the Intent is served from the Activity class while its in the ListView that the Intent is received.

Also do we ALWAYS have to override the method onActivityResult in the class where StartSubActivity is called?

Thanks,
Nitin
Back to top
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2655
Location: College Park, MD

PostPosted: Mon Dec 03, 2007 8:46 pm    Post subject: Re: ClassCastException!! Reply with quote

Hey Nitinkcv,

most of the time the solution is just one click away, or we just look right over it. I know what i'm talking about ... Rolling Eyes
Nitinkcv wrote:
Hi,
...
But after the line this.setListAdapter(SearchList), on hitting F6 it went into some source files and then the ClassCastException was being hit.


Hm, that is strange... Exclamation Is the Exception thrown at or after the line you said Question
I tried it with me and it works fine. Which of the parameters does the ClassCastException refer to Question as it cannot be this.searchEntries (by logical thinking and its type). The others look also very right:!:

Nitinkcv wrote:
What could be the reason? Sad is it because the Intent is served from the Activity class while its in the ListView that the Intent is received.

Don't think that it happens because of the Intent as it only starts your Activity (???) and thats it. But if it was so, there would probably be no ClassCastException...

Nitinkcv wrote:
Also do we ALWAYS have to override the method onActivityResult in the class where StartSubActivity is called?

No you don't have to as there is sth. like a default-procedure in the onActivityResult(..) from the Baseclass: Activity we are overriding.

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Nitinkcv
Developer
Developer


Joined: 29 Nov 2007
Posts: 29

PostPosted: Tue Dec 04, 2007 2:38 pm    Post subject: ClassCastException Reply with quote

A trivial mistake. i had given the layout file which is being used by my main.java.
this had the relative layout Smile

just had another query. is it possible for me to retain a layout having a textbox and then a list of items.
what i mean is that my sub.java which extends the listactivity would have a textbox at the top plus the list of all the search entries?

Similar to the sorts of MasterPages in .Net 2.0

Thanks,
Nitin
Back to top
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2655
Location: College Park, MD

PostPosted: Tue Dec 04, 2007 3:52 pm    Post subject: Reply with quote

Hello Nitincv,

yes it it possible, like it is even possible, to have a EditText, a MapView and Buttons in one layout Exclamation
Arrow Have a look here.

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Nitinkcv
Developer
Developer


Joined: 29 Nov 2007
Posts: 29

PostPosted: Tue Dec 04, 2007 4:43 pm    Post subject: Source code for Link. Reply with quote

Hi,

Would be eagerly waiting to get my hands on the source code of that map app.

Thanks,
Nitin
Back to top
View user's profile Send private message Send e-mail AIM Address Yahoo Messenger
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2655
Location: College Park, MD

PostPosted: Tue Dec 04, 2007 4:54 pm    Post subject: Reply with quote

Hi Nitinkcv,

I have nothing received so far. Will post it there immediately if lordhong finished cleaning up the code Smile

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
venkat
Senior Developer
Senior Developer


Joined: 27 Nov 2007
Posts: 152
Location: India

PostPosted: Wed Dec 12, 2007 6:10 pm    Post subject: Reply with quote

i run above program and when i press the "Open Sub Activity" button it will show Error message:(. i have attached error screen shot. i can't fix that error. can u any one help me to solve this problem.

regads,
venkat.



mainActivity.png
 Description:
Error message.
 Filesize:  23.51 KB
 Viewed:  21178 Time(s)

mainActivity.png


Back to top
View user's profile Send private message
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2655
Location: College Park, MD

PostPosted: Wed Dec 12, 2007 6:43 pm    Post subject: Reply with quote

Hello venkat,

read closely between the lines, there it says: "plusminus forgot to append the altered AndroisManifest.xml Exclamation " Wink
XML:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.anddev.android.subactivitywithresult">

    <application android:icon="@drawable/icon">
        <activity class=".MainActivity" android:label="@string/main_app_name">
            <intent-filter>
                <action android:value="android.intent.action.MAIN" />
                <category android:value="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity class=".SubActivityWithResult" android:label="@string/sub_app_name">
            <intent-filter>
                <action android:value="android.intent.action.VIEW" />
                <category android:value="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
    </application>
</manifest>


Appended it above too.

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
venkat
Senior Developer
Senior Developer


Joined: 27 Nov 2007
Posts: 152
Location: India

PostPosted: Thu Dec 13, 2007 7:21 am    Post subject: Reply with quote

Thank you very much Plusminus Wink Smile
Back to top
View user's profile Send private message
bloonlabs
Freshman
Freshman


Joined: 04 Dec 2007
Posts: 7

PostPosted: Sun Jan 20, 2008 10:55 pm    Post subject: Reply with quote

Ok so I was working on my seperate class today for my app and I keep on coming to the same problem. When I finish the subActivity it just closes the entire program. According to my code it should go back to my main class which will then do stuff. Here is my code:

The subActivity finish():
Java:

        Button b_save = (Button) findViewById(R.id.b_save);
        b_save.setOnClickListener(new Button.OnClickListener() {
            public void onClick(View v) {
               editor.commit();
               Options.this.setResult(RESULT_OK);
               Options.this.finish();
            }
        });


The main class:
Java:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, String data, Bundle extras) {
     super.onActivityResult(requestCode, resultCode, data, extras);
     if (requestCode == ACTIVITY_OPTIONS) {
          if (resultCode == RESULT_OK) restartWilfred();
          else if (resultCode == RESULT_CANCELED) gotoMainScreen();
     }
    }


More code can be found at the svn: http://projectwilfred.googlecode.com/svn/

Thanks!!

_________________
~Bloonlabs
http://www.bloonlabs.com
Back to top
View user's profile Send private message Visit poster's website
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2655
Location: College Park, MD

PostPosted: Sun Jan 20, 2008 11:40 pm    Post subject: Reply with quote

Hello bloonlabs,

the debugger never reaches the onActivityResult(...) Question Try to ensure such stuff with some logging ( Log.d(...) ).

Thats pretty strange... Confused
Your code looks right Exclamation , but the error has to hide somewhere.
Perhaps you used some IDs that should not be used. Confused Try the ID-Values from this tutorial, because they did work with me.

You could try to run exactly the same code from the tutorial, because I can ensure that it works. If it doesn't your problem is perhaps a problem of the emulator. Sad

Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
venkat
Senior Developer
Senior Developer


Joined: 27 Nov 2007
Posts: 152
Location: India

PostPosted: Mon Feb 04, 2008 12:27 pm    Post subject: Reply with quote

Hi plus minus,
Above code is very help full to me. now, I have a problem.
Can you tell me , how to pass value from "activity" to "sub Activity"? (or)
can you tell me how to declare global veriable?

_________________
Regards,
Venkat.
Back to top
View user's profile Send private message
Display posts from previous:   
       anddev.org - Android Development Community | Android Tutorials | Index -> Novice Tutorials All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


© 2007, Android Development Community
All rights reserved.
Powered by phpBB.