So I'm writing an app which, when plugged in, is supposed to launch an activity telling the user to unplug the device from a computer. In this class, I have a timer which periodically checks to see if it is plugged in. The code in the timer works other than when I try to start another activity when the user disconnects the cord. I am not sure if the issue lies in the class with the timer, or the Manifest, although the activity which I am trying to launch when disconnect was working earlier and I haven't made any changes to it.
Here is the code for the StateCheck class (tests whether its plugged in by checking the state of the SD card):
public class StateCheck extends Activity {
TextView stateCheck, unmountedImage, tester;
Timer timer;
int i = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.state_check);
stateCheck = (TextView) findViewById(R.id.tvStateCheck);
unmountedImage = (TextView) findViewById(R.id.tvUnmountedImage);
tester = (TextView) findViewById(R.id.tvTester);
//Intent openStartingPoint = new Intent("com.flannigan.MUSERCISEACTIVITY");
//startActivity(openStartingPoint);
MyTimerTask myTask = new MyTimerTask();
timer = new Timer();
timer.schedule(myTask, 1000);
}
class MyTimerTask extends TimerTask {
public void run() {
String state = Environment.getExternalStorageState();
i++;
if (Environment.MEDIA_MOUNTED.equals(state)) {
unmountedImage.getHandler().post(new Runnable() {
public void run() {
unmountedImage.setVisibility(View.INVISIBLE);
}
});
stateCheck.getHandler().post(new Runnable() {
public void run() {
stateCheck.setText("SD card is mounted!\nLoading...");
}
});
Intent openStartingPoint = new Intent("com.flannigan.MUSERCISEACTIVITY");
startActivity(openStartingPoint);
} else {
MyTimerTask myTask = new MyTimerTask();
timer = new Timer();
timer.schedule(myTask, 1000);
tester.getHandler().post(new Runnable() {
public void run() {
tester.setText(""+i);
}
});
}
}
}
}
Manifest:
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".Splash"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
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=".StateCheck"
android:label="Musercise"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="com.flannigan.STATECHECK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".MuserciseActivity"
android:label="Musercise"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="com.flannigan.MUSERCISEACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
Use runOnUiThread for Accessing UI elements from TimerTask Thread as:
StateCheck.this.runOnUiThread(new Runnable() {
public void run(){
// start next Activity here
// Access UI element here
}
});
and for Starting Activity Change your Intent as:
Intent intent=new (StateCheck.this,MuserciseActivity.class);
startActivity(intent);
Related
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
I work on app that acts like phone guard and should run on startup (or when launched by user) and keep running until user manually won't finish it. When application started (after device boot completed) i use moveTaskToBack for hiding it in background. After about ~12 seconds my application stop working (killed by system i suspect) without any notice, no logs at all (but still stay in history stack). Checked by app timer with log, and also when i start programm by clicking icon - new instance runs. As i noticed, if i execute moveTaskToBack from Handler which delayed even by 500ms - app won't be killed! Tested on galaxy tab 2 (4.1.2) and on alcatel one touch (2.3.6). Here the sample code for reproduce:
MainActivity
public class MainActivity extends Activity
{
Timer timerCheck;
int ticks = 0;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerCheck = new Timer();
timerCheck.schedule(taskCheck, 0, 1000);
if (IsStartup())
moveTaskToBack(true);
// if (IsStartup())
// {
// new Handler().postDelayed(new Runnable()
// {
// #Override
// public void run()
// {
// moveTaskToBack(true);
// }
// }, 1000);
// }
}
TimerTask taskCheck = new TimerTask()
{
#Override
public void run()
{
runOnUiThread(timerTickCheck);
}
private Runnable timerTickCheck = new Runnable()
{
public void run()
{
Log.e("testapp", "alive for " + ++ticks * 1000 + " ms");
}
};
};
private boolean IsStartup()
{
return getIntent().hasExtra("startup");
}
}
StartupReceiver
public class StartupReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context c, Intent i)
{
Intent in = new Intent();
in.setClassName("com.example.startuptest",
"com.example.startuptest.MainActivity");
in.putExtra("startup", "1");
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
c.startActivity(in);
}
}
manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.startuptest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name="com.example.startuptest.StartupReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity
android:name="com.example.startuptest.MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
So there is my questions - why android system has such behavior? Anyway to instantly hide app on startup?
The android OS can kill any background process if it needs it's resources. In your case, the system boot is a highly resource-consuming period, and activities in background have quite low priority when it comes to what to keep.
Anyway, if you want something to run in background for a prolonged time, I suggest you to check out services:
http://developer.android.com/guide/components/services.html
Manifest File is
android:icon="#drawable/app_logo"
android:label="#string/app_name" android:debuggable="false">
<activity
android:name=".SplashActivity"
android:label="#string/title_activity_main"
android:launchMode="standard"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Splash screen code is
public class SplashActivity extends MusicActivity {
private final int SPLASH_DISPLAY_LENGTH = 7000;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
/* Create an Intent that will start the Menu-Activity. */
Intent mainIntent = new Intent(SplashActivity.this,MenuActivity.class);
startActivity(mainIntent);
}
}, SPLASH_DISPLAY_LENGTH);
}
When you leave the app by using the 'home' key, I fire this from the activity that is running, (it's an audio player and this is the primary activity that you can exit from)
#Override
protected void onPause() {
super.onPause();
if (mp != null){
mp.pause();
if (isFinishing()){
mp.pause();
}
}
}
When I re-enter the app is just a few minutes things are perfect, the audio resumes where it was and so on -
However - if I walk away from the device for say an hour or so and then return and launch the app from the launcher, it freezes on the 'splash screen', no error message,no force close,it just sits there.
What should I be checking for?
Thanks
This is an example of splash screen but facing difficulty with it as I couldn't view my MainActivity class, couldn't be able to recognize the issue.Tried in manifest file by changing the action and the category name as well but could not be able to resolve to it.
Basically changed my Intent intent = new Intent(); as well but still the same goes on.
public class SplashActivity extends Activity
{
MediaPlayer player;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
player = MediaPlayer.create(SplashActivity.this, R.raw.splash);
player.start();
Thread timer = new Thread()
{
#Override
public void run()
{
try
{
sleep(4000);
}catch(InterruptedException e)
{
e.printStackTrace();
}
finish();
Intent intent = new Intent();
intent.setClass(SplashActivity.this, MainActivity.class);
startActivity(intent);
stop();
}
};
timer.start();
}
#Override
protected void onPause()
{
super.onPause();
player.release();
finish();
}
}
====>And here is my manifest file --
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mainsplashcreen"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="10" />
<application
android:icon="#drawable/android_splash"
android:label="#string/app_name" >
<activity
android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</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>
</application>
</manifest>
I would guess, that your problem is, that you finish your activity before you start the new one. If you call finish() on your activity, it will be destroyed, and so the startActivity() won't be called anymore (or if it will be called, it won't get a valid context anymore). So try to move the finish() method, at the end of your run method, that should solve the problem.
Another Very Short,Simple and Effective way of Implementing Flash Screen is as below:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Handler handler=new Handler();
Runnable gotoMain=new Runnable() {
public void run()
{
startActivity(new Intent(SplashActivity.this, MainActivity.class));
finish();
}
};
handler.postDelayed(gotoMain, 4000);
}
You just Replace you OnCreate Method with this one.
There are a few things which you should take care of:
1. The usage of stop() and the place it is being used are not encouraged. Besides being deprecated, it will also give you UnsupportedOperationExcecption.
2. Is your MediaPlayer being initialized correctly without any errors? Check the logs.
3. What is the reason you are using finish() in onPause() method? It is not recommended.
4. You are assigning MAIN action to both your activities. While it is allowed, it should be for a specific reason.
However, all these things should not avoid your application to go to the main activity. There may be the reasons with your main activity code.
I have made a splash screen with an Activity. I followed following example http://www.anddev.org/viewtopic.php?t=815 and it works perfectly when installed. But that's where my problem starts. It only shows after an install. So When I kill my app, the Activity isn't loaded anymore, it directly loads my second Activity. I think it's a little weird, because I set the intent-filter in my manifestfile on the splash screen.
Anyone knows how to solve this problem?
This is my manifestfile:
<application android:icon="#drawable/icon" android:label="#string/app_name"
android:theme="#style/MyLightTheme.NoShadow" android:debuggable="true" android:name="android.app.Application" >
<uses-library android:name="com.google.android.maps" />
<activity android:name=".MainActivity" android:label="#string/app_name"></activity>
<activity android:name="FindJob" android:label="#string/FindJobTitel"></activity>
<activity android:name="JobDetails" android:label="#string/MaatTitel" ></activity>
.
.
.
<activity android:name="Splash" android:configChanges="orientation" android:label="#string/Splash">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter></activity>
</application>
Splashscreencode:
private final int SPLASH_DISPLAY_LENGHT = 5000;
//private Drawable drawable;
private ProgressBar mProgress;
private int mProgressStatus = 0;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.splash);
mProgress = (ProgressBar) findViewById(R.id.progressBar1);
}
public void onStart(){
super.onStart();
//Log.i("START", "In on start");
Thread splashThread = new Thread() {
#Override
public void run() {
try {
int waited = 0;
while (mProgressStatus < 100) {
sleep(80);
//waited += 200;
mProgressStatus += 4;
mProgress.setProgress(mProgressStatus);
}
} catch (InterruptedException e) {
// do nothing
} finally {
finish();
Intent i = new Intent(Splash.this, MainActivity.class);
startActivity(i);
}
}
};
splashThread.start();
}
UPDATE: placing android:noHistory="true" in the mainActivity in ManifestFile solves the problem. HOWEVER. Each time I leave the app, it restarts all of it (splash screen, mainactivity and not last activity loaded). But it's better then before.