I'm currently experimenting with creating my own libraries (aar) and I've come to the point that I have a library with an activity in it up and running in my project. But I have one small problem that I can't solve: how do I send a String from my Mainactivity to the activity that I created in my library?
I know that if I was working with activities that belong to the same project I could just create an intent in activity 1, add a putExtra with the String, start the activity and dig up that intent in activity 2. But the activity in my library doesn't know the activity in my project exists, so that doesn't work.
I could put the info in my SharedPreferences, but I'd like to avoid that.
Any help? I've been searching the web and I've found a solution for the other way around, but sadly that's useless to me :-)
The activity in your library doesn't have to "know" the first one... It has just to check if the intent contains the extra you sent:
if(getIntent().getStringExtra("yourStringExtraName") != null){
//Do your stuff here
}else{
//Do stuff when there isn't your string
}
Related
I'm using Xamarin.Android to build an app for a customer that's meant to be supplementary to another app. The idea is that once they reach a point in their workflow where my app steps in, they will click a button inside their app that will launch my app, and will open an activity from my app based on some attached parameters.
My problem is that in the "calling" app, all that's exposed for me to work with is a parameterized URI that's passed directly to Android, so I have no means of creating and passing an Intent object. I can change the URI it sends to be whatever I like, so I've already added an intent filter that looks for the custom scheme myapp://.
I am new to SO, so I apologize if this question has been answered elsewhere, but I have looked for a few hours and in my searches so far, all I've seen are answers related to how to call another app from my own. The question I have is... how do I parse that request on the other end and know not only which activity to open, but the rest of the data or parameters that were in the URI? Is it possible to open an activity based on a parameter in that URI, or can I only point it to one activity?
Thanks in advance!
What you have to do is quite simple in your URL somewhere pass your activity name that you want to navigate to
Then in your code maintain a enum with all the possible activities you wanna navigate to:
enum ActivityName
{
MainAcitivity,
SomeotherAcitivity
}
Then in your received notification get the string where you have given the name of the activity and do something like this :
If(youractivityName==ActivityName.MainActivity.toString())
{
StartActivity(typeof(MainActivity));
}
Revert in case of queries.
I know of two ways to start an Activity with an intent. Let's say I'm in Activity A and I want to start Activity B. I could do the following.
1)
In Activity B I have some static method:
public static Intent newIntent(Context packageContext){
Intent intent = new Intent(packageContext, ActivityB.class);
return intent;
}
And from Activity A I can call:
startActivity(ActivityB.newIntent(this));
2) The other method is the one I see more often:
From Activity A I do the following
Intent intent = new Intent(this, ActivityB.class);
startActivity(intent);
Are there any benefits or drawbacks to using one versus the other? I think method 1 is a bit cleaner because it keeps the intent information in the class that will actually be started with the intent.
case first
Pros :
This follows the DRY principle mean don't repeat your self
Cons :
It is only limited to one class i.e ActivityB.class
Unclear naming convention for a Utility class
Note flexible to add extra properties unless method definition is modified to accept some map or something
Second case
Pros:
More flexible as any activity can be started
Any attribute can be added to intent object i.g putExtra and so many other
Cons :
Does not follow the DRY principle
Inefficient when duplicated many times
Improvements
Give your method proper naming
Can be overloaded to accept a map for key-value
Apply Class<?> to accept any class as parameter
The two approaches do exactly the same thing.
I think the first approach is indeed easier to understand and it's less code. But I think most people got used to the second approach and might be a little confused when they see it like that. This drawback isn't that significant though I don't think.
The thing is, if you use the first approach, you still need to use the second approach if you want to start an activity that you didn't create because you can't just add a static method to an already compiled .class file. This might make your code a little inconsistent.
Also, the name newIntent is kind of confusing. I don't know if it's just me, but doesn't it sound a bit like that you are going from Activity B to A? Maybe just intent?
I'm developing an Android module that basically consists of a custom View third parties can just drop into any of their activities.
This module includes a configuration activity (based on PreferenceActivity).
Given that you can't start an activity from a View, the module calls 'openConfig(Intent intent)' on the activity it is displayed in. This activity acts as a delegate for the module.
That works fine thus far (though I'd really like the module to handle everything internally, no delegate methods required, but I reckon that just isn't possible).
However, I need some sort of callback from the preference activity to the module, so that the module will get notified when the settings have been changed.
I was thinking of just adding the module's main class as a delegate to the preference activity;
ConfigActivity a = new ConfigActivity();
a.testVar = "testtest";
Intent intent = new Intent(getContext(), a.getClass());
delegate.handleConfigAction(intent); //
However, this test with just a simple String (instead of an interface) showed, that the String wouldn't get set after the activity has been started.
Second thought was to use 'putExtra()' on the intent, but that doesn't really suit the use case as the delegate I'd like to put there really is a View and not a serializable data object.
Are there any ways for me to handle this internally? I am aware of the 'onActivityResult()' function (http://developer.android.com/training/basics/intents/result.html), but that would mean that the third party developer using my module would need to handle this, something that needs to be avoided for obvious reasons.
Any help would be highly appreciated!
EDIT: FINAL SOLUTION
In the end I've changed the module from View to Fragment, which now works much better with handling "child" activities and such. When starting an Activity from a Fragment, the 'onActivityResult' function works beautifully to accomplish the task at hand.
You can start an Activity from a View using its Context as in:
#Override
public void onClick() {
Intent intent = new Intent(getContext(), ConfigActivity.class);
intent.putExtra("testVar", "testtest");
getContext().startActivity(intent);
}
You could use the onWindowVisibilityChanged() method to read the configuration that would be set in the ConfigActivity to make your View change its behavior.
First of, sorry for the bad title, I couldn't think at all what to call this.
Say if I have a string with a value of "ActivityMain", and I have a Activity in my project called ActivityMain. Is there anyway I can get a new instance of the class by the string?
The overall idea is to request data from a server, what sends back some different Activity classes, then I want to start whatever activity is returned.
Assuming you can get the fully qualified name for the activity's class, you could follow this answer and use:
Class<?> act = Class.forName("com.bla.TestActivity");
I think if else if ladder may do what you want.
if(responsefromsever.equals(NameOfActivityInString)){
// instantiate the activity
}
use case:
I am assuming there exist a Activity class whose name is MainActivity. And what you receive from server is response, (i.e String)
String nameOfActivity = "MainActivity";
if(response.equals(nameOfActivity)){
MainActivity instantiation or whatever you want to do
}else if(response.equals("SomeOtherActivity")){
//SomeOtherActivity or whatever you want to do
}
The overall idea is to request data from a server, what sends back some different Activity classes, then I want to start whatever activity is returned.
A simple way hat is coming to me is that you can have some switch condition or if-then-else conditions which would compare the string received and accordingly start the desired activity. Eg:
if ( stringReceived.equals("ActivityMain"){
//start ActivityMain
} else{
//others...
}
This might be useful, if there are not many activities to start.
It seems like you are sharing implementation details to your server of your client program. What if you want to hook up the server to an iOS app? Then the whole activity name returning idea wouldn't work. "Drawing a different line" for your interfaces might be the best option.
Have a Android technique question for those seasoned vets out there... I want to create a library that dynamically opens an activity. Furthermore, I want the project to be able to contain the activity and then pass this to the library. (This is all based around C2DM)
So, my project 'hotdogs' will have a reference to the library, and will tell it to open the activity 'TodaysToppings' and the library will open up the activity 'TodayToppings'. My other project 'Weather' will also extend the same library and tell it to open the activity 'TodaysForecast' and the library will open the activity 'TodaysForecast'.
Does that make sense?
Idea is simple. You can pass package name and action if necessary, or if it's main then Intent.ACTION_MAIN. So, your library can use Context to start new activity based on package name and action to open a specific activity. What about activity, it can be placed inside any other application, no need to pass it somewhere.
This is an old question but I came across this while trying to save the problem myself. I figured out a simpler way to do this without having to configure any strings or passing in any parameters.
String packageName = getPackageName();
Intent notificationIntent = getPackageManager().getLaunchIntentForPackage(packageName);
Now you have the intent you can add on extras, etc.