Android: How to determine if an activity is already running? - android

I created a base activity that has a menu, this menu will open other activities in the application.
public class BaseActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//Intent i = new Intent("com.app.Activity1");
//startActivity(i);
}
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.icon: Intent i1 = new Intent("com.app.Activity1");
startActivity(i1);
break;
case R.id.text: Intent i2 = new Intent("com.app.Activity2");
startActivity(i2);
break;
case R.id.icontext: Intent i3 = new Intent("com.app.Activity3");
startActivity(i2);
break;
}
return true;
}
}
All activities extend this base activity, so when you press the menu button, the menu pops up and you can select an activity.
However, lets say I use the menu to go to activity A. Once I'm in activity A I can use the menu to go to Activity A again. I can do this X times, but now the back button will go back to the same activity X times.
How can I tell if the activity is already running so a user can't keep opening the same activity?
Or rather, would you suggest I disable the menu item once in activity A?
Thanks for your input. Sorry if this seems like a trivial question.

There is a simple solution to this. You want to disable the menu item for the current activity in onPrepareOptionsMenu() in your BaseActivity like this:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Determine what activity I am and find the menu item for that activity
MenuItem menuItem = null;
if (getClass().equals(com.app.Activity1.class)) {
menuItem = menu.findItem(R.id.icon);
} else if (getClass().equals(com.app.Activity2.class)) {
menuItem = menu.findItem(R.id.text);
} else if (getClass().equals(com.app.Activity3.class)) {
menuItem = menu.findItem(R.id.icontext);
}
// Disable this menu item
if (menuItem != null) {
menuItem.setEnabled(false); // Make it non-selectable (even with shortcut)
menuItem.setVisible(false); // Make it non-visible
}
return true;
}

I think u need not to do that.I think you just appoint your activity's launchMode="singleTask".Code in your AndroidManifest.xml:
<activity android:name=".com.app.Activity1" android:launchMode="singleTask" android:configChanges="orientation|keyboardHidden" android:screenOrientation="portrait"></activity>
<activity android:name=".com.app.Activity2" android:launchMode="singleTask" android:configChanges="orientation|keyboardHidden" android:screenOrientation="portrait"></activity>
<activity android:name=".com.app.Activity3" android:launchMode="singleTask" android:configChanges="orientation|keyboardHidden" android:screenOrientation="portrait"></activity>
^-^

Kind of a trivial solution - why not have a global int in your baseActivity called 'int choice'? When you switch to an activity just set choice to that activity. For example
case R.id.icon:
if (choice != 1){
startActivity(i1);
choice = 1;
}
break;

You can implement this in two ways:
To call activity A from activity A, call it with flag as FLAG_ACTIVITY_REORDER_TO_FRONT, so A will be called again without creating a new instance, so goin back will not create any problem.
As you said, disable the menu item for activity A if activity A is in front.

Related

Back button works, but the actionbar button does not?

I have a pretty simple use case which seems to be working for all my Activities except one. All my Activities are calling getActionBar().setDisplayHomeAsUpEnabled(true);. The only place this isn't working is on an Activity I just added, which is also the only one I'm launching from the main activity's info menu. The actual OS back button works as expected in this case, but the Home button is not. Here's the menu logic that starts the activity:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.share:
share();
return true;
case R.id.support:
emailSupport();
return true;
case R.id.settings:
settings();
return true;
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
The problem is with the SettingsActivity, called in the menu by the settings() method you see in the switch above:
private void settings(){
Intent intent = new Intent(InfoMenuActivity.this, SettingsActivity.class);
startActivity(intent);
}
And the onCreate of the SettingsActivity is pretty simple too:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = this.getSharedPreferences(getString(R.string.preference_file), Context.MODE_PRIVATE);
setView();
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setDisplayShowHomeEnabled(true);
}
I originally only had the first getActionBar() call, but added the second to see if it changed anything, but it did not.
What am I missing?
From the comments it seems that you don't know how to set the parent activity in the manifest and keep supporting older versions.
For API 16 you can use parentActivityName attribute but for older versions you'll have to add a meta tag:
<activity
android:name="com.example.SettingsActivity"
android:label="Settings Activity"
android:parentActivityName="com.example.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.MainActivity" />
</activity>
If all you want to do is override the up button functionality to act as a back button then don't forget that in every activity you'll have to override onOptionsItemSelected.
However remember that overriding any default and expected android behaviour is bad practice.

