I am creating a chat application & for that purpose i have used TabHost.
In that first tab contains List of Buddies, and as soon as user clicks on any of the buddy
from buddy it should create another tab for that buddy in order to chat.
I am completed up to this but my problem is I am using a single Activity to perform Chat
but It always shows the same activity for each buddy.
Any Help will be highly appreciated. Here is my code,
public void onItemClick(AdapterView<?> arg0, View arg1, int position,
long arg3) {
RosterEntry entry = List.get(position);
String userName = entry.getName();
Intent intent = new Intent().setClass(RosterScreen.this,
com.spotonsoft.chatspot.ui.ChatScreen.class);
TabSpec tabSpec = Home.tabHost.newTabSpec("chat")
.setIndicator(userName).setContent(intent);
Home.tabHost.addTab(tabSpec);
}
Best Regards,
~Anup
in onCreate of ChatScreen you only setup basic stuff like getting View and store it in private fields
onResume you "recreate" ChatScreen with buddy-specific data ... how to do this (pls, read comments in code)?
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.*;
public class ChatScreen extends Activity {
TextView textview = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
textview = new TextView(this);
setContentView(textview);
}
#Override
public void onResume(){
super.onResume();
Intent intent = getIntent();
if(intent!=null){
//we read buddy-specific data here
textview.setText(intent.getStringExtra("chatwith"));
//we only setting textview with user name
//in real app you should store conversation somewere (fx in db)
//and load it here
}
}
}
and your code
Intent intent = new Intent().setClass(RosterScreen.this, com.spotonsoft.chatspot.ui.ChatScreen.class);
// you shoud add this line and provide some information fx useName or userID to ChatScreen Activity
intent.putExtra("chatwith", userName);
TabSpec tabSpec = Home.tabHost.newTabSpec("chat").setIndicator(userName).setContent(intent);
Home.tabHost.addTab(tabSpec);
You can add data to your intent before starting it, for example
intent.putExtra("user", userName);
In the onCreate of your activity you can read this data and use it to setup your activity.
Also, make sure that you have set the proper launchmode for your activity.
Related
I'm using The Complete Idiots Guide to Android App Development to get me started. I've been struggling through the book and I've come accross a problem that I don't understand. I'm creating a search class to add a search function to the app. I'm getting multiple errors in eclipse and the one I don't understand the most is
"Syntax error, insert "}" to complete ClassBody". I understand that Eclipse is telling me to close the class body, but it is closed. Just not where it's telling me to close it. Below where it's telling me to close it I have another method to enter.
Here is the code for the whole class.
package com.recipesapp;
import java.util.ArrayList;
import android.app.ListActivity;
import android.app.SearchManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.ListView;
public class RecipeSearch extends ListActivity{
#Override
public void onCreate(Bundle savedInstanceState){
//super.onCreate(savedInstanceState);
setContentView(R.layout.recipe_list);
Intent intent = getIntent();
if(Intent.ACTION_VIEW.equals(intent.getAction())){
//A search suggestion was clicked
Intent recipeIntent = new Intent(this, RecipeEntry.class);
recipeIntent.setData( intent.getData() );
startActivity(recipeIntent);
finish();
}
else if(Intent.ACTION_SEARCH.equals(intent.getAction())){
//The search was executed
String query = intent.getStringExtra(SearchManager.QUERY);
showRecipes(query);
}
}
private static final ArrayList<String> _RecipeSearchResults = new ArrayList<String>();
private ListView resultsView;
private void showRecipes(query){
SharedPreferences recipeNames = getSharedPreferences(MainMenu.RecipeNamesPref, RecipeEntry.MODE_WORLD_READABLE);
String[] recipeList= recipeNames.getString(MainMenu.RecipeNamesPref, null).split(",");
for(String recipe: recipeList){
if(recipe.contains(query))
ReicpeSearchResults.add(recipe);
resultsView=(ListView) findViewById(android.R.id.list);
resultsView.setAdapter(new ListViewAdapter(this));
resultsView.setTextFilterEnabled(true);
resultsView.setOnItemClickListener(this);
}
}
}
I know there are other errors, but I can't figure this one out. I've gone through and seen that I have all the curly brackets, open and closed. I don't understand why it wants to put in line 35, which is:
private ListView resultsView;
Also, it wants me to also delete the very last curly bracket. I would appreciate any help.
This is not the problem with curly brace. You missed a type for your method parameter
A method parameter should have type
Change this
showRecipes(query)
to
this
showRecipes(String query)
Your method private void showRecipes(query) does not contain a data type, that's why it is showing an error.
if you change it to something like this private void showRecipes(String query) it will stop showing } error.
Just move following line before onCreate function
private ListView resultsView;
private static final ArrayList<String> _RecipeSearchResults = new ArrayList<String>();
private ListView resultsView;
Both these two lines mentioned above are actually supposed to come before OnCreate
Where you are actually writing them. at that place every line is supposed to be inside some method.
#Override
public void onCreate(Bundle savedInstanceState){
//super.onCreate(savedInstanceState);
setContentView(R.layout.recipe_list);
Intent intent = getIntent();
if(Intent.ACTION_VIEW.equals(intent.getAction())){
//A search suggestion was clicked
Intent recipeIntent = new Intent(this, RecipeEntry.class);
recipeIntent.setData( intent.getData() );
startActivity(recipeIntent);
finish();
}
else if(Intent.ACTION_SEARCH.equals(intent.getAction())){
//The search was executed
String query = intent.getStringExtra(SearchManager.QUERY);
showRecipes(query);
}
More Over you are supposed to define tthe Data Type of the "query" parameter say String here in this case
private void showRecipes(String query){
SharedPreferences recipeNames = getSharedPreferences(MainMenu.RecipeNamesPref, RecipeEntry.MODE_WORLD_READABLE);
String[] recipeList= recipeNames.getString(MainMenu.RecipeNamesPref, null).split(",");
for(String recipe: recipeList){
if(recipe.contains(query))
ReicpeSearchResults.add(recipe);
resultsView=(ListView) findViewById(android.R.id.list);
resultsView.setAdapter(new ListViewAdapter(this));
resultsView.setTextFilterEnabled(true);
resultsView.setOnItemClickListener(this);
}
}
I new in the Android Programming and I want built a digital Schoolplan. For this I use a few Activities. I want create a plan and list them in a ListView that the User can click in the ListView on this Control and see all Homeworks and so.
Here is my Idea:
I build a Activity for the CreateMain:
public void createPlan(View view)
{
String PlanName;
Intent intent = new Intent(this,ListenActivity.class);
EditText planName = (EditText)findViewById(R.id.editText1);
PlanName = planName.getText().toString();
intent.putExtra(ListViewMessage, PlanName);
startActivity(intent);
}
And a Activity for show the create data in a ListView
import android.os.Bundle;
import android.view.Menu;
import java.util.List;
import android.app.ListActivity;
import android.widget.ArrayAdapter;
public class ListenActivity extends ListActivity {
private CommentsDataSource datasource;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_open);
datasource = new CommentsDataSource(this);
datasource.open();
List<Comment> values = datasource.getAllComments();
// Use the SimpleCursorAdapter to show the
// elements in a ListView
ArrayAdapter<Comment> adapter = new ArrayAdapter<Comment>(this,
android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
Comment comment = null;
String[] comments = new String[] { "t1", "t2", "t3" };
comment = datasource.createComment(comments[1]);
adapter.add(comment);
adapter.notifyDataSetChanged();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_list, menu);
return true;
}
}
But I don't know how I can use the data from the activity before for this activity in my ListView. I want to use a SQLite database but it don't work :(
There are few ways to pass data through Activities. Since you stored your information in a Bundle I will answer following that same logic.
If you didn't notice, you stored your information in the Intent's Extra Bundle in your createPlan method. After that, you started that Intent.
According to the official documentation:
"...extras -- This is a Bundle of any additional information. This can be used to provide extended information to the component. For example, if we have a action to send an e-mail message, we could also include extra pieces of data here to supply a subject, body, etc..."
So, to get that information you might use getIntent().getExtras() inside your ListenActivity to take back your Bundle and then you pass the key you used to store the plan's name using getIntent().getExtras().getString(your_key).
For example:
public class ListenActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
//...your stuff
String planName = getIntent().getExtras().getString(ListViewMessage);
//...your stuff
}
}
I don't recommend the use of SQLite to store small amount of data. If you really want to use it, there are very nice examples here.
So, I'm basically fooling around with some kind of login form, and trying to say a customized hello with the user name on the upcoming activity. The code compiles with no problem but the app crashes as soon as I click on the login button, the login worked successfully before I tried to implement the customized hello, so the problem has to be somewhere in the following code.
Here is where I call the activity:
Intent k = new Intent(this, MainActivity.class);
//Sends login name to activity k
k.putExtra("loginName", login.getText().toString());
//login is the EditText variable name for the login text field
startActivity(k);
Here is where I retrieve the extra data and try to use it as described:
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class ProfileActivity extends Activity {
TextView helloString;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
Bundle extras = getIntent().getExtras();
//Getting the hello text string
helloString = (TextView)findViewById(R.id.textHello);
String loginName = extras.getString("loginName");
helloString.setText("¡Hello, " + loginName + "!");
}
}
It somehow avoids the crash if I put in comment these two lines:
String loginName = extras.getString("loginName");
helloString.setText("¡Hello, " + loginName + "!");
Still, I can't be sure if the problem is really there or not, I thought it could have something to do with the type of data sent from the first activity not matching with the type being retrieved on the second, but still got no clue after trying some stuff around that.
Thanks in advance.
Editing:
I actually found out that I may have something to do with the fact that I am calling to mainActivity.class while the text is being shown in an activity called profileActivity.class, the problem is, profileActivity is being shown as a tab inside the mainActivity so I don't really know how should I approach that.
Editing 2:
So I solved it finally myself, for anyone interested I just sent the data to the MainActivity.class
Intent k = new Intent(this, MainActivity.class);
//Sends login name to activity k
k.putExtra("loginName", login.getText().toString());
startActivity(k);
And, inside the Main Activity, when calling the ProfileActivity to set it up as a tab:
//Profile tab
intent = new Intent(this, ProfileActivity.class);
Bundle extras = getIntent().getExtras();
intent.putExtra("loginName", extras.getString("loginName"));
spec = mTabHost.newTabSpec("home")
.setIndicator("Home", res.getDrawable(R.drawable.profile_icon))
.setContent(intent);
mTabHost.addTab(spec);
Problem solved, thanks for the help everyone anyways.
Your intent is refering to MainACtivity.class and you are trying to fetch the extras in ProfileActivity. Try changing the MainActivity.class to ProfileActivity.class if that is what your flow is.Please cross check your activities flow.
Hope it helps.
Intent k = new Intent(this, ProfileActivity.class);
//Sends login name to activity k
k.putExtra("loginName", login.getText().toString());
//login is the EditText variable name for the login text field
startActivity(k);
Since you stated that you want the data sent to ProfileActivity but need to open MainActivity, you can follow one of the 4 approaches.
NOTE: you should be checking when you use getExtra, that the returned value isn't null, and deal with it accordingly.
send the data first to the MainActivity, and then when you launch ProfileActivity from MainActivity, send the data that was previously passed in.
Put the data in a public static field in ProfileActivity. Public static variables can lead to issues, so I would recommend against this.
Save the data to a sharedPreferences file and read it when you need it in ProfileActivity.
SubClass Application, and you can set / access many variables there. The below was copied from Are static fields in Activity classes guaranteed to outlive a create/destroy cycle?:
public class MyApplication extends Application{
private String thing = null;
public String getThing(){
return thing;
}
public void setThing( String thing ){
this.thing = thing;
}
}
public class MyActivity extends Activity {
private MyApplication app;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = ((MyApplication)getApplication());
String thing = app.getThing();
}
}
On MainActivity:
String user = this.getIntent().getStringExtra("loginName");
And when you create the tabhost on MainActivity pass the string the same way:
Intent intent = new Intent().setClass(this, ProfileActivity.class);
intent.putExtra("loginName", user);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Initialize a TabSpec for each tab and add it to the TabHost
spec = mTabHost.newTabSpec("profile").setIndicator("Profile").setContent(intent);
mTabHost.addTab(spec);
Something like this.
But if you need the user name across the entire application use a Helper Class to store the user name.
I'm getting problems using the Intent for navigate through the screens. I want to send a variable and use it in the other class.
I'm using a method, the method takes the variable but i don't know how to send it with the intent to the new screen, which will use it to do some things.
Main class calls the metod:
private void pantallaDetalles(final int identificador)
{
startActivityForResult(new Intent(this,MostrarDetalles.class),REQST_CODE);
}
MostrarDetalles.class is the *.java which will take the variable. I'm begining it like this:
public class MostrarDetalles extends Activity {
SQLiteDatabase db;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.detalles);
//more code...
Cursor c = db.rawQuery("SELECT * FROM table WHERE _id="+ identificador, null);
}
Did you see? I'm talking about this. I don't know how to send the "identificador" variable from the main class to the second class through the Intent.
Can you help me with this? Thank you very much in advice.
JMasia.
Use the extras bundle in the intent.
Intent i = new Intent(...);
i.putExtra("name_of_extra", myObject);
Then on onCreate:
getIntent.getIntExtra("name_of_extra", -1);
Screen 1:
Intent i=new Intent("com.suatatan.app.Result");
i.putExtra("VAR_RESULT", "Added !");
startActivity(i);
Screen 2: (Receiver):
TextView tv_sonuc = (TextView) findViewById(R.id.tv_sonuc);
Bundle bundle = getIntent().getExtras();
String var_from_prev_intent = bundle.getString("VAR_RESULT");
tv_sonuc.setText(var_from_prev_intent);
You can use Intent.putExtra() to bundle the data you want to send with the intent.
I got 2 classes in my project. The first class(main) have a listview and this is the onclick():
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
// Get the item that was clicked
Object o = this.getListAdapter().getItem(position);
String keyword = o.toString();
class2 sec = new Class2();
Intent intent = new Intent(this, Class2.class);
startActivity(intent) ;
if (keyword == "hello"){
sec.setInfo(keyword);
}
}
so and then in my other class which have a defferent layout.xml. The code is:
public class det extends Activity {
static WebView map;
public TextView header;
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.details);
}
public void setInfo(String mystring){
header = (TextView) findViewById(R.id.text01);
header.setText(mystring);
//Toast.makeText(this, map, Toast.LENGTH_LONG).show();
//return;
}
Ye, i keep getting force close on my android phone. The App i meant to change the header text to text that ive tapped on the listview. But when i click a item it pop up a window with FC.
ive try to comment away the:
header = (TextView) findViewById(R.id.text01);
header.setText(mystring);
and it worked without a FC however the headertext is stil null.
Thank you!
Your Friend!
First of all, you need to post the stack trace for us to have any idea how to help.
Second, I'm assuming Class2 extends Activity or else Intent intent = new Intent(this, Class2.class); doesn't make any sense. That being the case, class2 sec = new Class2(); is ALWAYS wrong. You never ever call new on a class that extends Activity.
You can't call methods on another activity like that. Your only real option is to send the keyword in the intent by using putExtra, and then getting retrieving it in Class2