Start Activity with a variable - android

How can I do the name of the activity variable with a string?
Intent in = new Intent(MainActivity.this,
xxx.class);
If my string is "a" it will be:
Intent in = new Intent(MainActivity.this,
a.class);
else, if my string is "b":
Intent in = new Intent(MainActivity.this,
b.class);
how can I concatenate this? Thank you so much

how can I concatenate this?
Ideally, you don't. You use something else, like a switch statement or a HashMap<String,Class> lookup or something.
That being said, you are welcome to use Class.forName() if you really want.

I cannot check it right now but this should work:
Intent I = new Intent(this, Class.forName("your.package.ClassName"));
However this is a little dangerous IMHO. This would allow to start any activities from outside of your app. This would e.g. allow to open some internal activities from outside which are not exported.

Related

Android / Sending activity context through intent

I have 5 or so activities in Android (2 of them have been shown below), which share a common Navigation Drawer. If I log in into some account from the Navigation Drawer, after successful log in, the activity which was previously showing needs to be loaded. Is it possible to send activity context through intent?
FirstActivity.java
Intent intent1 = new Intent(FirstActivity.this, Login.class);
intent1.putExtra("activity", "FirstActivity");
startActivity(intent1);
finish();
SecondActivity.java
Intent intent2 = new Intent(SecondActivity.this, Login.class);
intent2.putExtra("activity", "SecondActivity");
startActivity(intent2);
finish();
When finding the name of the activity to return in log in activity, after successful log in.
Login.java
Intent intent3 = getIntent();
String activity = intent3.getStringExtra("activity");
...
Intent intent4 = new Intent(Login.this, Class.forName(activity));
startActivity(intent4);
finish();
returns the following error message:
W/System.err: java.lang.ClassNotFoundException: Home
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:453)
Does anyone know how to fix it up?
Making use of intent1.putExtra("activity", String.valueOf(FirstActivity.this)); also does not work out either, it says that com.example.nativeapp.FirstActivity#6a7640 is an invalid class name.
Should I convert the activity context to Serializable or Parcelable or even CharSequence when I try to send those variable values through intent? Activity or AppCompatActivity does not seem to inherit Serializable or Parcelable for that to work out it seems. CharSequence does not seem to make much difference from making use of String.
I know that I can create my own class to store global variables and activity contexts and my activity can inherit from that but since my activity already inherits NavigationDrawer, my activity cannot inherit a second class. Can I declare that as an interface and inherit an interface to access global variable values from interface? Getter and setter methods, for sure cannot work out in an interface, since no implementation of functions and no declaration of variable values are allowed in an interface.
One of the reasons why I have been considering to decide to make use of a central superclass for storing variable values and changing them from subclasses whenever that I am trying to move from one activity to another is that activity contexts like this, I am not sure how to pass them through intents. That intent, which should also be able to pass on within the other central global variables of the mobile application from one activity class to another. The central superclass, such as the NavigationDrawer which is an excellent candidate since all of my Android activity classes inherit from it would be best to use if all central global variables are stored in it and they are changed from subclasses whenever that I am trying to move from one activity to another.
How do I go about it?
you are trying to remember the last activity and then starting next specific activity.
This is the way to do it
change this
Intent intent = new Intent(Login.this, Class.forName(activity));
startActivity(intent);
finish();
to this-
Intent intent = getIntent();
String lastActivity = intent.getStringExtra("activity"); // lastActivity
if (lastActivity.equalsIgnoreCase("FirstActivity")) {
Intent intent = new Intent(Login.this, FirstActivity.class);
startActivity(intent);
finish();
} else if (lastActivity.equalsIgnoreCase("SecondActivity")) {
Intent intent = new Intent(Login.this, SecondActivity.class);
startActivity(intent);
finish();
}
create common method to optimize your code
You need to provide the fully qualified class name. Instead of "FirstActivity" you need to pass "my.fully.qualified.class.name.FirstActivity" where you provide the fully qualified class name.

ADT: Avoid duplicating code in package with dependency on another deployed package?

