When I run my app in an emulator and kill the process, my service gets started and runs in the background (Toast: "Service Called") BUT it does not get called at all on a real device and no logcat runs because the broadcast receiver or my service does not get called:
MainFest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Service -->
<service android:name=".MyService">
<intent-filter>
<action android:name="com.mypackage.myapp.MyService" />
</intent-filter>
</service>
<receiver
android:name=".BootReceiver"
android:enabled="true"
android:exported="true"
android:label="BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<!-- Service -->
MainActivity:
AsyncTask.execute(new Runnable() {
#Override
public void run() {
//TODO your background code
Intent i = new Intent(MainActivity.this, PushNotification.class);
startActivity(i);
}
});
PushNotification.class:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Context context = this;
if (!isMyServiceRunning()){
Intent serviceIntent = new Intent(context, MyService.class);
context.startService(serviceIntent);
finish();
}
else
{
finish();
}
}
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (MyService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
BootReceiver:
#Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent serviceIntent = new Intent(context, MyService.class);
context.startService(serviceIntent);
}
}
}
MyService:
public class MyService extends Service {
Handler handler;
#Override
public int onStartCommand(Intent intent, int flags, int startId){
// START YOUR TASKS
Toast.makeText(MyService.this, "Service Called", Toast.LENGTH_SHORT).show();
Context context = this;
Intent in = new Intent(context, FragmentMain.class);
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
in.putExtra("valuerunInBG", "1");
context.startActivity(in);;
//loop();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
// STOP YOUR TASKS
super.onDestroy();
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
Modify your manifest as given below
<receiver
android:name=".BootReceiver"
android:enabled="true"
android:exported="true"
android:label="BootReceiver">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I made a small change in it just given the priority by which it will start as early as possible
also change the code given below
#Override
public int onStartCommand(Intent intent, int flags, int startId){
// START YOUR TASKS
Toast.makeText(MyService.this, "Service Called", Toast.LENGTH_SHORT).show();
Context context = this;
Intent in = new Intent(context, FragmentMain.class);
in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
in.putExtra("valuerunInBG", "1");
context.startActivity(in);;
//loop();
return START_STICKY; //THIS WILL RESTART YOUR SERVICE IF IT GETS STOPPED BY ANDROID OS DUE TO LOW MEMORY
}
android.intent.action.BOOT_COMPLETED Takes time after your device starts, try waiting 3-4 minutes
Start your service again in your service class's onDestroy() method. This way when your application will be closed, then onDestroy() will be called and that will start your service again.
Some time Toast does not work inside of Service so please use Log to know whether your code is running or not.
Related
I'm writing a service that sends a message to a remote server every interval.
I'm using Android 4.4 (KitKat).
The service also has an activity that allows some minimal configuration such as the remote server's URL.
I managed to make the service work, start from boot and restart if killed, but I have some issue with the latter.
If I open the app for the first time, all works well. Killing the app results in a broadcast intent and the service revives (without the activity of course). Now, if I open the app a second time (after the kill and revive), the next time I kill the app, the service does not restart.
My broadcast receiver:
public class dynDNSBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "dynDNSBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"Broadcast received, starting dynDNS service");
context.startService(new Intent(context, dyndns.class));
}
}
My service:
public class dyndns extends Service {
private static String TAG = "dynDNS service";
public SharedPreferences myPrefs;
private Handler mainHandler;
private Timer timer;
#Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "Service onBind");
return null;
}
#Override
public void onCreate() {
super.onCreate();
startForeground(1, new Notification());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "dynDNS service started");
mainHandler = new Handler(getApplicationContext().getMainLooper());
timer = new Timer();
timer.schedule(new MyTimerTask(), 10000, 10000);
return START_STICKY;
}
#Override
public void onDestroy() {
timer.cancel();
super.onDestroy();
Log.d(TAG, "dynDNS service destroyed");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("restartService");
broadcastIntent.setClass(this, dynDNSBroadcastReceiver.class);
this.sendBroadcast(broadcastIntent);
}
Relevant code from my activity:
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
assert manager != null;
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
Log.d(TAG, serviceClass.getName());
Log.d (TAG, "Service status: Running");
return true;
}
}
Log.d (TAG, "Service status: Not running");
return false;
}
#Override
protected void onDestroy() {
stopService(mServiceIntent);
super.onDestroy();
}
Relevant code form the manifest:
<service
android:name="com.dyndns.dyndns"
android:enabled="true" android:process=":externalProcess">
<intent-filter>
<action android:name="com.dyndns.dyndns" />
</intent-filter>
</service>
<receiver android:name="dynDNSBroadcastReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="restartService"/>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
i want when boot run app server allow for receive message any time
without showing application
this code problem when boot show Notification twice only
but i want receive message any time
Is this "android:exported" important, What used
code AndroidManifest
<service
android:name=".appService"
android:exported="true"
android:enabled="true">
</service>
<receiver
android:name=".ServiceStarterBoot"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver>
code BroadcastReceiver
public class ServiceStarterBoot extends BroadcastReceiver {
private Context context ;
#Override
public void onReceive(Context context1, Intent intent) {
this.context = context1;
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Intent serviceLauncher = new Intent(context, appService.class);
context.startService(serviceLauncher);
}}
code Service
public class appService extends Service {
#Override
public void onCreate() {
super.onCreate();
lood();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
//return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "onStartCommand", Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent, flags, startId);
}
private void lood(){
SystemClock.sleep(3000);
Runnable runnable = new Runnable() {
public void run() {
boolean p= true ;
while(p) {
SystemClock.sleep(5000);
showNotification();
}
}
};
Thread mythread = new Thread(runnable);
mythread.start();
}
please help
thanks
you have to make your service sticky:
Service.START_STICKY
then it is infinite and restarts itself when killed by OS for any reason.
It even starts itself when booting OS and app is NOT opened by user.
Best regards.
pseudo code:
onStartCommand(..){
...
//e.g. wifilisterner
Wifilistener WF = new Wifilistener(Interface yourInterfaceCallBackMethod);
}
something like this.
I'm using android(version 4.1.1) MeLE box(SmartTv) for developing one application, i need to start up my application when device Boot Time is completed but my device not catch up the BOOT_COMPLETED Action. If i'm use that same application in mobiles or emulator the Boot_Completion action were caught by Broadcast_receiver.
if anyone known about this issue help me thanks in advance....
here is my code...
manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".BootCompletedReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<service android:name="NotifyingDailyService" >
</service>
BootCompletedReceiver class:
public class BootCompletedReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
// TODO Auto-generated method stub
Log.w("boot_broadcast_poc", "starting service...");
context.startService(new Intent(context, NotifyingDailyService.class));
}
}
Service class:
public class NotifyingDailyService extends Service {
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent pIntent, int flags, int startId) {
// TODO Auto-generated method stub
Toast.makeText(this, "NotifyingDailyService", Toast.LENGTH_LONG).show();
Log.i("com.example.bootbroadcastpoc","NotifyingDailyService");
return super.onStartCommand(intent, flags, startId);
}
}
One thing I noticed is you don't have the category set for your receiver in your Manifest. The following works for me in my App.
<receiver android:name="us.nineworlds.serenity.StartupBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Then in my StartupBroadcastReceiver, i have the following
public void onReceive(Context context, Intent intent) {
if (intent.getAction() == null) {
return;
}
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean startupAfterBoot = prefs.getBoolean("serenity_boot_startup", false);
if (startupAfterBoot) {
Intent i = new Intent(context, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
}
This will start the MainActivity class once bootup has been completed.
Link to the project code is here: https://github.com/NineWorlds/serenity-android/blob/master/serenity-app/src/main/java/us/nineworlds/serenity/StartupBroadcastReceiver.java
I have tried this
Trying to start a service on boot on Android
Also I have checked with http://blog.vogella.com/2011/12/11/automatically-starting-services-in-android-after-booting/
yet my app wont restart on Phone startup. Here's the code.
AndroidManifest.xml
<service android:name=".MyService">
</service>
<receiver android:name=".Autostart"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
MyService
public class MyService extends Service implements LocationListener {
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
public class LocalBinder extends Binder {
MyService getService() {
return MyService.this;
}
}
#Override
public void onCreate() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
// We want this service to continue running until it is explicitly
// stopped, so return sticky.
return START_STICKY;
}
#Override
public void onDestroy() {
// Cancel the persistent notification.
this.stopSelf();
// Tell the user we stopped.
}
MainActivity
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(getBaseContext(), MyService.class));
Am I going wrong anywhere?
Edit:
public void onReceive(Context arg0, Intent arg1)
{
Intent intent = new Intent(arg0,MyService.class);
arg0.startService(intent);
Log.i("Autostart", "started");
}
This is my BroadcastReceiver.
Yet no results.
try register BroadcastReceiver for ACTION_BOOT_COMPLETED. The you can recieve startup broadcast.
public class BootBroadCast extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent service=new Intent(context, MyService.class);
context.startService(service);
}
}
second you need add this in AndroidManifest.xml
<receiver android:name=".BootBroadCast" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" >
</action>
</intent-filter>
</receiver>
I have followed the article at vogella and was able to get my service started at Boot.
First of all, you should have a BroadcastReceiver for the event android.intent.action.BOOT_COMPLETED. Just follow the steps from the blog. It seems you have started the service on your app's 'onCreate'. This will get invoked only if the user starts your app.
When the system boots up, your receiver class's onReceive() method will be invoked. Here is where you should start your activity as below.
public class BootReceiever extebds BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, YourService.class);
context.startService(service);
}
}
From the research that I have done, it is better to start your service after a short delay as many applications / services may start at boot, so chances of low memory are more. I started my service after a small delay.
i try translate a word via Fora Dictionary Api. Here more about ForaApi. Here is my code:
String query = "com.ngc.fora.action.QUERY";
Intent foraIntent = new Intent(query);
foraIntent.putExtra("QUERY_ID", new Long("1"));
foraIntent.putExtra("QUERY", lword);
foraIntent.putExtra("MAX_RESULTS", 2);
foraIntent.putExtra("AS_PAGE", true);
foraIntent.putExtra("CALLBACK_ACTION", "com.myAPP.ServiceForFora.TRANSLATE");
foraIntent.putExtra("CALLBACK_PACKAGE", "com.myAPP");
foraIntent.putExtra("CALLBACK_CLASS", ".ServiceForFora");
startService(foraIntent);
But when Fora Dictionary try send intent to my service(ServiceForFora) i get this:
05-07 06:20:40.440: W/ActivityManager(52): Unable to start service Intent { act=com.myAPP.ServiceForFora.TRANSLATE cmp=com.myAPP/.ServiceForFora (has extras) }: not found
Here's my service:
epublic class ServiceForFora extends Service{
#Override
public IBinder onBind(Intent intent) {
Toast.makeText(this, "onBind", Toast.LENGTH_LONG).show();
return null;
}
#Override
public void onCreate() {
//code to execute when the service is first created
Toast.makeText(this, "onCreate", Toast.LENGTH_LONG).show();
super.onCreate();
}
#Override
public void onDestroy() {
//code to execute when the service is shutting down
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//code to execute when the service is starting up
super.onStart(intent, startId);
return Service.START_STICKY;
}
}
and Manifest notation:
<application><service android:name="com.myAPP.ServiceForFora"
android:exported="true">
<intent-filter>
<action android:name="com.myAPP.ServiceForFora.TRANSLATE"/>
</intent-filter>
</service>
.............................
</application>
Thank's
try to remove this code :
foraIntent.putExtra("CALLBACK_PACKAGE", "com.myAPP");
foraIntent.putExtra("CALLBACK_CLASS", ".ServiceForFora");
and add more parameters to service description :
android:enabled="true" android:exported="true" android:stateNotNeeded="true" android:excludeFromRecents="true" android:configChanges="keyboard|keyboardHidden|orientation"