Calling an Intent in Android that is a variable - java

I currently have a list view and I'm trying to direct the list view to different activities. So that if you click an item from let's say 1-4 you'll get the class that corresponds to that. The only way that I can think of doing it is grabbing the text of the item in the list view and starting the activity of that name. The code for it would go something like this:
final String chosen = "";
chosen = (String) ((TextView) view).getText();
Intent nextScreen = new Intent(getApplicationContext(), chosen.class);
That does not work. I get an error on the last line, saying that chosen cannot be resolved into a type.
I know that ((TextView) view).getText() works because
Log.d("Debug", "Test"+((TextView) view).getText());
gives me the correct chosen item in logcat.
Any ideas/suggestions? Thanks in advance
EDIT:
I tried changing my code to this:
String chosen = (String) ((TextView) view).getText();
try {
Intent nextScreen = new Intent(getApplicationContext(), Class.forName(chosen));
startActivity(nextScreen);
Log.d("Debug", "Good"+((TextView) view).getText());
}
catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("Debug", "Bad"+((TextView) view).getText());
}
Log.d("Debug", "Final"+((TextView) view).getText());
Log cat gave me an output of
BadItem1
FinalItem1
I think I'm going about this the wrong way as someone pointed out. I also think I should be using OnItemClickListener. I will try it and post my results for easier help in the future.

The error is here:
final String chosen = "";
chosen = (String) ((TextView) view).getText();
Since you declare chosen as final, you can assign it a value only once:
final String chosen = (String) ((TextView) view).getText();
Moreover I suppose you want to start the Activity which has the name that is stored in variable chosen. You cannot write chosen.class for this. The correct way to do this is:
Class.forName(chosen);
Hope this helps!

There is no Intent constructor that takes a Context and a String. You can probably do something like Class.forName(chosen) in the call to the Intent constructor.

Calling .class on a variable gets the class for that variable, not the class for the content of the variable.
I think that you should use the OnItemClickListener on the ListView to identity the clicked item. The position parameter, or calling getItemAtPosition(position), should be enough to identify uniquely a item in the listview and call the appropriate activity.
See documentation here: http://developer.android.com/reference/android/widget/AdapterView.OnItemClickListener.html