PreferenceActivity not associated with "Settings"

I have my simple PreferenceActivity class and its onCreate passes my R.xml.preferences screen to ((PreferenceActivity)super).addPreferencesFromResource. Finally, in my AndroidManifest.xml my activity as follows:
<activity android:name="com.criticalrf.jwalkietalkie.PreferenceServerActivity" >
<intent-filter>
<action android:name="android.intent.action.MANAGE_NETWORK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
On the device, the menu button will trigger a menu with only the word "Settings." Clicking on Settings makes the Settings button go away but does not show anything. Do I need to add something in my MainActivity? I followed this guide, I'm not sure what I missed.
If you want to open this preference activity from your main activity you should call somewhere in your MainActivity:
startActivity(new Intent(this, PreferenceServerActivity.class));
and preference activity will show.
Typical implementation would be doing it with options menu. Like:
private static final int SettingsId = 1;
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(0, SettingsId, 0, "Settings");
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case SettingsId:
startActivity(new Intent(this, PreferenceServerActivity.class));
return true;
default:
return false;
}
}
Intent filter in your manifest from tutorial just says, that this activity can be opened from system settings when user browse data usage of your app.

how to deal with action bar's button listners

I am new to android and dont know where should i write the actionlistner code for action bar buttons so that i don't need to write the action listner code in all activity.
Please look at below image: i have a menu.xml file for action bar menu and added in one of my activity via onCreateOptionMenu function. when user click on any of my button of action bar then i can track it via onOptionItemSelected function.
Problem-1: For all other activity, i can use same menu.xml file but do i need to override onCreateOptionMenu function of each activity.
Problem 2: Do i need to write onOptionItemSelected function code in all activity?
Please suggest me better solution of these problems.
Problem-1: For all other activity, i can use same menu.xml file but do i need to override onCreateOptionMenu function of each activity.
Problem 2: Do i need to write onOptionItemSelected function code in all activity?
You can create a 'base' Activity and implement the methods in that. Then all you need to do is make sure all other Activities extend the 'base' Activity.
Example (note I use ActionBarSherlock so my 'base' Activity initially extends ShelockFragmentActivity - that may not be the same in your case but this gives an example)...
public class MyBaseFragmentActivity extends SherlockFragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.my_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
super.onOptionsItemSelected(item);
// Handle menu selection here
}
}
Now any Activity that extends that 'base' Activity will automatically inherit the menu creation and item selection methods of the 'base' class.
public class ActivityA extends MyBaseFragmentActivity {
// No need to create the menu or handle item selection
}
Problem-1: For all other activity, i can use same menu.xml file but do i need to override onCreateOptionMenu function of each activity.
Yes, simply add your code to handle the menu options in a switch statement.
Problem 2: Do i need to write onOptionItemSelected function code in all activity?
Yes, for each activity that is using the action bar, you will need to override the onOptionItemSelected function and add your custom code.
For example:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_watchlist:
Intent intent = new Intent(HomeActivity.this, WatchlistActivity.class);
intent.putExtra("username", currentUser.getUsername());
startActivityForResult(intent, 0);
return true;
case R.id.menu_history:
Intent intent2 = new Intent(HomeActivity.this, HistoryActivity.class);
intent2.putExtra("username", currentUser.getUsername());
startActivityForResult(intent2, 0);
return true;
case R.id.menu_scores:
// Scores only available with Facebook login
if (facebookLogin)
{
Intent scoreIntent = new Intent(HomeActivity.this, ScoresActivity.class);
scoreIntent.putExtra("username", currentUser.getUsername());
scoreIntent.putExtra("accessToken", accessToken);
Session session = Session.getActiveSession();
scoreIntent.putExtra("session", session);
startActivityForResult(scoreIntent, 0);
}
else
Toast.makeText(getApplicationContext(), "Please login to Facebook to use this feature.", Toast.LENGTH_SHORT).show();
return true;
case R.id.menu_settings:
Intent intent3 = new Intent(HomeActivity.this, SettingsActivity.class);
intent3.putExtra("username", currentUser.getUsername());
startActivityForResult(intent3, 0);
return true;
default:
return super.onOptionsItemSelected(item);
}

