How to stop the MainActivity from being called first? - android

In my AndroidManifest.xml file, I have two activities:
<activity android:name=".activities.LoginActivity"/>
<activity android:name=".activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
According to the logic of my app, if I'm logged in, I'm redirected directly to the MainActivity, otherwise to the LoginActivity. First time I'm opening the app, LoginActivity is opened but in the background MainActivity is also called. How stop this from happening? But without making LoginActivity as the main activity?

The solution I always adopt is to create a third Activity SplashScreenActivity
<activity
android:name=".activities.SplashScreenActivity"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
This is nothing more than a Loading Activity where you can instantiate all the stuff you need across application and where you can make this logic.
You can, for example, call this in your SplashActivity's OnCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(/*logics to see if user is logged*/) {
startActivity(SplashScreenActivity.this, MainActivity.class);
}
else {
startActivity(SplashScreenActivity.this, LoginActivity.class);
}
finish(); //finish the splash activity.
}
Another little trick :)
Link from PPartisan in comment: How to implement SplashScreen
I always make this activity Layout-less so that you don't have that annoying "black screen flash" when you first launch your application. In order to do that, as you can see, I specified a theme in that activity's manifest where I simply set this:
<style name="SplashTheme" parent="AppTheme">
<item name="android:windowBackground">#drawable/background_splash</item>
</style>
where that resource is nothing more than a drawable with a background (white background and logo in center, for example).
That way you won't have that black flash when you run your application.
Good luck!

You should move the following code to your login activity but LoginActivity will be the main activity:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
You can also use one activity with fragments inside and choose which fragment to display to the user according to the login status. See https://developer.android.com/guide/components/fragments
Finally, as mentioned in comments, you can create a splash screen that check if the user is already logged in. But here again, the splash screen will be your main activity. See https://android.jlelse.eu/right-way-to-create-splash-screen-on-android-e7f1709ba154
Best

Related

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.

How to make an activity above the MainActivity.java?

My current MainActivity is a navigation drawer.
I want to make another activity on top of the navigation drawer.
Lets make that activity StartActivity.
On StartActivity there is a start button.
What i want to do is make the StartActivity opens up first when the app runs.
And when the user presses the START button on the StartActivity, it will direct him/her to the navigation drawer.
is this possible?
Create the StartActivity.
somewhere call "startActivity(intentforMainactivity);
go to the manifest and move
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
from the
<activity
android:name="sehtestapp.MainActivity"
into
<activity
android:name="sehtestapp.StartActivity"
Your Application will then start the StartActivity first
1) Create another Activity, that you'll call StartActivity
2) Set up a layout that you'll use in your StartActivity with a
button in it.
3)Create the onClickListener to launch a new Intent when clicked.
Make it launch the MainActivity.
4) Change your AndroidManifest as follow :
<activity
android:name="XXX.StartActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="XXX.MainActivity"
android:parentActivityName="XXX.StartActivity" />
You can try changing the Launcher activity and send intent having a boolean bundled in it when START button is pressed, in MainActivity fetch the intent, read that boolean value and open the drawer programmatically.

Want to launch another activity on start up page without using any listener?

Example I have a java class that has sliding menu code which the java name is Leftandright.java.
Then I have a Main_Activity, but without any listener I want the Application to launch at the LeftandRight.java page. How do I do that?
You can set the starting activity in manifest file, AndroidManifest.xml, by declaring that Activity as a main activity.
<activity
android:name="com.package.LeftandRight" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Or, you can add this code in Main_Activity.java (although this is a VERY BAD approach, do not use unless you know what you're doing)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startActivity(new Intent(this, LeftandRight.class));
}

How to handle Intents in Android app when you have Login Activity

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!

Open only one activity, without the main activity

I have an application that has one service and 2 activities.One activity (the main one) is a preferences activity and the other one is a dialog themed activity. The service from time to time needs to open only the dialog themed activity (using FLAG_ACTIVITY_NEW_TASK).
The problem is that when the preferences activity is opened in background (for example the user pressed HOME key instead of BACK, so the activity is OnPause) and the service tries to open the dialog themed activity, also the main activity is opened (comes in foreground).
I don't want this. So, how can I open only the themed activity from the service, without the main activity pop up ?
Android Manifest .xml
<service android:name=".SimpleService"> </service>
<activity
android:name=".Preferences" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".popup_activity" android:theme="#android:style/Theme.Dialog" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="screenon.popup.activity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
And from the service :
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory("screenon.popup.activity");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
I believe you're looking for the android:launchMode attribute.
Alex , I believe that all you want is to display preferences activity just once & then it must die(or lets say finish()) .
In that case you can override onResume of the preferences activity
to finish your preferences activity after it is resumed after pause
#Override
public void onResume()
{
//if activity is resumed after onPause then only run it
this.finish(); //simply kill your activity if it is resumed after pause
}
EDIT-To know whether the activity was paused you need to override onPause().I think you can dig out the rest.
Hope it helps!

Categories

Resources