My Service is not working on Android, why? - java

It's code here:
public class MyServeice extends Service
{
private Timer pushTimer;
private final int NOTEF_ID = 1234;
NotificationManager manager;
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public void onCreate()
{
Log.i("MyActivity", "1");
//pushTimer = new Timer();
manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
}
#Override
public void onDestroy()
{
Log.i("MyActivity", "2");
//pushTimer.cancel();
}
#Override
public void onStart(Intent intent, int startid)
{
Log.i("MyActivity", "3");
//pushTimer.schedule(new TimerTask()
//{
// #Override
// public void run()
// {
Notification not = new Notification(R.drawable.ic_launcher, "Custom notification", System.currentTimeMillis());
PendingIntent notIntent = PendingIntent.getActivity(this , 0, new Intent(this, MainActivity.class), 0);
not.setLatestEventInfo(this, "Title", "Text", notIntent);
manager.notify(NOTEF_ID, not);
manager.cancel(NOTEF_ID);
// }
//}, 0L, 60L * 1000);
}
}
I try to start it from my MainActivity activity class (before I thought that problem is in timer, but now I comment it).
Starting code here:
startService(new Intent(this, MyServeice.class));
Log from Service class is not shown, so I decided that Service is not started at all. Application doesn't crash and started normaly. Can you check my code?

You made a mistake in MyServeice Class
You use
#Override
public void onStart(Intent intent, int startid)
& in Service Life cycle there is no onStart(..) Method
Try this method instead of above
#Override
public int onStartCommand(Intent intent, int flags, int startId)
EDIT:
& second One you have to declare service in Manifest File Like:
<manifest ... >
...
<application ... >
<service android:name=".MyServeice" />
...
</application>
</manifest>
For more Information About Service Refer this Documentation
http://developer.android.com/guide/components/services.html

Use this method :
#Override
public int onStartCommand(Intent intent, int flags, int startId) {}
Here is good tutorial about services : Click here !

Question closed. Adding info about my service class into manifest solved my problem.

Related

How to keep alive a service, after starting, until the application be closed or killed in Android?

I am developing android application, so I am starting a service with alarm:
public void scheduleLocationCheckerAlarm() {
Intent intent = new Intent(getApplicationContext(), LocationCheckerReceiver.class);
final PendingIntent pIntent = PendingIntent.getBroadcast(this, LocationCheckerReceiver.REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
long firstMillis = System.currentTimeMillis();
AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis, 600000, pIntent);
}
LocationCheckerReceiver:
public class LocationCheckerReceiver extends BroadcastReceiver {
public static final int REQUEST_CODE = 12345;
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, LocationNotificator.class);
context.startService(i);
}
Service:
public class LocationNotificator extends Service {
public LocationNotificator() {
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Location checker", "Service running");
//My code is here
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Location checker", "Service destroyed");
}
So I want this service to be checking for something every 1 minute and to be running all the time, even when the application is closed by the user.
You must call startForeground(FOREGROUND_ID, buildForegroundNotification(filename)); in order to ensure that your service running continuously. Also, this will post a notification from your app to show the user about the service state. Please follow the reference.
Here is the code :
public class LocationNotificator extends Service {
private static int FOREGROUND_ID=1338;
public LocationNotificator() {
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("Location checker", "Service running");
//My code is here
startForeground(FOREGROUND_ID,
buildForegroundNotification(filename));
stopForeground(true);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d("Location checker", "Service destroyed");
}
private Notification buildForegroundNotification(String filename) {
NotificationCompat.Builder b=new NotificationCompat.Builder(this);
b.setOngoing(true);
b.setContentTitle("Some Title")
.setContentText("some File name")
.setSmallIcon(android.R.drawable.stat_sys_download)
.setTicker("downloading");
return(b.build());
}
You need to read this first. https://developer.android.com/guide/components/services.html
In a nutshell, start your service as a foreground service so there's lesser chance of Android killing your service. As a foreground service, you need to display an on-going notification in the status bar.
There's no direct way of making sure your service is never killed by the Android system. A workaround is to send a broadcast in onDestroy() of your service, and have a Receiver in your Android application start the service upon receiving the broadcast.
By the way, it seems that your service is sending location updates periodically to your backend server. This might be better implemented using Firebase Job Dispatcher library or Evernote's Android-Job library.

Service not run on app closed

The service works normally when is started from the MainActivity however when the application is removed from the recent apps or when activity is closed, the service is restarted instead of continuing from where it left off.
public class ServiceExample extends Service {
#Override
public IBinder onBind(Intent intent) {
// TODO: Implement this method
return null;
}
#Override
public void onCreate() {
// TODO: Implement this method
super.onCreate();
//Do Something
}
I need to perform an action in the background but it can not be stopped or restarted when the activity ends. The Service Statement is the best to Use?
Try putting this inside your service class.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
Add below code to service and override onStartCommand and return START_STICKY
#Override
public void onTaskRemoved(Intent rootIntent){
Intent restartServiceTask = new Intent(getApplicationContext(),this.getClass());
restartServiceTask.setPackage(getPackageName());
PendingIntent restartPendingIntent = PendingIntent.getService(getApplicationContext(), 1,restartServiceTask, PendingIntent.FLAG_ONE_SHOT);
AlarmManager myAlarmService = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
myAlarmService.set(
AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + 1000,
restartPendingIntent
);
super.onTaskRemoved(rootIntent);
}

How to start a service even if user force close it?

i want to start my service even if user force stop the app or some other app force stop my app.
Here is my code.
#Override
public void onDestroy() {
super.onDestroy();
stopLocationUpdates();
AlarmManager alarmMgr = (AlarmManager)this.getSystemService(this.ALARM_SERVICE);
Intent i = new Intent(this, LocationUpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, i, 0);
alarmMgr.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 10, pendingIntent);
}
I start service in onDestroy().This code will work for me if any one have more efficient way to do this please comment on it.
#Override
public void onDestroy() {
super.onDestroy();
startLocationUpdateService();
}
First of all, it is really very bad pattern to run service forcefully against
the user's willingness.
Anyways, you can restart it by using a BroadcastReceiver which handles the
broadcast sent from onDestroy() of your service.
StickyService.java
public class StickyService extends Service
{
private static final String TAG = "StickyService";
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
sendBroadcast(new Intent("YouWillNeverKillMe"));
}
}
RestartServiceReceiver.java
public class RestartServiceReceiver extends BroadcastReceiver
{
private static final String TAG = "RestartServiceReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "onReceive");
context.startService(new Intent(context.getApplicationContext(),
StickyService.class));
}
}
Declare the components in manifest file
<service android:name=".StickyService" >
</service>
<receiver android:name=".RestartServiceReceiver" >
<intent-filter>
<action android:name="YouWillNeverKillMe" >
</action>
</intent-filter>
</receiver>
Start the StickyService in a Component (i.e. Application, Activity, Fragment):
startService(new Intent(this, StickyService.class));

