I'm using this code on MainActivity for a splashscreen that works perfectly
final ImageView splash1 = (ImageView) this.findViewById(R.id.splash);
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
splash1.setVisibility(View.GONE);
}
}, 1000);
but everytime I'm back on MainActivity (where the main menu is), the splashScreen is there again. Is there a way to keep using this code, and just adding an if condition do not see the splashScreen after the first time?
(e.g: a variable that changes when the app loads)
Thanks in advance
Use 2 different activity SplashActivity and MainActivity.
Your "Splash" activity need to be MAIN LAUNCHER Activity. So modify the AndroidManifest file like this...
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
</activity>
<activity android:name=".Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
And Jump to MainActivity from SplashActivity after few seconds.. Use this code in SplashActivity.
Handler hadler=new Handler();
hadler.postDelayed(new Runnable() {
#Override
public void run () {
finish();
Intent i = new Intent(context, MainActivity.class);
startActivity(i);
}
}, 3000);
here 3000 is used for 3 seconds. The MainActivity auto start after 3 seconds. Hope it helps.
Use separate activity for splash screen after that go for MainActivity, Don't forget to use finish() in splash screen activity.
This link may help you
http://androidexample.com/Splash_screen_-_Android_Example/index.php?view=article_discription&aid=113&aaid=135
Simply create one variable to know whether its displayed or not.
class YourActivity extends Activity {
boolean isDisplayed;
#Override
protected void onStart() {
if (!isDisplayed) {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
isDisplayed = true;
splash1.setVisibility(View.GONE);
}
}, 1000);
} else {
splash1.setVisibility(View.GONE);
}
}
}
use finish() after starting the SplashScreen Activity
EDIT:
One more approach can be - Create a boolean application level variable (set to false) by extending Applicationclass & then checking it in the runmethod - If false then show the splash & set it to true, so that it will not execute again.
public class DefaultApplication extends Application {
private boolean isSplashDisplayed = false;
public boolean isSplashDisplayed() {
return isSplashDisplayed ;
}
public void setIsSplashDisplayed(boolean isSplashDisplayed) {
this.isSplashDisplayed = isSplashDisplayed;
}
}
Second Approach -
Its better to create a separate activity for Splash, then call MainActivity from SplashActivity & finish SplashActivity
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(SplashScreen.this, MainActivity.class);
startActivity(i);
finish();
}
}, 1000);
Also need to make your SplashActivity as launcher
<activity
android:name=".SplashActivity"
android:label="#string/title_activity_splash_screen" >>
<intent-filter>
<action android:name="android.intent.action.MAIN" />>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
< /activity>
Related
My app is starting twice and the weird thing is, it depends on the LOAD_TIME which activity is called twice. With a long delay, like >5000ms, my Main Activity is called twice. As you can see in the snap shot, with 2000ms, my startup activity and my run() Thread is called twice.
It also only happens on my emulator, if I use my physical phone everything runs fine. I thought it might has something to do with the Consumer class, which requires a newer build version. But I think it requires 24 and I am using Nexus 5 with version 30 so I should be fine.
Ami doing something wrong with the lifecycle or threading?
public class StartUpActivity extends AppCompatActivity {
public final int LOAD_TIME = 2000;
public static int counter;
final Handler handler = new Handler(Looper.getMainLooper());
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
counter++;
Log.d("debug counter startup: ", counter+"");
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.activity_start_up);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.titel_bar);
handler.postDelayed(new Runnable() {
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void run() {
Log.d("debug Handler: ", "run()");
PreLogin checkLoginStatus = new PreLogin();
checkLoginStatus.CheckIfStillLoggedIn((value) -> {
if(value==true){
Log.d("debug checkLogin", "checkIfStillLoggedIn=true");
Intent intent = new Intent(StartUpActivity.this, MainActivity.class);
intent.putExtra("caller", "StartUpActivity");
startActivity(intent);
finish();
}
else{
Log.d("debug checkLogin", "checkIfStillLoggedIn=false");
Intent intent = new Intent(StartUpActivity.this, ChooseLoginOrRegistrationActivity.class);
intent.putExtra("caller", "StartUpActivity");
startActivity(intent);
finish();
}
});
handler.removeCallbacks(null);
}
}, LOAD_TIME);
}
}
AndroidManifest:
<activity
android:name=".StartUpActivity"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
I have an app with two activities: MainActivity, which contains a URL entry field where the user can enter a YouTube video URL and press a submit button, to start the second activity, VideoActivity, which displays some information about this video (fetched from another web server).
The app also has a feature to receive intent via the Youtube application. When user presses the share button within the Youtube app, my app appears in the share list. Upon pressing share from the Youtube app, MainActivity should be brought to the front, and the URL should be posted within the MainActivity's URL field.
However, this only happens correctly on the first share. If the app is in the background when user shares from Youtube app, they are taken to whatever the last visible activity was, whether it is MainActivity or VideoActivity, (and even if it is MainActivity, the URL is not posted into the URL field, but the field is left in whatever state it was in when the app was last visible).
Here is my current AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.youcmt.youdmcapp">
<uses-permission android:name="android.permission.INTERNET"/>
<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">
<activity android:name=".MainActivity"
android:launchMode="singleTop">
<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.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
<activity
android:name=".VideoActivity"
android:parentActivityName=".MainActivity"/>
<service
android:name=".FetchVideoService"
android:exported="false"/>
</application>
</manifest>
Here is my MainActivity.java code:
public class MainActivity extends AppCompatActivity {
private ResponseReceiver mReceiver;
private EditText mUrlEditText;
private Button mSearchButton;
private ProgressBar mProgressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
mUrlEditText = findViewById(R.id.url_search_et);
Intent intent = getIntent();
if (intent.getType()!=null &&
intent.getType().equals("text/plain")) {
Bundle extras = getIntent().getExtras();
String value = extras.getString(Intent.EXTRA_TEXT);
if(value!=null)
{
mUrlEditText.setText(value);
}
}
mProgressBar = findViewById(R.id.progress_bar);
mSearchButton = findViewById(R.id.search_button);
mSearchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
askForVideo(mUrlEditText.getText().toString());
mSearchButton.setVisibility(View.INVISIBLE);
mProgressBar.setVisibility(View.VISIBLE);
} catch (Exception e) {
mUrlEditText.setText("");
mUrlEditText.setHint(e.getMessage());
e.printStackTrace();
}
}
});
}
#Override
protected void onResume() {
super.onResume();
//register the ResponseReceiver
mReceiver = new ResponseReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(FETCH_VIDEO_INFO);
registerReceiver(mReceiver, intentFilter);
}
private void askForVideo (String url) throws Exception {
try {
Intent intent = FetchVideoService.newIntent(this, url);
startService(intent);
} catch (Exception e) {
mUrlEditText.setText(e.getMessage());
}
}
public class ResponseReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int status = intent.getIntExtra(EXTRA_VIDEO_STATUS, FAIL);
mProgressBar.setVisibility(View.INVISIBLE);
mSearchButton.setVisibility(View.VISIBLE);
if(status==FAIL)
{
mUrlEditText.setText("");
mUrlEditText.setHint("Error retrieving video!");
}
else if(status==SUCCESS) {
Video video = intent.getParcelableExtra(EXTRA_VIDEO);
Intent videoActivityIntent =
VideoActivity.newIntent(getApplicationContext(), video);
startActivity(videoActivityIntent);
}
}
}
#Override
protected void onPause() {
unregisterReceiver(mReceiver);
super.onPause();
}
}
I do not think any of the other files will be useful in understanding the problem. Although this seems like something many app creators should have to deal with, I can find no answers to this problem. Please comment if you feel I should add any additional information and thank you in advance for any help!
Update: testing demonstrates that after the first use of "Share" from YouTube (and considering app remains in the background), the MainActivity no longer receives any new intent on further shares. However, my app is still brought to the foreground somehow. This is very confusing to me.
When you share from another app, your MainActivity is brought to the front and onNewIntent() is called on it. You don't override onNewIntent() so you never see the share Intent.
I am newbie to android studio and learning about services, I visited this page : https://xjaphx.wordpress.com/2012/07/07/create-a-service-that-does-a-schedule-task/
In which author made a background service as follows:
files go like:
So I create my own service called TimeService:
public class TimeService extends Service {
// constant
public static final long NOTIFY_INTERVAL = 10 * 1000; // 10 seconds
// run on another Thread to avoid crash
private Handler mHandler = new Handler();
// timer handling
private Timer mTimer = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
// cancel if already existed
if(mTimer != null) {
mTimer.cancel();
} else {
// recreate new
mTimer = new Timer();
}
// schedule task
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), 0, NOTIFY_INTERVAL);
}
class TimeDisplayTimerTask extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
// display toast
Toast.makeText(getApplicationContext(), getDateTime(),
Toast.LENGTH_SHORT).show();
}
});
}
private String getDateTime() {
// get date time in custom format
SimpleDateFormat sdf = new SimpleDateFormat("[yyyy/MM/dd - HH:mm:ss]");
return sdf.format(new Date());
}
}
Andoid Manfest.xml
<?xml version="1.0" encoding="utf-8"?>
<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">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".TimeService"
android:enabled="true"
android:exported="true"></service>
</application>
MainActivity.java is :
package com.example.shubhamrajput.myapplication;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, TimeService.class));
}
}
I tested this app on my phone ,but it is not working in the background when I terminate it from app tray, I want to make it run forever until user stops it forcefully from settings, How do I change this code? Please provide detailed explanation and also provide modified code ,so that I can understand it.How can I make it a foreground service?
You should not be running service in the background always because of it will use CPU and memory all the time.You will end up having very poor battery backup
You can use Job Scheduler for API level greater than 21 or Firebase Job Dispatcher for below API level 21.Using this, you can fire recurring job in an efficient manner.
You can run the service on different process so it will run always irrespective of the application
In manifest file
<service
android:name=".TimeService"
android:enabled="true"
android:process=":my_process">
</service>
You can also use START_STICKY
or you can follow this Answer for more details.
I am creating an android app and when I go to debug it on my samsung galaxy the Splash activity loads first,as it should, but after that the app crashes/stops right after doing the "Splash" activity. It doesn't go to the "MainActivity" activity after the thread sleeps for 5 seconds. Does anyone know what might be causing the problem? Plus after I tried debugging the app and loaded it onto my phone the app isn't even showing up. I am using Eclipse by the way. It shows the app in my application manager on my phone but it doesn't show the icon in my app screen.
Here is my Splash.java:
package com.example.mihirsandroidapp;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class Splash extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread timer = new Thread(){
public void run(){
try{
sleep(5000);
} catch (InterruptedException e){
e.printStackTrace();
}finally{
Intent openMainActivity = new Intent("com.example.mihirandroidsapp.MAINACTIVITY");
startActivity(openMainActivity);
}
}
};
timer.start();
}
#Override
protected void onPause() {
super.onPause();
finish();
}
}
Here is my Manifest:
<?xml version="1.0" encoding="utf-8"?>
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:debuggable="true"
android:allowBackup="true"
android:icon="#drawable/cartooncat"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".Splash"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.mihirsandroidapp.SPLASH" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.mihirsandroidapp.MAINACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
And here is my main activity which should start after the splash screen:
package com.example.mihirsandroidapp;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
int counter;
Button add, sub;
TextView display;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
counter = 0;
add = (Button) findViewById(R.id.bAdd);
sub = (Button) findViewById(R.id.bSub);
display = (TextView) findViewById(R.id.tvDisplay);
add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
counter += 1;
display.setText("Total is " + counter);
}
});
sub.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
counter -= 1;
display.setText("Total is " + counter);
}
});
}
}
Oh.. Where do I start.. Let's go through all of the issues:
1) Fix your manifest. Definitely not the right way to declare your activities. Here is what it should look like:
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:debuggable="true"
android:allowBackup="true"
android:icon="#drawable/cartooncat"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".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=".MainActivity"
android:label="#string/app_name" >
</activity>
</application>
2) Now let's fix the way you start your activity:
Intent openMainActivity = new Intent(Splash.this, MainActivity.class);
3) Don't call finish() in onPause() - you break native activity lifecycle flow. Call finish() right after you start new activity:
Intent openMainActivity = new Intent(Splash.this, MainActivity.class);
startActivity(openMainActivity);
finish();
4) Instead of creating separate thread, just a create a Handler and post Runnable there with 5 seconds delay:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//this will be called after 5 seconds delay
}
}, 5000);
Here is entire file put together:
public class Splash extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
Intent openMainActivity = new Intent(Splash.this, MainActivity.class);
startActivity(openMainActivity);
finish();
}
}, 5000);
}
If it doesn't help - we definitely need to look at logcat output...
A simple way to achieve this if one is ready to compromise on drawing performance is to define custom theme with splash image that one wants to use as window background and use this custom theme as application theme
styles.xml
<resources>
<style name="CustomTheme" parent="android:Theme">
<item name="android:windowBackground">#drawable/background_image</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
AndroidManifest.xml
<application
android:debuggable="true"
android:icon="#drawable/icon"
android:theme="#style/CustomTheme"
android:label="#string/app_name">
...
</application>
This would use the #drawable/background_image as the window.background. As a result if the activities has transparent background then #drawable/background_image will be visible as activities background. One can avoid this by setting appropriate color or drawable in onCreate of every activity programatically as
public void onCreate(){
super.onCreate(savedInstanceState);
setContentView(R.layout.layoutResID);
activity.getWindow().setBackgroundDrawableResource(R.color.window_bg);
}
Check this for more information
All what you need for a splash screen
SplashActivity.java
public class SplashActivity extends AppCompatActivity {
private final int SPLASH_DISPLAY_DURATION = 1000;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
Intent mainIntent = new Intent(SplashActivity.this,MainActivity.class);
SplashActivity.this.startActivity(mainIntent);
SplashActivity.this.finish();
}
}, SPLASH_DISPLAY_DURATION);
}}
In drawables create this bg_splash.xml
<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#color/app_color"/>
<item>
<bitmap
android:gravity="center"
android:src="#drawable/ic_in_app_logo_big"/>
</item></layer-list>
In styles.xml create a custom theme
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">#drawable/bg_splash</item>
</style>
and finally in AndroidManifest.xml specify the theme to your activity
<activity
android:name=".activities.SplashActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Cheers.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread th = new Thread(new Runnable() { /*create a new thread */
#Override
public void run() { /*
* The purpose of this thread is to
* navigate from one class to another
* after some time
*/
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
/*
* We are creating this new thread because we don’t
* want our main thread to stop working for that
* time as our android stop working and some time
* application will crashes
*/
e.printStackTrace();
}
finally {
Intent i = new Intent(MainActivity.this,
Splash_Class.class);
startActivity(i);
finish();
}
}
});
th.start(); // start the thread
}
http://www.codehubb.com/android_splash_screen
I have added splash screen by using following code:
public class SplashActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_layout);
initConstatnts();// method for intilizing any constants
new Thread(new Runnable() {
#Override
public void run() {
if (!isFinishing()) // checking activity is finishing or not
{
try {
Thread.sleep(3000);//delay
Intent i = new Intent(getBaseContext(),
HomeActivity.class);
startActivity(i);
finish();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}).start();
}
private void initConstatnts() {
}
}
Flow the below steps to Create your own splash screen
Create Activity1 and XML file
Design the XML file and put the welcome message
Crete Activity2 and XML file.
Start the Activity1
Start a Thread in Activity1 and sleep for 5 seconds
Start Activity2 from the Thread
There is nothing called readymade splash screen in Android . we can achieve that using above steps.
In a single line, start Activity1 wait for 5 sec then start Activity2.
So user will feel that first screen is splash screen.
You can download the complete code from below link
http://javaant.com/splash-screen-android/#.VwzHz5N96Hs
i have faced the same problem.... i think you code is perfect for the app
u just try with this in the Intent Creation in your splash activity class
Intent openMainActivity = new Intent("android.intent.action.MAIN");//MAIN is the that u want to start
//next after the current Activity
I want to start a game from a menu. In Eclipse, I have 2 projects, one with the menu, the other the actual game. Both using SimpleBaseGameActivity as their base. The examples on the net do something like below. In particular, it creates an intent and starts an activity with that intent. The code below gives a NoClassDefFoundError on MyGame.class. This is no surprise since MyGame.class doesn't exist, but rather MyGame.apk does. How do I do this?
public boolean onMenuItemClicked(final MenuScene pMenuScene,
final IMenuItem pMenuItem,
final float pMenuItemLocalX,
final float pMenuItemLocalY) {
switch(pMenuItem.getID()) {
case MENU_PLAY:
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Intent intent = new Intent(getApplication(), MyGame.class);
startActivity(intent);
finish();
}
});
return true;
}
}
----- edit
I've got it working, with everything in one project, in that when the menu item is clicked on, then the game starts. However, when the 'back arrow' is clicked, it doesn't return to the menu, but rather to the operating system. The activity definitions in the manifest file are below. Does this look correct?
<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>
<activity
android:name="com.mygame.MyGame"
android:label="#string/mygame_activity"
android:parentActivityName="com.menu.MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.menu.MainActivity" />
</activity>
I added this to MyGame, but it doesn't get called:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
}
--- edit
I needed to remove this line:
MainActivity.this.finish();
first insert in the Manifest in the tags
<application>...</application>
this tag:
<activity
android:name=".MyGame"
android:label="MygameName" >
</activity>
and change in your code:
public boolean onMenuItemClicked(final MenuScene pMenuScene,
final IMenuItem pMenuItem,
final float pMenuItemLocalX,
final float pMenuItemLocalY) {
switch(pMenuItem.getID()) {
case MENU_PLAY:
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
Intent intent = new Intent(MainActivity.this, MyGame.class);
startActivity(intent);
MainActivity.this.finish();
}
});
return true;
MyGame have to be an activity and it must be mentioned in Android.manifest as an activity.
http://developer.android.com/training/basics/firstapp/starting-activity.html
Please Remove call to function "finish()" and then it will take you back to the parent activity.