Implicit vs Explicit Intent in Android ( startActivity(intent) crashes ) - android

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

Related

Ordering activities in Android Manifest

Having issues trying to order the some of my activities in my application. Have implemented some ideas that I have seen on SO, but to no avail.
At the minute, my application is going SplashScreen > MainActivty. I want SplashScreen > LoginActivity > MainActivity
Any indications on where I'm going wrong would be appreciated.
Manifest
<activity
android:name="com.example.XXX.myapplication.SplashScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.XXX.myapplication.LoginActivity"
android:parentActivityName=".SplashScreen">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.XXX.myapplication.SplashScreen" />
</activity>
<activity
android:name=".SignUpActivity" />
<activity
android:name="com.example.XXX.myapplication.MainActivity"
android:parentActivityName=".LoginActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.XXX.myapplication.LoginActivity"
android:theme="#style/Theme.AppCompat.Light.NoActionBar" />
</activity>
You don't order activities in the manifest like this. Set your splash screen to the default activity. In the Java code for splash activity start mainactivity with the startactivity method. Then in loginactivity call startactivity for mainactivity.
https://developer.android.com/training/basics/firstapp/starting-activity.html
You should do it programmatically in Java, in your SplashScreen Class, you should have something like :
startActivity(new Intent(SplashScreen.this, LoginActivity.class));
Example :
private final int SPLASH_DISPLAY_TIME = 5000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent myIntent = new Intent(SplashScreen.this, LoginActivity.class);
startActivity(myIntent);
finish();
}
},SPLASH_DISPLAY_TIME);
}
Place and `Intent-filter` tag in your intended entry activity in AndroidManifest.xml file like this
```
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
```
If your initial activity is a place, start the next activity in your runnable thread as shown below.
```
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent(SplashActivity.this,ACTIVITY_TO_GO_TO.class);
startActivity(mainIntent);
finish();
}
}, TIME_OUT_NOW);
```
You can then move to anywhere else in ACTIVITY_TO_GO_TO activity.
You can not ordering Activities by Manifest
1.Your Launch page is Splash.So you can write below code in splash page
Thread timerThread = new Thread(){
public void run(){
try{
sleep(3000);
}catch(InterruptedException e){
e.printStackTrace();
}finally{
startActivity(new Intent(SplashScreenActivity.this,YourActivity.class));
finish();
}
}
};
timerThread.start();
You can write your Login Activity on plcae of YourActivity.
2.On Click Login button Ho to main Activity

Android didn't open open activity by url scheme if the app launch already

I have StartActivity and MainActivity, in manifest scheme is already set.
<activity
android:name=".StartActivity"
android:label="#string/app_name"
android:theme="#style/AppThemeNoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<data android:scheme="myApp" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:parentActivityName=".StartActivity" />
StartActivity:
public class StartActivity extends InstrumentedActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_start);
if (isLogin) {
Intent intent = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
}
}
The original design is after user pressed the url in browser, it open StartActivity and then go to MainActivity when user logined.
This works correctly in the first time (App is killed and user pressed the url).
But while the app is in the background (in MainActivity), after user press the url, it didn't go through StartActivity but only onResume of MainActivity.
Anyone know the reason? and how to make sure it go to StartActivity? Thanks.
when you open your Activity first time from URL ,that time Activity created so onCreate() method called .But if your Activity is in Background then
onNewIntent() will be called so Override this method And put you code here .
Add below method : IN MainActivity
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// add your code here
}
In Manifest :
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
/>
Start Activity :
Intent intent = new Intent(context, MainActivity.class);
startActivity(intent);
if you want pass any input value then you may pass in Intent through Bundle ,that is received into onNewIntent(Intent intent) ,and you can get just like we get data from Intent send from one Activity to next activity.

Is possible launch an an activity at Application.onCreate method?

The idea is to manage what activity will be launched depending on already set up properties?
Now I'm using Activity A1 which decides Activity A2 or Activity A3 will be launched.
A1 extends Activity{
...
onCreate(...) {
Intent intent = new Intent();
if (launchA2){
intent = new Intent(this,A2.class);
} else {
intent = new Intent(this,A3.class);
}
startActivity(intent);
finish();
}
...
}
Is there any solution to move this logic into Application class or somewhere without A1 class?
Futhermore, there is another problem about AndroidManifest.xml file.
<activity
android:name="A1"
android:launchMode="singleTop"
android:label="#string/app_alias">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Is it possible to change this Activity programmatically?

how to start an activity in another module explicitly

I created an aar and i added it to my project as an module. in this module i have a HelloWorldActivity that i want to run.
my module manifest looks like this.
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="ir.sibvas.testlibary1.HelloWorldActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="ir.sibvas.testlibary1.HelloWorldActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
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>
</application>
Now i can start this activity from my project using this code
Intent intent = new Intent("ir.sibvas.testlibary1.HelloWorldActivity");
startActivity(intent);
but as you can see this code is implicit and problem with implicit calling is that if i use this module in more than one app, both installed on user device it will show an app chooser dialog to user. So how can make this call explicit, preventing user from switching app?
this code will not run since HelloWorldActivity is not in the same package as calling activity
Intent intent = new Intent(this, HelloWorldActivity.class);
startActivity(intent);
I really don't want to change my module for each project that uses it.
You can use the Class.forName(), it worked for me when i was needed to start activity which is in another module in my project.
Intent intent = null;
try {
intent = new Intent(this,
Class.forName("ir.sibvas.testlibary1.HelloWorldActivity"));
startActivity(intent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
First module activity launch then second module activity launch
and write a line of code is perfectly fine.
try {
Intent launchIntent =
getPackageManager().getLaunchIntentForPackage("com.your.packagename");
if (launchIntent != null) {
startActivity(
launchIntent); //null pointer check in case package name was not found ClassNotFoundException
}
} catch (e) {
e.printStackTrace();
}
Intent intent = new Intent();
intent.setClassName(context.getPackageName(), "ir.sibvas.testlibary1.HelloWorldActivity");
startActivity(intent);

How to force app that has an main activity with category home set to close

i'm trying to develope an app for a tablet (ICS 4.0.3) that will be used in public places like bar, resturant ecc..
The user that uses that tablet ( so my application ) could not go in home and only administrator, setting a code, can go out.
What i've done is:
public class MainActivity extends Activity {
private Activity actual;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (getIntent().getBooleanExtra("EXIT", false)) {
finish(); // it doesn't work
}
}
#Override
public void onBackPressed() {
// do nothing!
}
}
MANIFEST:
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name"
android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY"/>
</intent-filter>
</activity>
ADMINISTRATION DIALOG:
TEST1: // application is relaunched
Intent homeIntent= new Intent(Intent.ACTION_MAIN);
homeIntent.addCategory(Intent.CATEGORY_HOME);
homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(homeIntent);
TEST2: // application is relaunched
System.exit(0);
TEST3: // it open settings (o.O)
Intent h = new Intent(Intent.ACTION_MAIN);
h.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
h.putExtra("EXIT", true);
context.startActivity(h);
My problem is that i can't go out from application.. how can i solve?
In TEST3 you've only provided ACTION_MAIN in the Intent. Android looks for apps that can handle this action and finds a long list of them. How should it know that it should launch yours?
I assume you've set your app as a HOME-screen replacement. Try adding this to the code for TEST3:
h.addCategory(Intent.CATEGORY_HOME);

Categories

Resources