Pass objects to IntentService from activity

To save battery in my app I decided to use the "new" Fused locations. However I need to pass some parameters into the service which receives GPS updates. The way It's done below would work (putExtras(...)), but I would need to make a lot of classes Serializable/Parseable, which would be a pain.
I have searched around and found some other way using Binder, but can't figure out how to get it to work. Is using Binder the only way or is there another?
If anything is unclear, please tell.
Thank you.
public class LocationService extends IntentService {
...
public LocationService(StartActivity startActivity, DatabaseSQLite db, HomeFragment homeFragment) {
super("Fused Location Service");
...
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
db = (DatabaseSQLite) intent.getExtras().get("DatabaseSQLite");
...
return START_REDELIVER_INTENT;
}
}
And this is how It's used in my activity:
#Override
public void onConnected(Bundle bundle) {
mIntentService = new Intent(this, LocationService.class);
mIntentService.putExtra("DatabaseSQLite", database);
...
mPendingIntent = PendingIntent.getService(this, 1, mIntentService, 0);
}
You should check out https://github.com/greenrobot/EventBus
Examples can be found here: http://awalkingcity.com/blog/2013/02/26/productive-android-eventbus/
Basically lets you do stuff like:
#Override
public void onConnected(Bundle bundle) {
mIntentService = new Intent(this, LocationService.class);
// could be any object
EventBus.getDefault().postSticky(database);
...
mPendingIntent = PendingIntent.getService(this, 1, mIntentService, 0);
}
And whenever you need the object
public class LocationService extends IntentService {
...
public LocationService(StartActivity startActivity, DatabaseSQLite db, HomeFragment homeFragment) {
super("Fused Location Service");
...
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// could also be in Broadcast Receiver etc..
db = EventBus.getDefault().getStickyEvent(DatabaseSQLite.class);
...
return START_REDELIVER_INTENT;
}
}
Not only is it simpler, this link also shows that it outperforms other methods: http://www.stevenmarkford.com/passing-objects-between-android-activities/

This is the correct way to repeat method every x second in service?

I write a method on service to run every x seconds. But there are some problems.
What I did is
public class noti extends Service {
Context mcont;
private Handler myhandler ;
private long RETRY_TIME = 15000;
private long START_TIME = 2000;
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onStart(Intent intent, int startId) {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mcont=this;
myhandler= new Handler();
myhandler.postDelayed(myRunnable, START_TIME);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
try {
myhandler.removeCallbacks(myRunnable);
} catch (Exception e) {
// TODO: handle exception
}
}
private Runnable myRunnable = new Runnable() {
public void run() {
try {
new get_notifyalert_service(mcont).execute("") ;
} catch (Exception e) {
// TODO: handle exception
}
myhandler.postDelayed(myRunnable, RETRY_TIME);
}
};
}
this is the right way?
on the phone when I check the settings->apps->running-apps it says sometimes restarting and it took long time
thanks in advance
I see two problems in your solution:
First: Your commands will indeed be activated periodically, but they will do so on the main thread. In many cases, maybe most, you want your periodical processing to run on a separate thread.
if that is what you want, a timer will be a better option:
t = new Timer();
task = new TimerTask() {
#Override
public void run() {
// do periodical action <-------------
}
};
t.scheduleAtFixedRate(task, 0, 1000);
Second: your service will, sooner or later, be reclaimed by Android, stopping the periodical
processing.
For many apps this is not a real problem. You do not really want your background logic running all the time.
If that is not the case for you, declare your service as a foreground service (i.e. guaranteed not to be killed by Android):
Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
System.currentTimeMillis());
Intent notificationIntent = new Intent(this, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(this, getText(R.string.notification_title),
getText(R.string.notification_message), pendingIntent);
startForeground(ONGOING_NOTIFICATION_ID, notification);
..Or, at minimum, set it to be sticky:
public class StickyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_NOT_STICKY;
}
}

Categories

Resources