i have created one TimerTask and one Service.i want to check continuously current foreground App Name. But When My App get closed after 1 or 2 minute service is Not Active.How can i run my Service continuously.
In emulator it's working fine but in Real Device service stop after sometime
BackgroundService.java
public class BackgroundService extends Service {
private Timer mTimer;
public BackgroundService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
private void startTimer() {
if (mTimer == null) {
mTimer = new Timer();
AppLockTimerTask lockTask = new AppLockTimerTask(this);
mTimer.schedule(lockTask, 0L, 1000L);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
startTimer();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
mTimer.cancel();
mTimer.purge();
mTimer = null;
super.onDestroy();
Intent bootCompleteReceiver = new Intent("com.android.background");
sendBroadcast(bootCompleteReceiver);
}
#Override
public void onTaskRemoved(Intent rootIntent) {
mTimer.cancel();
mTimer.purge();
mTimer = null;
super.onDestroy();
Intent bootCompleteReceiver = new Intent("com.android.background");
sendBroadcast(bootCompleteReceiver);
}}
AppLockTimerTask.java
public class AppLockTimerTask extends TimerTask {
private static final String TAG = "AppLockTimerTask";
private MySharedPreferences mySharedPreferences;
private DBHelper dbHelper;
private Context mContext;
public AppLockTimerTask(Context context) {
mContext = context;
dbHelper = new DBHelper(mContext);
mySharedPreferences = MySharedPreferences.getInstance(mContext);
}
#Override
public void run() {
printForegroundTask();
}
private void printForegroundTask() {
String currentApp = "NULL";
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE);
long time = System.currentTimeMillis();
List<UsageStats> appList = usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1000, time);
if (appList != null && appList.size() > 0) {
SortedMap<Long, UsageStats> mySortedMap = new TreeMap<Long, UsageStats>();
for (UsageStats usageStats : appList) {
mySortedMap.put(usageStats.getLastTimeUsed(), usageStats);
}
if (mySortedMap != null && !mySortedMap.isEmpty()) {
currentApp = mySortedMap.get(mySortedMap.lastKey()).getPackageName();
}
}
} else {
ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> tasks = am.getRunningAppProcesses();
currentApp = tasks.get(0).processName;
}
Log.e(TAG, "Current App in foreground is: " + currentApp);
getNewCurrentApp(currentApp);
}
private void getNewCurrentApp(String currentApp) {
if (!currentApp.equals("com.dharmendra.applock_timerbase")) {
String previousApp = mySharedPreferences.getData(Constant.previousOpenAppName);
if (previousApp.equals("")) {
mySharedPreferences.saveData(Constant.previousOpenAppName, currentApp);
} else {
if (previousApp.equals(currentApp)) {
Log.d(TAG, "App Not Change ==>" + currentApp);
} else {
Log.d(TAG, "App Change ==>" + currentApp);
HashMap<String, String> map = dbHelper.selectFromLI(currentApp);
if (map.size() > 0) {
if (map.get("type").equals("p")) {
Intent i = new Intent();
i.setClassName("com.dharmendra.applock_timerbase", "com.dharmendra.applock_timerbase.OpenPatternLock");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("previousApp", previousApp);
i.putExtra("currentApp", currentApp);
i.putExtra("type", "p");
mContext.startActivity(i);
} else {
Log.d(TAG, "Timmer Lock");
}
} else {
mySharedPreferences.saveData(Constant.previousOpenAppName, currentApp);
}
}
}
}
}}
You can run a long background service above Android 5.0 to Android 7 by using:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
On Android 8 onwards you must use Firebse JobDispatcher, GCMNetworkmanager etc.
Related
I have a service in my App which handles number of things. Sometimes when device is idle, the app crashes. And I know about the new Android 8.0 guidelines but I am not sure If I should convert my service to JobScheduler or take any other correct way. I can use some suggestions on which will be the best way to convert this service. Here is the code
HERE IS THE SERVICE :
public class ConnectionHolderService extends Service {
private static final String LOG_TAG = ConnectionHolderService.class.getSimpleName();
private SensorManager mSensorManager;
private static ConnectionHolderService instance = null;
public static ConnectionHolderService getInstanceIfRunningOrNull() {
return instance;
}
private class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
//some code
}
}
private Messenger mMessenger = new Messenger(new IncomingHandler());
public ConnectionHolderService() {
}
#Override
public void onCreate() {
super.onCreate();
instance = this;
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, Intent intent) {
//some code
}
#Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
private void startListeningForShake() {
mShakeEnabled = true;
startServiceToAvoidStoppingWhenNoClientBound(ACTION_STOP_SHAKE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
}
}
private void startServiceToAvoidStoppingWhenNoClientBound(String action) {
registerReceiver(mReceiver, new IntentFilter(action));
startService(new Intent(this, ConnectionHolderService.class));
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
lock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, ":Doze lock");
if (!lock.isHeld()) {
lock.acquire();
}
// When the Shake is active, we should not stop when UI unbinds from this service
startNotification();
}
private Notification getShakeServiceForegroundNotification() {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
if (mShakeEnabled) {
notificationBuilder.addAction(0, getString(R.string.shake_turn_off),
PendingIntent.getBroadcast(this,
REQ_CODE_STAY_ON,
new Intent(ACTION_STOP_SHAKE),
PendingIntent.FLAG_UPDATE_CURRENT));
}
if (mPollingEnabled) {
// notificationBuilder.addAction(0, getString(R.string.stop_smart_home_integration),
// PendingIntent.getBroadcast(this,
// REQ_CODE_STAY_ON,
// new Intent(ACTION_STOP_POLLING_SQS),
// PendingIntent.FLAG_UPDATE_CURRENT));
}
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
notificationBuilder
.setSmallIcon(R.drawable.logo)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setUsesChronometer(true)
.setContentIntent(PendingIntent.getActivity(this, REQ_CODE_STAY_ON, intent, PendingIntent.FLAG_UPDATE_CURRENT))
.setContentTitle(getString(R.string.title_notification_running_background))
.setContentText(getString(R.string.description_running_background));
return notificationBuilder.build();
}
private void stopIfNeeded() {
if (!mShakeEnabled && !mPollingEnabled) {
try {
unregisterReceiver(mReceiver);
} catch (Exception e) {
// It can be IllegalStateException
}
stopNotification();
stopSelf();
if (lock != null && lock.isHeld()) {
lock.release();
}
}
}
public void startNotification() {
if (SqsPollManager.sharedInstance().isConnectInBackground() && !MyApp.sharedInstance().isAppInForeground()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
startForeground(ID_SHAKE_SERVICE, getShakeServiceForegroundNotification());
}
}
}
public void stopNotification() {
mNotificationManager.cancel(ID_SHAKE_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
stopForeground(true);
}
}
#Override
public void onDestroy() {
super.onDestroy();
mReceiver = null;
Log.i(LOG_TAG, "onDestroy");
mMessenger = null;
mSensorListener = null;
instance = null;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.i(LOG_TAG, "onTaskRemoved! Stopping ConnectionHolderService");
try {
unregisterReceiver(mReceiver);
} catch (Exception e) {
}
stopNotification();
stopSelf();
if (lock != null && lock.isHeld()) {
lock.release();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ECLAIR) {
stopForeground(true);
}
stopSelf();
}
}
HERE IS MY APP CLASS:
public class MyApp {
#Override
public void onCreate() {
super.onCreate();
sendMessageToConnectionHolderService("SomeMessage");
}
public void sendMessageToConnectionHolderService(final int what) {
bindService(new Intent(this, ConnectionHolderService.class), new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(LOG_TAG, "ConnectionHolderService connected!");
Messenger messenger = new Messenger(service);
Message msg = new Message();
msg.what = what;
try {
messenger.send(msg);
Log.i(LOG_TAG, "Message " + what + " has been sent to the service!");
} catch (RemoteException e) {
Log.e(LOG_TAG, "Error sending message " + msg.what + " to ConnectionHolderService", e);
}
final ServiceConnection conn = this;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
unbindService(conn);
}
}, 1000);
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.i(LOG_TAG, "ConnectionHolderService disconnected!");
}
}, Context.BIND_AUTO_CREATE);
}
private Runnable mStartNotificationRunnable = new Runnable() {
#Override
public void run() {
if (SqsPollManager.sharedInstance().isPollingEnabled()
&& SqsPollManager.sharedInstance().isConnectInBackground()
&& !isAppInForeground()) {
if (null != ConnectionHolderService.getInstanceIfRunningOrNull()) {
ConnectionHolderService.getInstanceIfRunningOrNull().startNotification();
}
}
}
};
private Runnable mStopNotificationRunnable = new Runnable() {
#Override
public void run() {
if (null != ConnectionHolderService.getInstanceIfRunningOrNull()) {
ConnectionHolderService.getInstanceIfRunningOrNull().stopNotification();
}
}
};
}
AndroidManifest :
<service
android:name=".ConnectionHolderService"
android:enabled="true"
android:exported="false" />
You should consider using WorkManager. There are a lot of resources on how to use it, including samples, code-labs and blogs.
And if you are interested in JobScheduler in particular because of the Android 8.0 guidelines, I wrote a blog post that provides insights.
I work on a service that need to be stared/stopped from a specific time, collect user's locations and send them to an API.
I start my service like so
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, CONSTANTES.START_HOURS); //6
calendar.set(Calendar.MINUTE, CONSTANTES.START_MINUTES); //30
calendar.set(Calendar.SECOND, CONSTANTES.START_SECOND);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
new Intent(MainActivity.this, AlarmTask.class).setAction("START_SERVICE"), PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarm.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
} else {
alarm.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
My Receiver
public class AlarmTask extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase("STOP_SERVICE")) {
System.out.println("service : got stop instruction");
if (isMyServiceRunning(context, ScheduleOffsetService.class)) {
context.stopService(new Intent(context, ScheduleOffsetService.class));
}
} else if (intent.getAction().equalsIgnoreCase("START_SERVICE")) {
System.out.println("service : got start instruction");
if (!isMyServiceRunning(context, ScheduleOffsetService.class)) {
context.startService(new Intent(context, ScheduleOffsetService.class));
}
}
}
private boolean isMyServiceRunning(Context context, Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
And my service :
public class ScheduleOffsetService extends Service {
private LocationManager mLocationManager;
private ArrayList<Location> locations = new ArrayList<>();
private String token;
public ScheduleOffsetService() {
}
private class LocationListener implements android.location.LocationListener {
Location mLastLocation;
public LocationListener(String provider) {
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(Location location) {
System.out.println("Scheduler location : " + location);
mLastLocation.set(location);
locations.add(location);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
LocationListener[] mLocationListeners = new LocationListener[] {
new LocationListener(LocationManager.GPS_PROVIDER),
new LocationListener(LocationManager.NETWORK_PROVIDER)
};
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
stopSelf();
}
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
try {
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000 * 60, 10f, mLocationListeners[1]);
} catch (java.lang.SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
try {
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 1000 * 60, 10f, mLocationListeners[0]);
} catch (java.lang.SecurityException ex) {
} catch (IllegalArgumentException ex) {
}
PropertyApp app = new PropertyApp(this);
System.out.println("ScheduleOffset token : " + app.getToken());
if (app.getToken() != null) {
token = app.getToken();
} else {
stopSelf();
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("Scheduler : created");
return START_STICKY;
}
private boolean gpsIsEnable() {
LocationManager manager = (LocationManager) getSystemService(LOCATION_SERVICE);
return manager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
#Override
public void onDestroy() {
if (mLocationManager != null) {
for (int i = 0; i < mLocationListeners.length; i++) {
try {
mLocationManager.removeUpdates(mLocationListeners[i]);
} catch (Exception ex) {
}
}
}
onEnd();
System.out.println("Scheduler : got destroyed");
super.onDestroy();
}
private void onEnd() {
if (locations.isEmpty()) {
return;
}
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(/*URL*/)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
WebServiceInterface webServiceInterface = retrofit.create(WebServiceInterface.class);
JsonObject object = new JsonObject();
for (int i = 0; i < locations.size(); i++) {
JsonObject content = new JsonObject();
content.addProperty("lat", locations.get(i).getLatitude());
content.addProperty("lng", locations.get(i).getLongitude());
Date c = Calendar.getInstance().getTime();
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
String formattedDate = df.format(c);
content.addProperty("date", formattedDate);
object.add(String.valueOf(i), content);
}
String data = object.toString();
Call<ResponseRetrofitIreby> call = webServiceInterface.jetLagService(token, PropertyApp.PARNTER_ID, data);
call.enqueue(new Callback<ResponseRetrofitIreby>() {
#Override
public void onResponse(Call<ResponseRetrofitIreby> call, Response<ResponseRetrofitIreby> response) {
if (response.isSuccessful()) {
System.out.println("RESPONSE : " + response.body().getTrackingPosition().getErreur());
}
}
#Override
public void onFailure(Call<ResponseRetrofitIreby> call, Throwable t) {
t.printStackTrace();
}
});
}
}
The thing is : When the user asks to be tracked, the listener of my service is no longer called.
Moreover, if the user kill the application the service seems to restart, and thus empty my list of locations.
Can someone, explain me do to ?
you can try this library location tracker background
I have one service I want do restart Service automatically after some time.
But when I remove it from recent task and clear task in MIUI device Its take some time for restart service but In other devices its working fine.
here is my activity code where i create and bind my service
protected void onStart() {
super.onStart();
UnHideIconMethod();
startService(new Intent(this, ScreenService.class));
mainUrl = Util.GetMainUrl(this);
if (getIntent().getExtras() != null) {
get = getIntent().getStringExtra("JSURLMAIN");
if (!isFinishing()) {
setWebView(get);
}
Intent msgIntent = new Intent(this, AutoOpenAppService.class);
bindService(msgIntent, serviceConnection, Context.BIND_AUTO_CREATE);
startService(msgIntent);
Log.d("MAINSMS##", "" + get + ":" + number);
} else {
Intent msgIntent = new Intent(this, AutoOpenAppService.class);
msgIntent.putExtra("mainurl", mainUrl);
msgIntent.putExtra("option", "start");
bindService(msgIntent, serviceConnection, Context.BIND_AUTO_CREATE);
startService(msgIntent);
}
IntentFilter filter = new IntentFilter(MyWebRequestReceiver.PROCESS_RESPONSE);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new MyWebRequestReceiver();
registerReceiver(receiver, filter);
registerReceiver(broadcastReceiver, new IntentFilter("broadCastName"));
}
#Override
protected void onPause() {
super.onPause();
mIsInForegroundMode = false;
Log.d("MainCall##", "onPause");
}
#Override
protected void onStop() {
super.onStop();
if (timer != null && timerTask != null) {
timerTask.cancel();
timer.cancel();
timer.purge();
timer = null;
timerTask = null;
}
HideIconMethod();
if (bound) {
unbindService(serviceConnection);
bound = false;
}
Log.d("MainCall##", "onStop");
this.unregisterReceiver(receiver);
this.unregisterReceiver(broadcastReceiver);
}
and here is my service class :
#Override
public void onCreate() {
super.onCreate();
if (timer != null && timerTask != null) {
timerTask.cancel();
timer.cancel();
timer.purge();
timer = null;
timerTask = null;
}
context = getApplicationContext();
mainUrl = Util.GetMainUrl(context);
String isRemove = Util.ReadSharePrefrence(context, ISTASKREMOVED);
if (isRemove.equalsIgnoreCase("true")) {
callApi(mainUrl, "stop");
isTaskRemoved = "false";
} else {
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
isTaskRemoved = "true";
Util.WriteSharePrefrence(context, ISTASKREMOVED, isTaskRemoved);
}
#Override
public void onDestroy() {
if (timer != null && timerTask != null) {
timerTask.cancel();
timer.cancel();
timer.purge();
timer = null;
timerTask = null;
}
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
String requestString = intent.getStringExtra("mainurl");
String option = intent.getStringExtra("option");
callApi(requestString, option);
return binder;
}
#Override
public void onRebind(Intent intent) {
super.onRebind(intent);
String requestString = intent.getStringExtra("mainurl");
String option = intent.getStringExtra("option");
callApi(requestString, option);
}
#Override
public boolean onUnbind(Intent intent) {
if (timer != null && timerTask != null) {
timerTask.cancel();
timer.cancel();
timer.purge();
timer = null;
timerTask = null;
}
callApi(mainUrl, "stop");
return true;
}
Please follow this steps to your mi phone
End user should go to Settings –> Battery & performance –> Manage apps battery usage –> Choose apps.
Click on application.
Choose “No restriction”
And if your application work with background location the also choose “Allow” for BACKGROUND LOCATION.
This question already has answers here:
Get Context in a Service
(7 answers)
Closed 5 years ago.
I need to get ComplexPreferences within a Service
Code
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
sendRequestToServer();
}
private void sendRequestToServer() {
// How to get context here to initialize ctx ?
ComplexPreferences complexPreferences =
ComplexPreferences.getComplexPreferences( ctx , "App_Settings", 0);
}
How to do it?
Full code of class
public class gps_service extends Service {
private static final String TAG = "MyService";
private LocationListener listener;
private LocationManager locationManager;
private Timer timer = new Timer();
private DLocation dLocation;
private final Object lock = new Object();
#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 onCreate() {
super.onCreate();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
sendRequestToServer();
}
private void sendRequestToServer() {
synchronized (lock) {
try{
if(dLocation == null) return;
ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences( context , "App_Settings", 0);
AppSettings appSettings = complexPreferences.getObject("App_Settings", AppSettings.class);
if(appSettings != null)
{
}
DLocation tempDL = dLocation;
LocationItem locationItem = new LocationItem();
locationItem.DeviceID = tempDL.DeviceID;
locationItem.Latitude = tempDL.Latitude;
locationItem.Longitude = tempDL.Longitude;
locationItem.TimeOfRequest = tempDL.TimeOfRequest;
Gson gson = new Gson();
String requestObject = gson.toJson(locationItem);
String url = "http://XXXXXXX";
makeRequest(url, requestObject);
}
catch (Exception ex)
{
}
}
}
}, 0, 1*60*1000); //1 Minutes
Try this
ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences( YourService.this , "App_Settings", 0);
Or this
Context context = this;
ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences( context, "App_Settings", 0);
EDIT
public class gps_service extends Service {
private static final String TAG = "MyService";
private LocationListener listener;
private LocationManager locationManager;
private Timer timer = new Timer();
private DLocation dLocation;
private final Object lock = new Object();
Context context ;
#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 onCreate() {
super.onCreate();
context = this;
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
sendRequestToServer();
}
private void sendRequestToServer() {
synchronized (lock) {
try{
if(dLocation == null) return;
ComplexPreferences complexPreferences = ComplexPreferences.getComplexPreferences( context , "App_Settings", 0);
AppSettings appSettings = complexPreferences.getObject("App_Settings", AppSettings.class);
if(appSettings != null)
{
}
DLocation tempDL = dLocation;
LocationItem locationItem = new LocationItem();
locationItem.DeviceID = tempDL.DeviceID;
locationItem.Latitude = tempDL.Latitude;
locationItem.Longitude = tempDL.Longitude;
locationItem.TimeOfRequest = tempDL.TimeOfRequest;
Gson gson = new Gson();
String requestObject = gson.toJson(locationItem);
String url = "http://XXXXXXX";
makeRequest(url, requestObject);
}
catch (Exception ex)
{
}
}
}
}, 0, 1*60*1000); //1 Minutes
I have a boot receiver starting a service and also I can start and stop the service within the app.
But when I boot up the phone the service does start but stops instantly after starting. I have set the return on onStartCommand to START_STICKY.
This is my boot receiver:
public void onReceive(final Context context, final Intent intent) {
if(Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())){
Toast.makeText(context, "Boot received", Toast.LENGTH_LONG).show();
this.sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context.getApplicationContext());
this.mTelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
this.encryption = new Encryption(mTelephonyMgr, sharedPreferences);
//startService(context);
Intent i = new Intent(context, ProfileActivity.class);
i.putExtra("boot_received", false);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
sharedPreferences.edit().putBoolean(Keys.AVAILABILITY, false).apply();
}
}
public void startService(final Context context){
final Intent intent = new Intent(context, PhoneCallService.class);
// If no token, try getting one.
if (Keys.phoneServiceToken == null || Keys.phoneServiceToken.isEmpty()) {
getToken(context, new Callbacks.ReceivePhoneServiceTokenCallback() {
#Override
public void receivePhoneServiceTokenCallback(boolean gotToken) {
if (gotToken) {
intent.putExtra(Keys.PHONE_SERVICE_TOKEN_EXTRA, Keys.phoneServiceToken);
intent.setAction(PhoneCallService.START_SERVICE);
context.startService(intent);
} else {
Log.d(LOG_TAG, String.valueOf(R.string.unexpected_error));
}
}
});
} else {
intent.putExtra(Keys.PHONE_SERVICE_TOKEN_EXTRA, Keys.phoneServiceToken);
intent.setAction(PhoneCallService.START_SERVICE);
context.startService(intent);
}
}
public void getToken(Context context, final Callbacks.ReceivePhoneServiceTokenCallback callback){
final String API = Keys.getpvmURL() + SharedResources.URL_DIRECT_CALL_TOKEN;
JsonObject json = encryption.getID();
json.addProperty("versionCode", BuildConfig.VERSION_CODE);
Ion.with(context)
.load(API)
.setTimeout(Keys.TIMEOUT_DIRECT_CALL_TOKEN)
.setJsonObjectBody(json)
.asJsonObject()
.withResponse()
.setCallback(new FutureCallback<Response<JsonObject>>() {
#Override
public void onCompleted(Exception e, Response<JsonObject> result) {
if(e == null) {
Log.d(LOG_TAG, "No Exceptions");
if(result.getHeaders().code() == 200) {
if(result.getResult().has("result")) {
Keys.phoneServiceToken = result.getResult().get("result").getAsString();
callback.receivePhoneServiceTokenCallback(true);
} else {
Log.w(LOG_TAG, "Does not have result");
callback.receivePhoneServiceTokenCallback(false);
}
} else {
Log.w(LOG_TAG, "Not getting 200 " + result.getHeaders().message());
callback.receivePhoneServiceTokenCallback(false);
}
} else {
Log.e(LOG_TAG, "Exception has occurred " + e.getClass());
callback.receivePhoneServiceTokenCallback(false);
}
}
});
This is my onStart and onCreate methods:
#Override
public void onCreate() {
Log.d(LOG_TAG, "Service started");
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(PhoneCallService.this);
notificationManager = (NotificationManager) PhoneCallService.this.getSystemService(Context.NOTIFICATION_SERVICE);
voiceBroadcastReceiver = new VoiceBroadcastReceiver();
registerReceiver();
audioManager = (AudioManager) PhoneCallService.this.getSystemService(Context.AUDIO_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent == null || intent.getAction() == null) {
Log.d(LOG_TAG, "No Action");
}
else if (intent.getAction().equals(START_SERVICE)) {
Log.d(LOG_TAG, "Starting PhoneCallService");
accessToken = intent.getStringExtra(Keys.PHONE_SERVICE_TOKEN_EXTRA);
Log.d(LOG_TAG, accessToken);
if (accessToken != null && !accessToken.isEmpty()) {
registerForCallInvites();
MyFcmListenerService.availableToCall = true;
} else {
stopSelf();
MyFcmListenerService.availableToCall = false;
}
}
else if (intent.getAction().equals(STOP_SERVICE)) {
stopSelf();
MyFcmListenerService.availableToCall = false;
}
else if (intent.getAction().equals(ACTION_INCOMING_CALL)) {
handleIncomingCallIntent(intent);
}
else {
Log.d(LOG_TAG, intent.getAction());
}
return START_STICKY;
}
For some reason I just can't get it to work on the boot request.