Choose an activity to load in startup - Android - android

I have an android application which needs to decide which activity to load first (from 2 activities) on startup. The application is a kind of an alarm. So, the thing is I have to launch one of those activities by checking whether there is already an alarm is set or no alarm is set.
Is there a way to check this on startup using AlarmManager class without conflicting with the default alarm application in my phone.
Or should I use a database of temporary data storing method to get the details.
How can I develop this.
Please help me.

Define an activity that takes care of this. Give it the intent filter so it is launched first
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
In this activity, perform the logic that decides which activity should be opened.
For example, my app has a SplashActivity that checks if a user is logged in. If there's none, it starts LoginActivity, if there is, it goes to content activity.
<activity
android:name=".SplashActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
and
public class SplashActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (userLoggedIn()) {
startActivity(new Intent(this, ContentActivity.class));
} else {
startActivity(new Intent(this, LoginActivity.class));
}
}
}

Have a common base Activity and in its onCreate method you can write logic to choose from your Activitys, and start the chosen Activity from there. The base Activity need not load any UI (i.e. need not call setContentView) and it can call finish() just after launching the Intent.

Related

Multiple Instances of the same app are generated in stack

If there is an app has a login activity, and it launches by the icon click. this login activity can be launched by another intent too. the problem is when the activity is running, (launched by touching the app icon) and when it receives the different intent call it starts another login activity.
how can i launch the login activity again after closing the current running activity, when the different intent call is received to launch the login activity.
the different intent mentioned above is, when the user select an specific file with specific extension, my app must be started.
<activity
android:name=".login.Login"
android:configChanges="orientation|keyboardHidden"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT" />
<data
android:scheme="content"
android:mimeType="application/octet-stream"
android:pathPattern=".*\\.chat"
tools:ignore="AppLinkUrlError" />
</intent-filter>
</activity>
The second intent is called , my app downloads the selected file and stores it in internel storage.
this is the onCreate method in the Login Activity
public void onCreate(Bundle savedInstanceState) {
if (getResources().getBoolean(R.bool.portrait_only)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
super.onCreate(savedInstanceState);
if (isTaskRoot()) {
Uri data = getIntent().getData();
if (data != null) {
getIntent().setData(null);
try {
importData(data);
} catch (Exception e) {
// warn user about bad data here
finish();
return;
}
}
}
...................................
}
when user selects a specified file, the app launches another activity. then there are two login activities in the stack. help me to get rid of this
singleinstance, singletask solutions were tried. but when the launchingmode is set to singleinstance or singletask and the second intent call is received it does not call the
importData()
method. so the file that i want to download is not downloaded..
Here I used "singleTask" as launchMode. Then I have to use onNewIntent() when the Activity is called again. below link gives some more Explanation.
“onCreate()” method is not called from another intent filter

How to check if user actually started the android app, not just returned to the activity?

How to distinguish the call of onCreate() on actual start of app or on switching activities of already started app and similar actions (like returning to the app while it is not shut down)?
I've already tried to check if savedInstanceState!=null, but it only works on screen rotation, not returning to the activity from another activity of this app or another app. I also tried to get/set a special variable in onRestoreInstanceState() and onSaveInstanceState(), but it is not the solution for described cases.
How to implement this checking?
static boolean isFirstRun = true;
public void onCreate(...) {
if (isFirstRun) {
// do stuff
isFirstRun = false;
}
}
Did you try to do something like that?
What you can do in this case, is make your "default" Activity a basic launcher style Activity. Its only purpose is to launch your main Activity. When the launcher starts the main Activity, it can pass that fact through with a Bundle.
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("first_start", true);
startActivity(intent);
The launcher Activity is defined in XML as having noHistory. That way, it will only be opened with the App is started for the first time.
<activity
android:name=".LauncherActivity"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>

How to resume android app without losing activities stack (or the app state) with deep linking?

I have this <intent-filter> that every time certain link is pressed it opens my app but the problem is it opens a new instance of my app. Is there anyway to trigger onResume() and just resume my app without losing its state or the activities stack?
This is the intent filter:
<intent-filter>
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="example.com" />
<data android:pathPattern="/.*" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
Update
Thanks to user David Wasser answer below I found answer:
So I created EntryActivity which is launched on top of gmail/inbox app:
public class EntryActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.entry_activity);
Uri uriParams = getIntent().getData();
Log.e("EntryActivity", uriParams.getHost() );
Log.e("EntryActivity", uriParams.getQueryParameter("uid") + " " + uriParams.getQueryParameter("type") + " " + uriParams.getQueryParameter("token") );
Intent startCategory = new Intent(this, GotEmailActivity.class);
startCategory.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startCategory);
this.finish();
}
}
Then when my app is opened at GotEmailActivity I send email to user with link to open app and GotEmailActivity has attribute android:launchMode="singleTop" in AndroidManifest so only 1 instance of it is opened:
<!--
Important: notice android:launchMode="singleTop"
which seeks if an instance of this activity is already opened and
resumes already opened instance, if not it opens new instance.
-->
<activity
android:name=".presenters.register.email.GotEmailActivity"
android:label="#string/title_activity_got_email"
android:launchMode="singleTop"
android:theme="#android:style/Theme.Translucent.NoTitleBar" >
Now what is happening is that EntryActivity is opened ontop of Gmail app but it closes inmediatle but first launches GotEmailActivity which is already opened so attribute launchMode Singletop prevents a new instance of such activity.
You should create another Activity that you use as an entry point to your application when responding to that <intent-filter>. Something like this:
What you need is just a simple Activity that does nothing. Here is an example:
public class EntryActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Check to see if this Activity is the root activity
if (isTaskRoot()) {
// This Activity is the only Activity, so
// the app wasn't running. So start the app from the
// beginning (redirect to MainActivity)
Intent mainIntent = getIntent(); // Copy the Intent used to launch me
// Launch the real root Activity (launch Intent)
mainIntent.setClass(this, MainActivity.class);
// I'm done now, so finish()
startActivity(mainIntent);
finish();
} else {
// App was already running, so just finish, which will drop the user
// in to the activity that was at the top of the task stack
finish();
}
}
}
Put your <intent-filter> on this activity, instead of your "launcher" Activity. Make sure that in the manifest the task affinity of this activity is the same as the task affinity of the other activities in your application (by default it is, if you haven't explicitly set android:taskAffinity).
When the <intent-filter> gets triggered, if your application is running, then the EntryActivity will be started on top of the topmost activity in your application's task and that task will be brought to the foreground. When the EntryActivity finishes, it will simply return the user to the topmost activity in your application (ie: wherever the user left it when it went into the background).
If your app was not running, the EntryActivity recognizes this and starts your app from the beginning, passing it the Intent containing the ACTION and DATA that triggered the <intent-filter>.
Should work.

How do I make an activity the first activity launched but only on the first run of the application

I need my app to have one activity(Register) be the first activity launched when an app is first installed but then after the initial run it will have a different activity(LogInActivity) be the first activity launched... I have put code in that makes the Register activity only run once but I can't figure out how to alter my manifest to get the desired results. I have tried moving the MAIN action to the Register activity but that causes it to be launched everytime I run my app. When the MAIN action is in the LogInActivity then Register doesn't run at all. I also tried to add a DEFAULT action in my manifest under the opposite activity of where I had the MAIN action but that didn't work either and upon further research of what DEFAULT does I don't believe this is what I need. So is there some other intent I need to add to my XML?
Manifest:
<application
android:allowBackup="true"
android:icon="#drawable/skey"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
///////////FIND INFO ACTIVITY
<activity
android:name=".FindInfoActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.LogInActivity" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
//////////LOG IN ACTIVITY
<activity
android:name=".LogInActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.LogInActivity" />
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
//////////REGISTER ACTIVITY
<activity
android:name=".Register"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.LogInActivity" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Don't have three separate LAUNCHER activities unless you want the user to be able to launch the app from the homescreen from three separate items (there are valid use-cases for this, but this isn't it).
Have one activity that handles launching the application. It checks the boolean in your SharePreferences, then starts the appropriate activity from there. Then just finish the Activity so the user won't re-open it when the user presses "Back".
public class LauncherActivity extends Activity {
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
if (firstTimeRunning()) {
// start register activity.
} else {
// start login activity.
}
finish();
}
}
In the Manifest just have this Activity as:
<activity android:name=".LauncherActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
You don't need any IntentFilters for your register activity or login activity because these are never opened through implicit intents, nor do they have any special permissions (from what I can see).
Use SharedPreference. When you open the app the first time do this:
SharedPreferences shared;
shared=getSharedPreferences("com.example", Context.MODE_PRIVATE);
shared.edit().putBoolean("first_time",true).apply();
in your onCreate() of first Activity do this:
SharedPreferences shared;
shared=getSharedPreferences("com.example", Context.MODE_PRIVATE);
if(shared.getBoolean("first_time",false)){
startActivity(new Intent(FirstActivity.this, NewFirstActivity.class));
finish();
}
Is the easiest way to "storage" data and states. SharedPreference also works with Strings, Int values, etc (if you don't want boolean value)
In your Manifest you should have only one launcher class, in the same class's onCreate method check for already logged in condition (SharedPreference). If yes, then using Intent launch HomeActivity otherwise launch LoginActivity if the user has registered and logged out. When user logs in, save account id / session details / user details in SharedPreference which you can validate in your launcher class for starting specific activity.
As Mariano said, you can use SharedPreferences. If you don't want to open your settings at startup you can use a Dialog to let the user decide to go to your settings or do nothing.
By the way, I think that use SharedPreferences to store login information (username and password) is best practice than be asking these values every time you start an app.

Android Lollipop App Notification Settings

In Android Lollipop, when you long press a Notification, it gives you access to settings for that Notification's app, such as priority, or simply blocking it. Is there an intent that I can use to access those settings?
Found the answer here - https://plus.google.com/+CyrilMottier/posts/YY6tbJrJMra
You need to add this to the activity you want to be attached to that settings icon
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.NOTIFICATION_PREFERENCES" />
</intent-filter>
In addition to the correct answer from #shmuel :
In case you want this "App settings" system button to jump to one specific fragment of your app's Settings activity deriving from PreferenceActivity, you can create a dummy intermediary activity to handle the intent-filter as details above, and then in this activity you simply do:
public class DeepSettingsFragmentDummyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent settingsIntent = new Intent(this, SettingsActivity.class);
// Standard mechanism for a PreferenceActivity intent to indicate
// which fragment to activate automatically.
settingsIntent.putExtra( PreferenceActivity.EXTRA_SHOW_FRAGMENT,
YourTargetPreferenceFragment.class.getName());
startActivity(settingsIntent);
finish();
}
}
This code automatically launches the YourTargetPreferenceFragment fragment, and then dismisses itself (finish()) so as to not remain in the activity stack when the user hits Back.
Your Manifest must contain:
<activity
android:name=".DeepSettingsFragmentDummyActivity"
android:label="...">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.NOTIFICATION_PREFERENCES" />
</intent-filter>
</activity>

Categories

Resources