Android action bar 'up' items, with activities that have more than one parent

I have an Android app that uses the action bar, and the flow through the system is determined in the manifest as so:
<... android:parentActivityName="com.polymorph.amsmobile.xyzActivity" >
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="com.polymorph.amsmobile.xyzActivity" />
However there is a screen that users can go to from several points within the hierarchy and as such there is more than one 'parent' activity, so I want to dynamically specify the parent activity rather than specifying in the manifest.
My goal is to ensure that when they use the 'up' on the action bar, it will take them to the correct page of the app.
Do you mean something like this in an Activity from where you want to be able to go Up to another activitiy from the ActionBar?
#Override
protected void onCreate(Bundle b) {
ActionBar ab = getActionBar();
ab.setHomeButtonEnabled(true);
ab.setDisplayHomeAsUpEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, GoToThisActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
}
}
If you just want to go to the previous activity, you can just do:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
break;
}

How to call Activity from a menu item in Android?

I'm attempting to call startActivity(myIntent) from the click of a menu button but my application crashes at that point.
The same startActivity call works fine from a regular button click, so, I assume the menu button is missing information about the context? Or maybe I'm totally off the mark here.
So... what's the correct way to have a menu item take me to a specific Activity?
I've revised my code based on the initial set of advice. Still crashing in the same place. The debugger doesn't enter the exception clause, the app just dies.
[EDITED WITH CODE SNIPPET]
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
try{
switch (item.getItemId()) {
case R.id.menuItemLang:
startActivity(new Intent("com.my.project.SETTINGS"));
return true;
default:
return super.onOptionsItemSelected(item);
}
}catch(Exception e){
log(e);
}
}
First option
You have to override onOptionsItemSelected method in your Activity, which is called when user clicks on the item in Options menu. In the method you can check what item has been clicked.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_item1:
Intent intent = new Intent(this, ActivityForItemOne.class);
this.startActivity(intent);
break;
case R.id.menu_item2:
// another startActivity, this is for item with id "menu_item2"
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}
There is also onContextItemSelected method which works similary, but for Context menu (I'm not sure, what menu you mean).
More information at http://developer.android.com/guide/topics/ui/menus.html
EDIT:
Second option
I think the first option is easier, but from your code I see, that you want to start activity as an action (because of String parameter in Intent constructor). To do this, you need to specify an action in your AndroidManifest.xml. So, if I would start activity ActivityForItemOne (from previous example) the <application> element in AndroidManifest.xml would look like this:
<application ...>
...
<activity android:label="Activity For First Item" android:name=".ActivityForItemOne">
<intent-filter>
<action android:name="my.app.ITEMONE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
And the Intent will be:
Intent intent = new Intent("my.app.ITEMONE");
The my.app. is package of your application. It's not necessary to use your application package, but it's recommended for uniqueness of actions.
More information at:
Class Intent - Action and Category constants
Action element
Intents and Intent Filters
Hope this solve your problem.
More optimice:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:
return true;
case R.id.item2:
return true;
default:
return super.onOptionsItemSelected(item);
}
}
if There have 2 Class
1 MainActivity
2 Welcome
then you need to go from
welcom>MainActivity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.logout:
Intent intent = new Intent(this, MainActivity.class);
this.startActivity(intent);
break;
case R.id.settings:
// another startActivity, this is for item with id "menu_item2"
break;
default:
return super.onOptionsItemSelected(item);
}
return true;
}

Categories

Resources