Android - activity launched at startup + moveTaskToBack = killed - android

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

Related

Why service is killed in Asus tablets and works fine in samsung

I create a service to works in the background when my app is killed by the user and it works fine in Samsung tablet but on my Asus tablet is killed when I close my app!
but google services are works in my Asus tablet this is my code:
public class InternetService extends Service {
public static final int notify = 1000; //interval between two services(Here Service run every 5 Minute)
private Handler mHandler = new Handler(); //run on another Thread to avoid crash
private Timer mTimer = null; //timer handling
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
if (mTimer != null) // Cancel if already existed
mTimer.cancel();
else
mTimer = new Timer(); //recreate new
mTimer.scheduleAtFixedRate(new TimeDisplay(), 0, notify); //Schedule task
}
#Override
public void onDestroy() {
super.onDestroy();
mTimer.cancel(); //For Cancel Timer
Toast.makeText(this, "Service is Destroyed", Toast.LENGTH_SHORT).show();
}
//class TimeDisplay for handling task
class TimeDisplay extends TimerTask {
#Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
#Override
public void run() {
G.AppsList.clear();
populateDataFromServer();
Log.i("SERVICES", "SERVICE");
}
});
}
}
}
and this is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="androidmarket.ehsan.com.androidmarket">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission
android:name="android.permission.INSTALL_PACKAGES"
tools:ignore="ProtectedPermissions"/>
<application
android:name="project.utils.G"
android:allowBackup="true"
android:icon="#mipmap/logo"
android:label="#string/app_name"
android:supportsRtl="false"
android:theme="#style/Theme.AppCompat.NoActionBar">
<activity android:name="project.activity.ActivityStartup">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity android:name="project.activity.ActivityApplicationsList">
</activity>
<activity android:name="project.activity.ActivityApplicationDetail">
</activity>
<activity android:name="project.activity.ActivityInternet">
</activity>
<service android:name="project.service.InternetService" android:enabled="true" android:exported="true"></service>
</application>
</manifest>
This is very important for me,Thank you for your answers.
I have a Asus Zenfone Max 3 as my personal phone and i also use it when i'm developing apps. This pre-installed Mobile Manager app by Asus is actually stopping whatever is running in the background. Just disable this in the app's settings. Settings Screenshot

Android Application with only Service

I need to make an application "x" that has only service in it(no activity and no broadcast receiver) which can be called from activity of another application "y". I need to ask is it possible because on clicking a button in application "y" service of application "x" must be called but it is not happening. I don't see service running in the android phone. So is it even possible to have a single service in a project and nothing else?
application "y" code
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button button = (Button) findViewById(R.id.button);
if(button!=null){
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
startService(new Intent("com.example.sonali.serviceonly.OnlyService"));
Toast.makeText(getApplicationContext(), "text", Toast.LENGTH_SHORT).show();// Perform action on click
}
});
}
}
}
application "x" manifest file
``
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<service android:name="com.example.sonali.serviceonly.OnlyService" android:exported="true" android:enabled="true">
<intent-filter>
<action android:name="com.example.sonali.serviceonly.OnlyService"/>
</intent-filter>
</service>
</application>
``
Yes it's possible.
You have to start service like this.
Intent intentService = new Intent();
intentService.setComponent(new ComponentName("com.example.app", "com.example.app.servicename"));
startService(intentService);
You must have to set this exported as true in menifest file.
android:exported="true"
I have tested it's working fine on 4.4.4 Version.
Try Explicit Intent for version 5+
ComponentName n = new ComponentName("com.xxx.yyy", "com.xxx.yyy.OnlyService");
Intent a = new Intent();
a.setComponent(n);
a.setAction(Intent.ACTION_MAIN);
a.addCategory(Intent.CATEGORY_LAUNCHER);
a.putExtra("destinationAddress","5554");
ComponentName c = getApplication().startService(a);
if(c==null)
{
Log.e("error", "failed to start with " + a);
}

Android KitKat not showing Toast once the App goes to background

