So I was trying to make a menu in an application that has a single item. Clicking this menu item takes you to another activity. So basically I'm starting a sub-activity on having that menu item clicked.
The problem is here that I have to specify my intent in the onCreate() method of my main activity, but I need this intent in my onOptionItemSelected() method which is outside the onCreate() method. How do i do this?
My onCreate() method:
public void onCreate(Bundle savedInstanceState) {
Intent myIntent=new Intent(mainActivity.this,secondActivityt.class);
}
My onOptionsItemSelected() method:
public boolean onOptionsItemSelected(MenuItem item){
if(item.getItemId()==R.id.aboutbtn){
startActivity(myIntent);
}
So here I'm unable to access myIntent. Is there anyway I can declare the intent outside the onCreate method and still make the program work, or anyway I can access the intent outside the onCreate method?
should be pretty easy, just declare a private class variable and store your intent in that like
public class MyActivity extends Activity{
private Intent myIntent;
public void onCreate(...){
...
myIntent = new Intent(...);
}
public boolean onOptionsItemSelected(MenuItem item){
...
//use the myIntent here
}
}
I didn't try it out now, but I don't see any reason why this should not work, unless I didn't clearly understand your issue :)
Just as a sidenote. You maybe should also give a look at the Activity lifecycle, basically which event (onCreate, onResume, onStart, onDestroy,...) is fired when. The following figure taken from Android Developers describes it best:
Related
I am trying to finish one activity from another.
For that purpose I am having only the component name of that activity.
How can i finish that ?
1.Make your activity A in manifest file: launchMode = "singleInstance"
2.When the user clicks new, do FirstActivity.fa.finish(); and call the new Intent.
3.When the user clicks modify, call the new Intent or simply finish activity B.
FIRST WAY
In your first activity, declare one Activity object like this,
public static Activity fa;
onCreate()
{
fa = this;
}
now use that object in another Activity to finish first-activity like this,
onCreate()
{
FirstActivity.fa.finish();
}
SECOND WAY
While calling your activity FirstActivity which you want to finish as soon as you move on, You can add flag while calling FirstActivity
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
But using this flag the activity will get finished evenif you want it not to. and sometime onBack if you want to show the FirstActivity you will have to call it using intent.
You can do it in very simple way.
First create a static instance of your activity e.g. MainActivity, whom you want to finish like,
public static MainActivity act=MainActivity.this;
and now in another actvity e.g. MainActivity2 just call this line,
MainActivity.act.finish();
Try extending that activity and override the finish method
public class ma extends MainActivity{
#Override
public void finish()
{
super.finish();
}
}
You want to exit application after log out.
that time to user this
i.addCategory(Intent.CATEGORY_HOME);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
or try to another way like
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
moveTaskToBack(true);
finish();
}
I'm making my very first Android application but I ran into a problem.
I have over 8 different classes which all use the same actionbar.
Now in place of calling the method in every different class (and having a lot of double code) I would like to call the method of the main class in my other classes.
This is a part of my code for the onOptionsItemSelected in main.java
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.actionbar_new_income:
Intent newIncome = new Intent(this, NewIncome.class);
this.startActivity(newIncome);
return true;
}
}
Now I was wondering how I could call the method in another class (newIncome.java)
I have this so far, but it keeps saying I need to add arguments. And I ofcourse need to be able to detect which menuitem is clicked..
MainActivity main = new MainActivity();
main.onOptionsItemSelected();
Any help please?
Thanks!
You should not do this. If you have common code then put it in a class (not an activity) that is accessible by any activity that needs it.
You will still have some duplication but this is normal.
A good way of reducing activity launch code is to add a static method to each activity that you can call which launches the activity it is in.
E.g in your NewIncome Activity you could have
Public static void Launch(Context c) {
Intent newIncome = new Intent(c, NewIncome.class);
C.startActivity(newIncome);
}
You could then launch this activity from any other activity just by calling
NewIncome.Launch(this);
If required you can add parameters to the method and then add Extras to the Activity using these parameters.
You can do it like the following example if your menu entries are totally independent of the activity in which they are contained:
In each activity
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return CommonClass.HandleMenu(this, item.getItemId());
}
In a common class
public class CommonClass {
public boolean HandleMenu (Context c, int MenuEntry) {
switch (MenuEntry) {
case R.id.actionbar_new_income:
NewIncome.Launch(c);
etc....
...
}
}
If your 8 classes are activities you may define a base activity with the onOptionsItemSelected which is the one where you put the elements in the actionbar you want. Then make the other activities derive from it.
I have two Activities: the MainActivity starts the NewReminderActivity. The first one will be notified when a new reminder has been created. Therefore it implements the interface OnEventAddedListener.
Do I need to use serialization to add the MainActivity to the intent or is there a better solution? I've never seen any examples using serialization to accomplish this and I'm sure it's very common to pass an interface from one activity to another in order to communicate.
public class MainActivity extends Activity implements OnEventAddedListener {
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
if(item.getItemId() == R.id.action_addReminder)
{
// NewReminderActivity c = new NewReminderActivity(this);
// Intent intent = new Intent(this, c.getClass()); // this won't work
Intent intent = new Intent(this, NewReminderActivity.class);
startActivity(intent);
return true;
} else {
return super.onOptionsItemSelected(item);
}
}
}
You absolutely should not try to pass one activity to another, whether it's by serializing it (which won't even work for a number of reasons) or setting a reference.
Android will take care of cleaning up old activities out of memory, but won't be able to do so as long as you're holding on to a reference from it. Never hold on to other activities or fragments outside of their context!
You should follow the documentation on starting activities and getting results by using startActivityForResult() and provide that activity's result through onActivityResult(int, int, Intent).
I have seen many examples with
startActivityForResult(Intent, int)
and then using
onActivityResult(int, int, Intent)
but for me I dont need to pass anything, I simply want to startActivity(intent), and when intent activity returns, a method get called in main activity..
Any tutorial on doing this?
EDIT:
Here a sample code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_options);
createEvent = (Button) findViewById(R.id.createEvent);
createEvent.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(optionsInterface.this, MainActivity.class);
startActivity(intent);
}
});
}
here, after I return from MainActivity (press back, or just close it), I want the activity to perform a task ( with no data being passed from MainActivity)
you can use startactivityforResult().. it doesn't matter if you send any data back or not... when you use startactivityonResult() the method onActivityResult will get called...just check for the request code there and do whatever you want...sending back something is not necessary.
Instead of startActivity() you might want to use startActivityForResult(), so that you get a call back on result.
This looks very similar to my previous question because it's some sort of follow up. I was not very happy with the only solution given; also, the solution was for a problem slightly different from this one. So let me try to explain the problem again...
A notification is created at boot (with a BroadcastReceiver).
My app main activity is opened and the home button is pressed (the activity will be sent to the back stack).
I pull down the status bar and press on the notification previously created at boot.
That will start some activity, different from the main one.
I press the back button and the main activity is displayed.
This is not very different from my previous question... The thing is, "main activity" was just an example. I could have opened the app main activity and then opened the about activity through a menu option and pressed the home button. The back stack would now be MainActivity ยป AboutActivity. Which means that when the back button is pressed while in "some activity" (started by pressing the notification), we would be brought to the top of the back stack, that is, the about activity.
What basically want is to prevent any other activity to be opened when I press the back button while in "some activity" (again, started by pressing the notification). I want to be brought exactly where I was, that could be the desktop or some other app's activity, but not my app's MainActivity nor AboutAcitivity cause that's not where I was, those were in the back stack, "sleeping" in the background.
I have come up with a solution, but I don't think it's very elegant and I was looking for something more, well, elegant... If you have any other suggestion, please, let me know.
Anyway, this is my proposed solution:
// I use this class for public static (or public static final) members and
// methods
public final class AppHelper {
public static final String KEY_RESUME_FROM_NOTIFICATION = "resumeFromNotification";
private static boolean sResumeFromNotification = false;
public static boolean getResumeFromNotification() {
return sResumeFromNotification;
}
public static void setResumeFromNotification(boolean resumeFromNotification) {
sResumeFromNotification = resumeFromNotification;
}
}
public class MainActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
(...)
}
#Override
protected void onResume() {
super.onResume();
if(AppHelper.getResumeFromNotification()) {
AppHelper.setResumeFromNotification(false);
moveTaskToBack(true);
}
}
}
public class AboutActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
(...)
}
#Override
protected void onResume() {
super.onResume();
if(AppHelper.getResumeFromNotification()) {
AppHelper.setResumeFromNotification(false);
moveTaskToBack(true);
}
}
}
public class SomeActivity extends Activity {
// This will be called when the notification is pressed and the activity is
// not opened yet
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
(...)
extractIntentExtras(intent);
}
// This will be called if the activity is already opened and the
// notification is pressed
#Override
protected void onNewIntent(Intent intent) {
extractIntentExtras(intent);
super.onNewIntent(intent);
}
private void extractIntentExtras(Intent intent) {
Bundle bundleExtras = intent.getExtras();
if(bundleExtras != null) {
// These intent extras are set on the Intent that starts this activity
// when the notification is pressed
AppHelper.setResumeFromNotification(bundleExtras.getBoolean(
AppHelper.KEY_RESUME_FROM_NOTIFICATION));
mRowId = bundleExtras.getLong(AgendaNotesAdapter.KEY_ROW_ID);
populateNoteUpdateFields();
}
}
}
I don't know, but this solution doesn't look very elegant to me (but it works as I expect it) and I'm looking for alternatives or for strong opinions on my proposed solution as an acceptable and good solution. Thoughts?
After doing some more reading perhaps this is the combination of flags you need:
Intent intent = new Intent(mContext, SomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
startActivity(intent);
I think that should force your SomeActivity class to be launched in a completely new task.
When launching the Activity from the notification, you can control how the Activity you are about to open is put on the back stack, and what task it's associated with with Intent flags. You can try something like:
Intent intent = new Intent(mContext, SomeActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
If that doesn't work, try setting a few of the other flags until you get the desired behavior.
Do you ever want your MainActivity to stay in history? If not then my simple, crude solution is to finish the MainActivity when it is paused.
(Call this in your MainActivity)
#Override
public void onPause() {
finish();
}
This will ensure that your MainActivity is removed from history when you navigate away from it, and will never appear when the back button is pressed.
This could be used for AboutActivity as well.