So, right now in my App I'm sending data from actual class, to other, special class prepared to show informations from it, like here:
Intent intent = new Intent(ActualFluidsBernoullisEquationMenuActivity.this, DetailSubjectActivity.class);
Of course I'm also passing some info, on which I first need to create database reference, so there is like 15 lines of code.I have like 15 of those activities, which is creating a lot of boilerplate (the only changing line is which .this class I'm passing)
So I wanted to create universal method for intent like this:
Intent engineeringTheoryIntent(String callingActivity, String subjectKey) throws ClassNotFoundException {
Intent intent = new Intent(Class.forName(callingActivity).getClass().this, DetailSubjectActivity.class);
}
(This doesn't work, just in case)
I just cannoot find the way how to properly pass first class. I tried Class.forName, I tried passing whole class, but not any of those works for me. I also didn't find any info if this is even possible (I'm kind of beginner in matter of android). So is there way to do it?
I'm posting the solution in the comments as an answer, so that it helps people who encounter similar problems in future.
So, instead of passing the activity class name (as String) you can simply pass the Activity itself as the argument to your universal function, like this :
Intent engineeringTheoryIntent(Activity callingActivity, String subjectKey) throws ClassNotFoundException {
and then you can create your Intent using it like this :
Intent intent = new Intent(callingActivity, DetailSubjectActivity.class);
So, your function will look something like this:
Intent engineeringTheoryIntent(Activity callingActivity, String subjectKey) throws ClassNotFoundException {
Intent intent = new Intent(callingActivity, DetailSubjectActivity.class);
}
Related
I am a beginner at android development, and have reached the end of Building your First App. Before I move on, I would like to confirm and validate my understanding of using multiple activities and communicating from one activity to another.
/** Called when the user clicks the Send button */
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
1) Is my understanding correct that the second paramater in the constructor for Intent (Intent intent = new Intent(this, DisplayMessageActivity.class)) serves as a reference for startActivity(...) and reflection is used to call the method onCreate() in the class DisplayMessageActivity since the class DisplayMessageActivity was given as a class object?
2) What is the use of the first paramater (the context one in the constructor)? (Basically how does Android use the first parameter, a brief description please, to start the activity)?
3) As seen in the tutorial, last part of building your first app, it advises me to declare a variable as such: (public final static String EXTRA_MESSAGE = "me.marshac.myfirstapp.MESSAGE";). I know the purpose of this declaration and initialization, but why don't I have to specify the full package name (me.marshac.myfirstapp. (...) .MESSAGE) and where is the MESSAGE variable coming from? The only two variables similar to that are both local variables in sendMessage() and the other activity's onCreate(), but they are different case and local?
I am sorry for the very in-depth inquiries, I want to establish a firm understanding of the beginner concepts before I move on to intermediate/advanced ones.
1) Yes. I think that's what is happening behind the scenes. If you want to know exactly how they did it, you can go to read the Android OS source code. It is open source, you know. Just Google it!
2) Android uses a stack for storing activities. When you first started your app, it's like this:
MyActivity
Then when you start another activity, a new activity object is pushed onto the stack
DisplayMessageActivity
MyActivity
When you tap the back button, an activity from the stack is popped.
If you didn't give this as the parameter, how would the OS know where to push the new activity onto?
3) I think this is just a convention of some kind. I usually use simple names like message, and it works! It's similar to asking why should I name a class in PascalCase and a local variable in camelCase?
I'm simply trying to carry a string onto the next activity without having to define an entire object for the task. I've seen similar solutions and gotten them to work BUT without using AsyncTask to create the intent.
protected void onPostExecute(Boolean result) {
if (loggedIn && hasPin) {
Intent intent = new Intent(UniteActivity.this,
WebViewActivity.class);
intent.putExtra(PASSED_USERNAME, passUser);
startActivity(intent);
}
if (loggedIn && !hasPin) {
Intent intent = new Intent(UniteActivity.this,
CreatePinActivity.class);
intent.putExtra(PASSED_USERNAME, passUser);
startActivity(intent);
PASSED_USERNAME is a public static constant to hold the package name, just as the putExtra() method requires. I then try to pull the value out in the next activity.
Intent extras = getIntent();
String username = extras.getStringExtra(UniteActivity.PASSED_USERNAME);
// carry username to next activity
Intent intent = new Intent(CreatePinActivity.this,WebViewActivity.class);
intent.putExtra(PASSED_USERNAME, username);
startActivity(intent);
There is never a String to pull out, the value of username is always null. I've gone through the debugger and found that the Eclipse IDE debugger shows different intent ID's between the activities, they are never consistant. Is it possible that AsyncTask is interfereing somehow because it splits into a seperate thread?
I don't know if this applies to your problem, because I can't see from your code snippet if the intermediary activity is freshly created or not.
BUT: the getIntent()-method always returns the first Intent that started the activity. If the activity remains in the background and receives a new Intent this value does not get updated automatically. You have to override onNewIntent(...) and manually call setIntent(...) for this to work (or do all your stuff directly there).
So just for the case that you do not run your posted code in the onCreate() method please check if you did not miss to fetch the real intent you are interested in.
Not sure of the exact answer for you solution.
You calling startActivity on the UI since it's in postExecute().
If all else fails you can just save that value to a sharedpreference.
The way you have handled the variable PASSED_USERNAME seems incorrect. You have used it in some palaces as simple PASSED_USERNAME whereas in some other places you have used it with the class named prefixed UniteActivity.PASSED_USERNAME. Since it is a Public Static Constant always use it prefixed with the class name.
I'm currently working on an Android App and, almost every time I use it, I get a an error. Most of the time it doesn't crash the app, but it is still frustrating that I'm seeing this error. I thought I did a check for it, but I could be wrong. Thanks for the help! The relevant code is below. (It's relevant because the line outside the if statement is throwing the NullPointerException.)
Activity activity;
if(activity == null)
{
activity = new Activity();
}
Intent intent = new Intent(activity, Service.class);
You don't usually instantiate the Activity class in this manner. Please see the documentation on the Android Activity class here:
http://developer.android.com/reference/android/app/Activity.html
You should post some more of the surrounding code, but your problem is that creating new Intent requires a valid Context. Usually you create an Intent within an Activity (or Service or BroadcastReceiver) class so you can just do something like:
Intent intent = new Intent(this, Service.class);
Occasionally you'll create it somewhere else and pass it that valid Context, but you should pretty much never create an Activity by calling the constructor directly. There's a lot of other initialization necessary to make it useful.
As postet previously there is more to initiate for an activity than calling the constructor. Probably you get a null pointer exception deep within the Intent Constructer where it is trying to get some of the Activityinformation usually provided.
If you really want to create a Service, heres a link for starting a Service, but you should really read the whole article and probably some more of the activity lifecycle ressources.
http://developer.android.com/guide/topics/fundamentals/services.html#StartingAService
In my Android application I have a new intent which is launched depending on the results and returns of some other methods, so I've launched the intent this way:
methodOne(methodTwo(methodThree()));
This is the code for launch search results:
private void methodOne(ArrayList<String> identities) {
Intent intent = new Intent(Class.this, AnotherClass.class);
intent.putStringArrayListExtra("aList", identities);
startActivity(intent);
}
This currently works fine, and I get the results I want. I just wondered if the way I am calling this method is good or bad practice as I don't really know myself.
If you are passing the ArrayList of event identities to the function when you call it, there is no need to do the:
eventIdentities = getEventIdentities(searchResults);
because you already have the ArrayList being passed into the method so you can use it.
I want to invoke one application from another application.
My Java file code:
Intent intent = new Intent(Intent.ACTION_RUN);
intent.setComponent(new ComponentName("Package name", "class name"));
startActivity(intent);
But I'm getting problem in specifying exact package path and I don't know permission for that code in Manifest. Please, help me on this.
I am going to assume that you really mean that you want to launch another app, not another Activity in your app.
Then there are two ways to do this. You can try using an implicit intent which according to the docs, an (Implicit) intent is "an abstract description of an operation to be performed" that "provides for performing late runtime binding between code in different applications." Sort of like trying to launch a method over the wire using an interface. You cannot be sure exactly what the class of the object that is launched only that it can handle the action and categories that you declare.
The second approach is an explicit intent, which is more like making a concrete call over the wire. If you know the package and class name this should work.
Intent intent = new Intent(Intent.ACTION_MAIN);
//intent.putExtra("plain_text", "Testing");
intent.setClassName("packagename", "packagename.ClassName"); // Explicit Intent
try {
startActivity(intent);
}
catch (Exception e)
{
Log.d(TAG","onCreate",e);
}
}
You can add extra info using flags depending on your needs and where your are trying to launch from.
JAL
Starting an external activity from your app is done using a slightly different method to that which you are using. You need to create an intent with a given action. For example, launching an intent to fetch an image from the gallery would look like this:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, IMAGE_PICK);
Note that you don't explicitly define the activity to be loaded, rather the kind of action you want to perform. Android will then pick (or have the user pick) an activity that has registered to handle this kind of intent to be run.
You might need to be a little more specific about what you're doing. If all you want to do is, say, launch another Activity from your main Activity, something like this would work:
Intent intent = new Intent(this, OtherActivity.class);
intent.putExtra("key", "data"); //put any data you want to pass into the new activity
startActivity(intent);
Then just make sure you put the new activity in your manifest like this:
<activity android:name=".OtherActivity"
android:label="#string/other"/>
If your goal is something else then you should be ore specific with what you want to do.