I am running a service from my Android test app, which needs to show toast from counter value which is continuously increasing in a service.
Its starting well, and showing the toast. But, once I press back/home button to keep the app in background, the toast stops showing. When I again bring the app to foreground, again the toast started visible.
This problem happens sin Kitkat. But in JellyBeans and below, its working fine.
Here is my manifest file.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.rtrgroup.mysms"
android:installLocation="internalOnly">
<uses-sdk android:minSdkVersion="9"
android:targetSdkVersion="19"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true">
<activity
android:name="com.rtrgroup.mysms.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>
<service android:name="com.rtrgroup.mysms.MyService"
android:enabled="true"
android:exported="true">
</service>
</application>
</manifest>
Here is my MainActivity.java file.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public void onStart() {
Intent serviceIntent = new Intent(this, MyService.class);
startService(serviceIntent);
}
}
Here is my service code, MyService.java:
package com.rtrgroup.mysms;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.*;
import android.widget.Toast;
public class MyService extends Service {
Handler handler;
int count = 0;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handler = new Handler();
handler.postDelayed(test, 1000);
return START_NOT_STICKY;
}
Runnable test = new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(), "TOAST count = " + String.valueOf(count), Toast.LENGTH_SHORT).show();
count++;
handler.postDelayed(test, 5000);
}
};
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
So, how to make toast visible always, even the app is in background and the service is running? Please explain.
if you want to detect when the user put your app in background , override this method
#Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
switch (level) {
case ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN:
// do your magic here
break;
}
}
check the documentation http://developer.android.com/reference/android/content/ComponentCallbacks2.html#TRIM_MEMORY_UI_HIDDEN
also you can start your service in "foreground" mode for this check
Show notification from background started service
or you can show a notification instead a toast.

Using android beacon library to get the application running in the background

I'm using the android beacon library to get the application running in the background to let the application scan for ibeacons even the user goes to the task switcher and swipes an app off the screen.
the beacon library is here :
https://altbeacon.github.io/android-beacon-library/index.html
the code i used:
MonitoringActivity for searching for ibeacons :
public MonitoringActivity() {
}
private RegionBootstrap regionBootstrap;
private BeaconManager beaconManager;
private BackgroundPowerSaver backgroundPowerSaver;
#Override
public void onCreate() {
super.onCreate();
Log.d("Beacon app", "App started up");
// wake up the app when any beacon is seen (you can specify specific id filers in the parameters below)
Region region = new Region("UniqueId", null, null, null);
regionBootstrap = new RegionBootstrap(this, region);
//Changing between scan periode
backgroundPowerSaver= new BackgroundPowerSaver(this);
//beaconManager.setBackgroundScanPeriod(5000l);
//beaconManager.setBackgroundBetweenScanPeriod(10000l);
}
#Override
public void didDetermineStateForRegion(int arg0, Region arg1) {
// TODO Auto-generated method stub
}
#Override
public void didEnterRegion(Region arg0) {
// TODO Auto-generated method stub
Log.v("Beacon entry ", "beacon entred to range");
Intent intent = new Intent(MonitoringActivity.this, MonitoringActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
RangActivityfor result:
public class RangActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rang);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.rang, menu);
return true;
}
and the code of the manifest:
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<application
android:name=".MonitoringActivity"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:persistent="true"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name"
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=".MonitoringActivity"
android:label="#string/title_activity_monitoring" >
</activity>
<activity
android:name=".RangActivity"
android:label="#string/title_activity_rang"
>
</activity>
</application>
the problem that i have that the application works only whene i press tha back button until it exit or the home button but if i goes to the task switcher and swipes the app off the screen it's not running anymore . How can I fix this ?
Killing an app from the task switcher will shut down the app so it is not running, preventing it from detecting beacons (at least for awhile). The library is designed to re-launch itself on the next power connect/disconnect event. So for testing purposes, simply connect your phone to a charger or to your computer's USB port.
You can read more about this limitation here: http://altbeacon.github.io/android-beacon-library/resume-after-terminate.html
EDIT: On some devices, folks have reported that the ACTION_POWER_CONNECTED event does not work after killing apps with the task switcher. You can see a discussion of the issue here: https://github.com/AltBeacon/android-beacon-library/issues/44
I have created a test app here to see if this issue applies to your specific device. If you can install that test app on your device and follow the instructions, you should know if you device is affected. Please report back your results!

I am having issue with my splash screen as am not getting into the next activity

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.

Categories

Resources