I am trying to achieve following case on Android, but no success:
1) Launch Application (Launcher Activity which is a subclass of Base Activity). The Base Activity has code as follows:
///This is in BaseActivity
#Override
public void onCreate(Bundle instance)
{
super.onCreate(instance);
//Config.isLoggedIn() is a static function.
if(! Config.isLoggedIn())
{
////Config.startLoginActivity is a static function
Config.startLoginActivity(this, getIntent());
finish();
}
}
The Config.startLoginActivity functions is defined as
public static void startLoginActivity(final Context ctx, final Intent finishIntent)
{
Intent i = new Intent(ctx, ItemListActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("FINISH_INTENT", finishIntent);
ctx.startActivity(i);
}
Now, the ItemListActivity contains a list of Items as {Item1, Item2, Item3}. In ItemListActivity, I am saving the passed "finishIntent" as
///This is ItemListActivity onCreate Method
if(getIntent().hasExtra("FINISH_INTENT"))
mFinishIntent = getIntent().getParcelableExtra("FINISH_INTENT");
and the onItemListSelected method is described as follows :
#Override
public void onItemSelected(String id) {
Config.setLogInState(true);
if(mFinishIntent != null)
{
Log.i("ITEMLISTACTIVITY", "Class Name = " + mFinishIntent.getClass().getName());
Log.i("ITEMLISTACTIVITY", "Starting mFinishIntent Activity");
startActivity(mFinishIntent);
finish();
}
}
But the issue is the Main Activity is not being launched again, Android takes me to the home screen instead. While looking for a solution, I saw that Google I/O app has the same implementation and that works flawlessly but in my case it is not. I am unable to figure it out. Please help.
Thanks in Advance.
Manifest File is as follows :
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.app.myapplication.ItemListActivity"
android:label="#string/app_name" >
</activity>
<activity
android:name="com.app.myapplication.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Ok Here is a quick help which works for 100 percent which I'm using not mostly but EVERYTIME! you must past it through intent and in your case here it is how it must look like.
Intent intent = new intent(//name of your activity in which you are at the moment.this, //name of activity to which you want to go.class);
startActivity(intent);
Hope this will help
Related
I need my app to check if it's running for first time or not. If it's the first time, then it should launch LoginActivity instead of MainActivity. And if it's not the first run, it should display MainActivity as usual.
I used SharedPreference value to check if it's available, then app decides its not running it's first run.
This is what I've tried so far
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set default values into settings
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
// Check if the app is running on its first run
SharedPreferences fRun = getPreferences(MODE_PRIVATE);
if(fRun.getBoolean("firstrun", true)){
SharedPreferences.Editor editX=fRun.edit();
editX.putBoolean("firstrun", false);
editX.apply();
// Login activity stuff here
// Goto login screen
Intent loginIntent=new Intent(getApplicationContext(),LoginActivity.class);
startActivity(loginIntent);
//finish();
} else {
setContentView(R.layout.activity_main);
}
}
}
My problem is, when I run my app, it suddenly crashes and displays message Unfortunately, the app has stopped.
Why does the app crash? Is it because code in my LoginActivity have errors or do I need to first load MainActivity then call LoginActivity?
You can use LoginActivity as LAUNCHER activty and check whether the user is logged in. If yes, start MainActivity.
The AndroidManifest.xml:
<activity
android:name=".LoginActivity"
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=".MainActivity"/>
And the LoginActivity:
public class LoginActivity extends ActionBarActivity {
private static final String LOGIN_KEY = "LOGIN_KEY";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SharedPreferences pref = getPreferences(Context.MODE_PRIVATE);
if (pref.getBoolean(LOGIN_KEY, false)) {
//has login
startActivity(new Intent(this, MainActivity.class));
//must finish this activity (the login activity will not be shown when click back in main activity)
finish();
}
else {
// Mark login
pref.edit().putBoolean(LOGIN_KEY, true).apply();
// Do something
}
}
}
The MainActivity:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Do something
}
}
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity android:name=".Activity.MainActivity" />
<activity android:name=".Activity.SignupActivity" />
<activity android:name=".Activity.SigninActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
You need to rearrange your Activity classes a bit I think. It's very simple to decide if your application has run first time or not and launch some Activity based on this decision. I would like to suggest the following architecture.
You can set a LauncherActivity to decide whether you need to start LoginActivity or MainActivity like this:
public class LauncherActivity extends Activity {
private boolean firstLaunch = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent i;
SharedPreferences pref = getSharedPreferences(Constants.ApplicationTag, MODE_PRIVATE);
firstLaunch = pref.getBoolean(Constants.FIRST_LAUNCH, true);
if (firstLaunch) {
i = new Intent(LauncherActivity.this, LoginActivity.class);
startActivity(i);
} else {
i = new Intent(LauncherActivity.this, MainActivity.class);
startActivity(i);
}
finish();
}
}
You have another problem I need to sort out is calling setContentView inside an else statement which is erroneous. You need to put setContentView just after the super.onCreate(savedInstanceState); in any of your Activity.
When you're putting it inside an else statement, the content view may not be set which will cause an application crash.
So remove the checking for first run from MainActivity and move that portion to LauncherActivity which will solve the problem.
The AndroidManifest.xml of the LauncherActivity may look like this
<activity
android:name=".Activities.LauncherActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
In my application I have several "intents" that I use to transition between different activities in my application. I have noticed a strange behavior that occurs on Samsung devices - but not on Nexus devices - whenever a new intent is created the application launches a second "task" for this new activity! When the user goes to the multi-tasking menu they can see multiple copies of the application! This is not the desired behavior. Any and all advice would be greatly appreciated!
Manifest:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme"
android:launchMode="singleInstance">
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"
android:launchMode="singleInstance">
</activity>
<activity
android:name=".Settings_area"
android:screenOrientation="portrait" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="AIzaSyDieXTCaFoIL0kJ_IM4UMBSQL3sNn92AWM" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps" />
<activity android:name=".Splash"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".aboutPageActivity" />
<activity android:name=".turnOffFromNotification"
android:noHistory="true"></activity>
</application>
I have already attempted removing the launch modes as well as changing the application launch mode to singleTop and standard.
Intent that creates a second instance:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent mainIntent = new Intent(Splash.this,MainActivity.class);
Splash.this.startActivity(mainIntent);
Splash.this.finish();
}
}, splashDisplayLength);
return;
}
Intent that creates a third instance:
public void goToAboutPage()
{
Intent goToAboutPage = new Intent(this, aboutPageActivity.class); //create the intent to go to the map screen
startActivity(goToAboutPage); //actually go to the map screen
}
A third instance can also be created from launching a settings intent:
public void changeToSettingsScreen() //changes the screen to the setting screen
{
readyToSendPackets = false;
sendSwitch.setChecked(false);
// textView.setText("NOT sending"); //set the textview to advise users packets are not being sent
Intent goToSettings = new Intent(this, Settings_area.class);
startActivity(goToSettings);
}
I also over rode the onNewIntent Method:
protected void onNewIntent(Intent intent) {
// super.onNewIntent(intent); //REMOVED THIS TO AVOID DOUBLE INSTANTIATION ON TOUCHWIZ IF ANYTHING BREAKS LOOK HERE FIRST
setIntent(intent); //this allows us to recieve the extras bundled with the intent
// System.out.println("Here is the bindle: " + getIntent().getExtras());
if (getIntent().getExtras() != null) //check to see if there are any extras, there wont be on apps first start
{
Bundle extras = getIntent().getExtras(); //get the extras
String methodName = extras.getString("methodName"); //assign the extras to local variables
if(methodName != null && methodName.equals("turn_send_switch_off"))
{
sendSwitch.setChecked(false);
}
//else if(**other actions that may need to be performed can go here**)
}
Thank you very much for any help!!!
Usually if you have to force a single instance of the app, you should avoid putting android:launchMode="singleInstance" on each activity seeing as it would try to launch an instance for each activity.
Removing the launchMode from everything except the application should ensure that only the application runs in a single instance, although what #Shaishav said is true, most of the time you can let android deal with the lifecycle of an application by not setting the launchMode, unless you have a real need to ensure only one instance is running at a time.
The question can be asked in two ways:
- How I can make some processing of variables and data before launching the main activity?
- How I set the main launcher activity based on some logic? i.e. before viewing an activity from a set of activities, I should retrieve data from preferences. And this should be done only for the 1st usage without preferences activity to be saved in the back button stack.
public static String getProfile(Context context) {
SharedPreferences mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
// String profile = mSharedPreferences.getString("pref_profile_list", "-1");
String profile = mSharedPreferences.getString("pref_login_list", "-1");
Log.i(TAG, profile);
return profile;
}
void init() {
String profile = getProfile(this);
Log.i(TAG, "getProfile " + profile);
switch (parseInt(profile)){
case 0:
startActivity(new Intent(this, firstActivity.class));
break;
case 2:
startActivity(new Intent(this, secondActivity.class));
break;
default:
Log.i(TAG, profile);
}
}
Thanks.
You can use the android:name="your class name" inside the <application> tag of the manifest file.
android:name :
The fully qualified name of an Application subclass implemented for the application. When the application process is started, this class is instantiated before any of the application's components.
The subclass is optional; most applications won't need one. In the absence of a subclass, Android uses an instance of the base Application class.
Example:
public class Platform extends Application {
public static String str="";
#Override
public void onCreate() {
super.onCreate();
str="I am executed first";
}
}
To execute Platform before any other application's component add this Platform class to manifest file of your project like below,
<application
android:name="com.example.Platform"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen" >
<activity
android:name="com.example.HomeActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Hope it helps.
For reference read http://developer.android.com/guide/topics/manifest/application-element.html
create a activity "UILApplication" for your resource initialization
and in the manifest include that
**android:name="com.example.UILApplication"**
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.Light.DarkActionBar" >
<activity
android:name="com.example.HomePage"
android:label="#string/app_name"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
........
so that it will execute before your launch activity..
Hope this Helps you
The best option would be to use a Splash Screen.
The Splash Screen can be used for a variety of purposes including loading data, making calls to the server, showing the app logo and applying whatever logic you would want. You can think of it as an Activity which runs before your MainActivity and does the pre-processing, while showing a progress screen to the user.
You can create an Class by extends Application class
PreAppResources.Java
public class PreAppResources extends Application{
public static String execute="execute before mail activity";
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
System.out.println(execute);
}
}
AndroidManifest.xml
<application
android:allowBackup="true"
android:name="com.example.listtt.PreAppResources"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.listtt.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
If its not working please let me know i will try to help you more.
I'm new in this world. I have a problem when I use startActivity(intent).
This is the Manifest:
<activity
android:name="com.example.counter.Splash"
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="com.example.counter.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
And this is the code:
public class Splash extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread timer = new Thread(){
public void run()
{
try
{
sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
finally
{
Intent i=new Intent ("com.example.counter.MainActivity");
startActivity(i);
}
}
};
timer.start();
}
I'd want to show Splash activity for 5 seconds and then show MainActivity.
LogErrors: !https://www.dropbox.com/s/kg7xyp6h4b95itq/Screenshot%202014-02-08%2016.57.36.png
There are two ways of doing what you are trying to do.
Using an implicit Intent
Using an explicit Intent
Refer Intent Types
Implicit Intent
Declare Intent Filters for your Activity in your AndroidManifest.xml. By doing that the Android system understands what kind of Intents your component(in this case your MainActivity) can handle.
<activity
android:name="com.example.counter.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.counter.MainAction" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<activity>
Now you will be able to launch your Activity with the same Intent
Intent i=new Intent ("com.example.counter.MainAction");
startActivity(i);
Such implicit Intents are used when you don't explicitly know which Activity has to be started and you want the Android system to decide which component to start. If the system finds multiple components which can handle your Intent, it will allow the user to choose.
Note: it is possible that there are no applications that can handle your intent. In this case, your application will crash when you invoke startActivity(). To avoid this, before calling startActivity() you should first verify that there is at least one application registered in the system that can handle the intent. To do this use resolveActivity() on your intent object.
Explicit Intent
In your case, you should use an explicit Intent as you already know which Activity you want to start. So create an Intent by passing the context and the component(Activity) class you want to start.
Intent i=new Intent (this,MainActivity.class);
startActivity(i);
You have to reference the class you want to start. So you'd need something like:
Intent newAct = new Intent(this, Splash.class);
startActivity(newAct);
What you're passing is an Action that is not understood as a class name.
I guess, Splash is your Launcher Activity, make following changes in your manifest file:
<activity
android:name="com.example.counter.Splash"
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="com.example.counter.MainActivity"
android:label="#string/app_name" >
</activity>
Make your activity this way:
public class Splash extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
/*Splach screen that display for 5 seconds when app start*/
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(Splash.this, MainActivity.class);
startActivity(i);
finish();
}
}, 5000);
}
}
I hope this should solve your problem now.
I think you should be able to use (implicit Intent):
Intent i=new Intent ("com.example.counter.MainActivity");
There is no reason to change it to (explicit intent):
startActivity(new Intent(mContext, MainActivity.class));
but then you need to change the action in intent filterof MainActivity from:
<action android:name="android.intent.action.MAIN" />
to:
<action android:name="com.example.counter.MainActivity"/>
You need to declare an activity in manifest file.
Like this:
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".FirstActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activty
android:name="com.example.counter.MainActivity"/>
</application>
Hope it helps.
i think it is better if you use Handler put this code at the splash Activity at the onCreate
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
finish();
}
}, 1500);
and if you want to open it one time it is good to use SharedPreferences
Im writing a program that offers a quick reply dialog upon receipt of an SMS.
However, I am getting an unexpected result. When I receieve an SMS, the appropriate dialog activity comes up displaying the correct phone number and message, however there is a second activity behind it that is the 'default' activity in my program (it is what opens when i launch my application)
I do not want this second activity to come up. The quick reply activity should come up by itself over top of whatever the user was doing before.
The 'floating' activity:
public class quickReply extends Activity {
String mNumber, mMessage;
TextView mMainText;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mMainText = (TextView)findViewById(R.id.mainText);
try{
Intent i = getIntent();
Bundle extras = i.getExtras();
mNumber = extras.getString("theNumber");
mMessage = extras.getString("theMessage");
this.setTitle("Message From:" + mNumber);
mMainText.setText(mMessage);
} catch(Exception e) {
mMainText.setText(e.getMessage());
}
}
}
The call to the activity inside an onReceive()
Intent i = new Intent(context, quickReply.class);
i.putExtra("theNumber", mNumber);
i.putExtra("theMessage", mMessage);
i.setFlags(
Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
The Manifest:
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".quickReply"
android:label="#string/app_name"
android:theme="#android:style/Theme.Dialog"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".SmsReceiver">
<intent-filter>
<action android:name=
"android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
the only way I have found that works, in your activity definition in manifest:
android:launchMode="singleInstance"
but then you have to relaunch your main/default activity once the dialog is dismissed. NOTE: you will lose all state from the previous launch, so this is a less than ideal solution.
UPDATE:
you can also do this by:
Intent.FLAG_ACTIVITY_CLEAR_TASK
so here's what I did:
open the original/main activity
from a service, launch the dialog style activity using the above (main goes bye-bye).
when the user dismisses the dialog, start main again with an extra intent (IS_BACK) that is processed in onCreate() and calls:
moveTaskToBack(true);
this will keep the task under the dialog on top and your main in the back of the stack.
You should set the task affinity of the activity to something different than your main activity. This will separate it from the main activity and it will track as a separate task:
<activity android:name=".quickReply"
android:label="#string/app_name"
android:theme="#android:style/Theme.Dialog"
android:launchMode="singleTask"
android:taskAffinity="quickReply"
>