When I have e.g. a custom service and a custom activity in the same ADT project, then I can use this in the service, to start my activity:
Intent i = new Intent(context, MyCustomActivity.class);
startActivity(i);
However when I have the service and activity in separate projects, then I cannot do this since I do not have a direct reference to MyCustomActivity.class. This is problematic: I do not wish to include a JAR just to be able to fix that broken reference, since I assume this will increase the package size and create redundant data on the device (i.e. activity code is duplicated between the service and activity packages). So instead, I use this (perhaps there are other options?):
Intent i = new Intent("com.mypackage.myStringActionName");
startActivity(i); //is this a broadcast?
OR
Intent i = new Intent("com.mypackage.myStringActionName");
sendBroadcast(i);
...But I don't really like sending broadcasts when all I want is to direct the intent to a single activity to tell it to start.
So, what other ways are there to go about avoiding duplication (in ADT)? Or else a better way to send direct intents?
you can try this:
Intent i = new Intent();
i.setComponent(new ComponentName(packageName, classname));
startActivity(i);
the className must contains the packageName and main activity name

starting activities without .class

I have searched for how to start and Activity from another Activity and I keep finding
Intent intent = new Intent(this, ExampleClass.class);
startActivity(intent);
But I want to start from an instantiated activity. I have a container with many activities and when the user selects from my UI I wish to show a particular one.
So, for example.
class MyExample extends Activity {
MyExample mx = new MyExample();
So how do I now start this Activity.
What I would like is
Intent intent = new Intent(this, mx);
startActivity(intent);
Any help greatly appreciated from a reasonably experienced Java developer but new to Android.
This is possible, though I do not understand yet why you want to do this.
Make sure the Activity you want to startis well declared in your manifest :
<activity android:name=".com.example.MyExample" ... />
Then you can call in you current Activity :
Intent myIntent = new Intent();
myIntent.setComponent(new ComponentName("com.example", "com.example.MyExample"));
startActivity(myIntent);

Get calling activity from some other activity

I am calling an activity from another activity by this code:
Intent intent = new Intent(context, mClass);
context.startActivity(intent);
and from my new activity which is started by this code. I want to know which activity starts this activity. I used this code for this purpose
Intent intent = getIntent();
Class<?> c = intent.getClass();
if (c != OffersActivity.class) {
prepareForNotifications();
setListAdapter();
}
but by this code I am not able to get the classname which starts this activity. I really need some help.
thanks
There is a method getCallingActivity(), but that only works, if the calling activity calls you with startActivityForResult(). I have seen libraries use that and say that you must call them that way, but frankly it is a bit nasty. The simple answer is that you're not supposed to know. Android is a system of loosely coupled activities and the calling activity should thus have no real meaning to your activity. Any information your activity needs should be put explicitly in the intent, so if you really want to know who called you then the caller needs to put that extra in. You won't be able to tell if they are lying of course, so don't go trying to use this for anything security-related. However, I would suggest that whatever you're determining based on the caller, is what the caller should be passing you instead. Might be time for a rethink on why you want to do this, since trying to fight the system will only lead to pain.
I would suggest:
public static final String INTENTSENDER = "sender";
void mMethod() {
Intent intent = new Intent(context, mClass);
intent.putExtra(INTENTSENDER, mClass);
context.startActivity(intent);
}
knowing who sent it:
Class<?> c = (Class<?>)intent.getExtras().get(INTENTSENDER);
However, you can also use this:
ComponentName componentName = this.getCallingActivity();
Now, you can use componentName to get the sender of the intent.
Maybe it's best to use the extras parameters in the intent when you call them...like: Intent.putExtra(PARAM,value) on the caller activity...and on the opened activity you check:
intent.getStringExtra(PARAM)
getParentActivity() is not what yout are looking for?

Which is the correct way to start an Activity?

Let's say the Activity I want to start is named "OccupyThePieShop"
I was previously using this methodology to start an Activity:
Intent oTPS = new Intent();
timeIntervalConfigIntent.setClassName("com.aXX3AndSpace.KeepInTouch",
"com.aXX3AndSpace.KeepInTouch.OccupyThePieShop");
startActivity(oTPS);
...but was told that this is more the norm:
Intent oTPS = new
Intent(KeepInTouchActivity.this, OccupyThePieShop.class);
KeepInTouchActivity.this.startActivity(oTPS);
...and so I replaced my calls to startActivity() with that usage.
Now, I've come across a couple more ways which seem quite "elegant," namely:
startActivity(new Intent(getApplicationContext(), OccupyThePieShop.class));
...and:
Intent intent = new Intent(this, OccupyThePieShop.class);
startActivity(intent);
Is one way preferred over the others, and if so, why?
I think this is probably an issue of personal preference. I like startActivity(new Intent(this, OccupyThePieShop.class)); because, as you said, it is elegant.

Categories

Resources