I have an application that presents a sort of catalog of items in a ListView. The list is rather long, so I've implemented the Search capability like this:
<activity android:name=".ItemsOverview"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- enable the search dialog to send searches to ItemsSearch -->
<meta-data android:name="android.app.default_searchable"
android:value=".ItemsSearch" />
</activity>
...
...
<activity android:name=".ItemsSearch">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
ItemsSearch then presents the same ListView, but containing only items that match the Search criteria.
There are two fundamental problems with this:
ItemsSearch is an almost duplicate of ItemsOverview (but with some enhancements for the search capability);
ItemsSearch overlays ItemsOverview such that if three or four searches are done, it takes four or five presses of the Back button to get out. Not quite the desired effect. :)
I would like to, in some fashion, end the original Activity when the second Activity starts and, ideally, combine the two Classes (Overview and Search) into one. Is there a way for my Activity to detect that it's already running in another process, and to kill that other process at inception?
Once I understand this, I can probably figure out how to combine the two. What do others do when they need to utilize a filtered list?
If I understand, you would you like to clear the Activity Back Stack. Use the activity flags when you call your search Activity.
Intent intent = new Intent(this, Search.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
This is the developer page about the activity back stack.
To end old Activity when Search starts new Activity give finish() in odler activity and call new activity.
Intent intent = new (Intent(MainActivity.this,GPSActivity.class);
startActivityForResult(intent, ACTIVITY_GPS);
finish();
In this we can start new Activity GPSActivity and finishes MainActivity.
Related
In my app I have a Activity that is opened from a Notification, but is not declared has main activity or launcher activity·
Also, this activity is declared has "singleTop".
Works fine for most users, but some are a little problem.
In some occassions when click the Notification the Activity is opened and, when click back, the app Main Activity is shown.
How to don't show the main activity when click back?
Also, if the users are in this activity and click home, and later it clicks into the app icon in order to open the Main activity, the previously opened activity, that is not main activity is opened. This can change?
Thanks.
-- The structure of the manifest is:
<activity android:name=".MainActivity" android:label="#string/app_name" android:exported="true" android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ShowAlarmsActivity" android:launchMode="singleTop" android:exported="true" android:theme="#style/AppThemeWithoutActionBar" />
you may do this my either overriding on back press and starting the parent activity using this code
or if you are using action bar you may use parent activity tag
Intent intent = new Intent(getApplicationContext(), ParentActivity.class);
startActivity(intent);
also if you want to distinguish that if the user is coming from notification or from app launch you may use intent to pass some key value and cater it
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="parentActivity" />
I want to know what is the differences between the back and up actions.
I've already found online how they work, but I didn't find what different happens when I trigger them.
When I intent another activity and go back with up action, it seems to just show again my last activity without executing any method (my images show like it was cached).
When I intent another activity and go back with back action, it seems to reconstruct the entire layout (my images reloads).
What really happens?
Thanks.
First you must understand the concept of Up and Back navigation, you should read this link about Navigation with UP and Back
When pressed back button the actual screen is removed but when pressed up button relaunch the parent-activity.
In your manifest need to add propert launchMode of activity, something like this
<activity
android:name="com.example.client.app.MainActivity"
android:label="#string/app_name"
android:launchMode="singleInstance"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
I hope you serve.
I am looking for advice when it comes to properly handling flows between Activities. Let's say I have two activities - LoginActivity and MainActivity:
<activity
android:name=".LoginActivity"
android:configChanges="keyboardHidden|orientation"
android:label="#string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:configChanges="keyboardHidden|orientation"
android:label="#string/app_name"
android:launchMode="singleTop"
android:screenOrientation="portrait" />
Now, when application starts, I start LoginActivity, and if login is successful I show MainActivity.
Now, the problems start when I want to handle certain types of Intents. Let's say I want to add custom schema to my app:
<intent-filter>
<data android:scheme="customschema" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
To which activity would I add this? Ideally I would love to add it to MainActivity and then handle it in onNewIntent method, but it is possible that my app was not started and in that case, I first need to run LoginActivity. On the other hand if I add that to LoginActivity, I need a way to pass that intent to MainActivity once user is successfully logs in. Or if app is already started I need to switch focus from LoginActivity to MainActivity and pass intent data immediately.
I believe this problem must've been solved previously and I would much rather follow best practice rather than try to invent my own solution - which is why I am looking for advice.
Forget what I said initially, I was thinking of Broadcast Receivers.
Use this solution by Commonsware instead:
How to create/disable intent-filter by programmable way?
Your MUST never have more then a ONE LoginActivity instance.
Once you've received intent to your "Main activity" make sure in the onCreate method to check for the login, and if the user is not logged in, throw an intent back to the LoginActivity.
if the user have reached the LoginActivity, but is already logged in throw an intent back to the main activity.
This might cause a glitches in the UI, but that would only indicate a faulty design, since no event of any kind should arrive to an application which is not logged in!
I'm trying to integrate search in my app but I'm being blocked by one issue. My activity is declared like this and is located inside of TabActivity.
<activity
android:name="FileBrowserActivity"
android:screenOrientation="portrait"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"/>
</activity>
As you can see its launchMode is set to singleTop. But when I invoke search, input the search query and press enter another instance of such activity is launched. No onNewIntent is being called! But in the launched activity each new search doesn't launch a new activity.
The desired behaviour is to stay within current activity. Basically that's how android launcher search works.
You should rather use android:launchMode="singleTop" like described in this article.
You could use android:noHistory http://developer.android.com/guide/topics/manifest/activity-element.html#nohist
I have an activity handling search (ACTIVITY_1), which works perfectly when I use the search (via SEARCH button on the phone) within/from this activity.
However, when I use search from another activity (ACTIVITY_2..x) by implementing onNewIntent and forward the query string to my Search_Activity.class (ACTIVITY_1)
#Override
protected void onNewIntent(Intent intent) {
Log.i(TAG, "onNewIntent()");
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
Log.i(TAG, "===== Intent: ACTION_SEARCH =====");
Intent myIntent = new Intent(getBaseContext(), Search_Activity.class);
myIntent.setAction(Intent.ACTION_SEARCH);
myIntent.putExtra(SearchManager.QUERY, intent.getStringExtra(SearchManager.QUERY));
startActivity(myIntent);
}
}
it always pauses ACTIVITY_2 first and then goes to onCreate() of ACTIVITY_2.
Why does it recreate my ACTIVITY_2 when it is already there and doesn't go to onNewIntent directly?
Is there another way I can forward search queries directly to ACTIVITY_1? For example via a setting in the Manifest.xml
Is it possible to generally forward all search queries automatically to ACTIVITY_1 without even implementing onNewIntent in all the other activities?
Currently I have to put an <intent-filter> in every single activity to "activate" my custom search there and forward the query then to the activity that handles search via the onNewIntent (as shown above).
<activity android:name=".Another_Activity"
android:theme="#style/MyTheme">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
I'm not sure I understand the chain of events your describing, but here's how you need to configure your application in the case were ACTIVITY_1 is the search Activity you always want to launch from all your other Activities when the user presses the 'search' button.
Assuming that the search button works perfectly on Activity1, you just need to add a bit of glue meta-data to your application telling it that all your other Activities should use ACTIVITY_1 for searching, as shown in the manifest snippet below:
<application>
<meta-data
android:name="android.app.default_searchable"
android:value=".ACTIVITY_1" />
<!-- All your activities, service, etc. -->
</application>
Using this, you should be able to remove the intent-filters from all but ACTIVITY_1, and you won't need to use the onNewIntent handler in any of your other Activities.