Make a Factory.
This way you don't have to tie your class names to the text the user is reading. giving you more flexibility / better user experience / easier code to maintain. Helping with your separation of concerns as well.
class NavFactory {
private static final int CLASS_FIRST = 1;
public static Intent getNavIntent(Context context, String name){
switch(getId(name)){
case CLASS_FIRST:
return new Intent(context, FirstClass.class);
default:
return null;
}
}
private static int getId(String name){
if("listItemOneText".equals(name)
return CLASS_FIRST;
return -1;
}
}
Ref: Java Factory Pattern
In your case:
String chosen = (String) ((TextView) view).getText();
Intent nextScreen = NavFactory.getNavIntent(this, chosen);

You are new sending String as the class of supposed Activity. This is what you need:
final String chosen = "";
chosen = ((TextView) view).getText();
Class<?> chosenActivity = Class.forName(chosen);
Intent nextScreen = new Intent(this, chosenActivity);

Related

using putExtra and hasExtra for send and fetch multiple values

I have a Recycleview of multiple movie's poster. I tried to click each poster to start a new activity with details of the movie, now I've tried to use the details of movie like date and name of movie to be shared in detail activity so I used this code in MainActivity:
#Override
public void onClick(String MovieName, String MovieDate) {
Context context = this;
Class destinationClass = DetailActivity.class;
Intent intentToStartDetailActivity = new Intent(context, destinationClass);
intentToStartDetailActivity.putExtra(Intent.EXTRA_TEXT, String.valueOf(MovieName));
intentToStartDetailActivity.putExtra(Intent.EXTRA_CC, String.valueOf(MovieDate));
startActivity(intentToStartDetailActivity);
}
and in DetailActivity:
mMovieName = (TextView) findViewById(R.id.tv_movie_Name);
mMovieDate = (TextView) findViewById(R.id.tv_movie_date);
Intent intentThatStartedThisActivity = getIntent();
if (intentThatStartedThisActivity != null) {
if (intentThatStartedThisActivity.hasExtra(Intent.EXTRA_TEXT )) {
movieName = intentThatStartedThisActivity.getStringExtra(Intent.EXTRA_TEXT);
mMovieName.setText(movieName);
}
if (intentThatStartedThisActivity.hasExtra(Intent.EXTRA_CC )) {
movieDate = intentThatStartedThisActivity.getStringExtra(Intent.EXTRA_CC);
mMovieDate.setText(movieDate);
}
}
It works fine and I get the information in detail activity but I used Intent.EXTRA_TEXT and Intent.EXTRA_CC and I need to use more. So, my question is can I rename the EXTRA_ with some other word that I choose? Cuz I saw it when I search different names for Extra but don't know how to create a new one like Extra_DESCRIPTION.
And the second question - is it true to use a new if condition with hasExtra() like I did to get information? can't I use only on if condition with hasExtra() to get all information? if so then how to do that?
ofcourse you can use any key you like.
for example
intent.putExtra("username", yourUsername);
intent.putExtra("password", yourPassword);
and it's a good practice to check intent.hasExtra(String key) to avoid null pointer exception.
or you can just directly check if intent has any extra budle by intent.hasExtras()

Is it possible to pass class name as a parameter in Java?

I have following code:
private void startLesson(String input) {
Intent intent = new Intent(StartovayaAktivnost.this, OsnovnayaAktivnostORM.class);
intent.putExtra("vybor_razdela", input);
startActivity(intent);
}
I want to launch different activities depending on parameter, is there a simple solution to pass a class name like
private void startLesson(String input, String activityname) {
Intent intent = new Intent(StartovayaAktivnost.this, activityname.class);
intent.putExtra("vybor_razdela", input);
startActivity(intent);
} //I know it's not gonna work
or the only way is to use embranchments like
private void startLesson(String input, String activityname) {
if (activityname.equals("OsnovnayaAktivnost"))
{
Intent intent = new Intent(StartovayaAktivnost.this, OsnovnayaAktivnost.class);
intent.putExtra("vybor_razdela", input);
startActivity(intent);
}
else if (activityname.equals("OsnovnayaAktivnostORM")) {
Intent intent = new Intent(StartovayaAktivnost.this, OsnovnayaAktivnostORM.class);
intent.putExtra("vybor_razdela", input);
startActivity(intent);
}
}
You can have a class as a parameter. Consider the following:
private void startLesson(String input, Class activityname) {
Intent intent = new Intent(StartovayaAktivnost.this, activityname);
intent.putExtra("vybor_razdela", input);
startActivity(intent);
}
You can then call your method as
startLesson("input", Main.class);
The same way as they're using classes as their parameters.
you can do something like:
Class<?> myClass = Class.forName(activityname);
Intent intent = new Intent(StartovayaAktivnost.this, myClass);
intent.putExtra("vybor_razdela", input);
startActivity(intent);
However, activityname should be the full class name.
You already have answers that show you solutions. I am more curious about your use-case though. For a similar situation I created a map of strings to classes of a certain base type. When passing activityName to that map, I would find the activity, or not. This gives you more control over what kind of classes are allowed to be loaded in this situation. In your scenario it would be harder to limit what kind of classes can be passed into Intent. But I imagine they have to adhere to certain rules that make up an activity.
Something like:
Map<String, MyBaseActivityType> activities
If you need new instances of the activity class every time, you can modify it a bit, I haven't given that part much thought.
But don't use reflection unless you really really need it. It gets messy quickly.
Found an answer while trying at random:
private void startLesson(String input, String activityname) throws ClassNotFoundException {
Intent intent = new Intent(StartovayaAktivnost.this, Class.forName(activityname));
intent.putExtra("vybor_razdela", input);
startActivity(intent);
}

Passing multiple strings to a new activity and displaying them in a list view. Java, Android SDK

I have my 2 activities set up and linked.
What I'm trying to do:
Take a generated text view in my first activity, convert it to a string, pass it to my other activity, where is it displayed in a list view with other previous passed text views.
So in my first activity I currently have:
public void SaveMessage(View view) {
String saved = message.getText().toString();
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
intent.putExtra("message",message);
Toast.makeText(getApplicationContext(), R.string.addedfavs, Toast.LENGTH_SHORT).show();
}
However I don't really know where to go from this, I've looked at trying store the strings in arrays or then in array lists, but to no avail.
Help would be much appreciated on how to receive each string and store it in some sort of arraylist (as arrays are of fixed size) or any format that could consequently be displayed in a ListView.
However I don't really know where to go from this,
First of all you must start the intent activity:
context.startActivity(intent);
Then, when necessary, in FirstActivity or SecondActivity, get the intent that started your activity with:
Intent intent = getIntent();
Now, you have also the extras with that intent. As you have the extra data as Strings, use intent.getStringExtra(String name) method.
In your case:
String message = intent.getStringExtra("message");
I've looked at trying store the strings in arrays or then in array lists, but to no avail.
You have other extra methods like getStringArrayListExtra to pass ArrayList<> or getStringArrayExtra to pass Arrays
I could not properly understand your question, but according to my understanding, there are two solutions.
Solution 1:
If you want to save previously passed texts, you can do that using a db. Whenever you pass a string from your first activity to second one, store that text in db and get all the strings from db and populate those in list.
Or you can save it in arraylist and save the array list to SharedPreferences like:
public void addMessage(String message) {
if (currentMessages == null) {
currentMessages = new ArrayList<String>();
}
currentMessages.add(message);
//save the task list to preference
SharedPreferences prefs = getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE);
Editor editor = prefs.edit();
try {
editor.putString(MESSAGES, ObjectSerializer.serialize(currentMessages));
} catch (IOException e) {
e.printStackTrace();
}
editor.commit();
}
public ArrayList<String> getMessages() {
if (currentMessages == null) {
currentMessages= new ArrayList<String>();
}
// load tasks from preference
SharedPreferences prefs = getSharedPreferences(SHARED_PREFS_FILE, Context.MODE_PRIVATE);
try {
currentMessages = (ArrayList<String>) ObjectSerializer.deserialize(prefs.getString(MESSAGES, ObjectSerializer.serialize(new ArrayList<String>())));
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
You can use this arraylist as a data source for your adapter.
Solution 2:
If there are multiple messages that are passed via intent, then use this:
ArrayList<String> messages = new ArrayList<String>();
messages.add(message1);
messages.add(message2);
.
.
.
messages.add(messageN);
Then use this arraylist as a data source for your adapter.
Edited:
SHARED_PREFS_FILE can be a static final String like:
public static final String SHARED_PREFS_FILE = "sharedPrefsFile";
(Desired preferences file. If a preferences file by this name does not exist, it will be created when you retrieve an editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).)
You can get ObjectSerializer class from here and add it to your project.

retrieving string from parse.com and displaying it in TextView Android

I have uploaded data onto parse.com and i am trying to retrieve the data from parse.com and display it in a textview.
i have a parseconstants class:
public static final String TYPE_STRING = "string";
public static final String KEY_FILE_TYPE = "fileType";
i send the message and it uploads to parse fine
String fileName = "text.txt";
String fileType = "text";
these 2 values are sent to parse.com as filename and filetype.
but when i get it back in inboxActivity here:
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
ParseObject message = mUserBio.get(position);
String messageType = message.getString(ParseConstants.KEY_FILE_TYPE);
ParseFile file = message.getParseFile(ParseConstants.KEY_FILE);
Uri fileUri = Uri.parse(file.getUrl());
if (messageType.equals(ParseConstants.TYPE_STRING)){
Intent intent = new Intent(getActivity(), ViewTextActivity.class);
intent.setData(fileUri);
startActivity(intent);
}
it does not call on the text activity class and does not show the class.
in the TextViewController i try to display the text into the TextView like below:
mDisplay = (TextView)findViewById(R.id.bioDisplay);
Uri textUri = getIntent().getData();
File string = new File(textUri.toString());
mDisplay.setText((CharSequence) string);
1) Why does the ViewtextActivity not show?
2) will the textview display the retrieved user bio?
Firstly, try to avoid calling constants like this:
ParseConstants.KEY_FILE_TYPE
Completely!
Rather import your class statically:
import static <your_package_name>.ParseConstants.*;
//now you can access your constants by calling it on its own:
String messageType = message.getString(KEY_FILE_TYPE);
EDIT
Your naming standards are not up to standard (An instance of File, should be called something to do with a File, and not "string")!! You are trying to display an object of type File within a TextView which won't work. Rather try this, instead of letting Android Studio cast it to a CharSequence:
mDisplay.setText(string.toString());
Thirdly, when calling ViewTextActivity, there are 3 ways to do this (as I am not sure if you are using a Fragment or not):
//if you are using a Fragment:
Intent intent = new Intent(getActivity(), ViewTextActivity.class);
//if you are using a FragmentActivity, you need to cast it:
Intent intent = new Intent((Your_Base_Activity) getActivity(), ViewTextActivity.class);
//if you are using a normal activity:
Intent intent = new Intent(Your_Activity_Name.this, ViewTextActivity.class);
As far as your TextView displaying data is concerned, your code does seem logically correct.
EDIT 2
From the ParseObject API, we see that getString will return the String value from that Key that is put in as the parameter (See Here).
According to you, you are checking if the return value is equal to the word "string". This doesn't make sense, as you are putting in the key value of "fileType".
My suggestion is check if the return is not null by using a log:
String messageType = message.getString(KEY_FILE_TYPE);
Log.e("MessageReturned: ", "Returned-" + messageType);
Or you can rethink, what the value that is supposed to equate to is supposed to be, as "string" doesn't make sense as far as I can see.
EDIT 3
Since you are saying that the value uploaded for the variable fileType is "text" should you not rather be doing this:
if (messageType.equals("text")){
EDIT 4
Your method of parsing information between the intents is obsolete. You need to try this:
if (messageType.equals(ParseConstants.TYPE_STRING)){
Intent intent = new Intent(getActivity(), ViewTextActivity.class);
intent.putExtra("fileUri", fileUri.toString());
startActivity(intent);
}
Then in your other class, you access it like so:
Bundle extras = getIntent().getExtras();
Uri receivedFileUri = Uri.parse(extras.getString("fileUri"));

How can I open an Activity using the name as string via intent?

I want to use String variable containig the name of an activity, and i want to open the activity via in intent.
For example:
next = "foo.class";
Intent baslat = new Intent(this,next);
"next" is my value. I think using variable is impossible because eclipse don't let me use two arguments.
How can I solve this problem?
Edit: I am trying to go to "foo.class"
Edit: I solve the problem, You are all so nice and pretty :D, kisses for all, thank you very much!
OK, use the method Class.forName()
String myClass = "foo.class";
Intent myIntent = new Intent(getApplicationContext(), Class.forName(myClass));
startActivity(myIntent );
There is a method Intent.putExtra(). You can use this method to add extra variables inside your intent object.
String next = "foo.class";
Intent baslat = new Intent();
baslat.putExtra("my_tag", next);
Intent.putExtra() is what you're looking for.
next = "foo.class";
Intent baslat = new Intent(/*intent action goes here*/);
basalt.putExtra(/*data name*/, next);
If foo.class is where you're headed, then use Intent(Context packageContext, Class cls):
Intent baslat = new Intent(this, foo.class);
startActivity(basalt);

Categories