I have an application in Xamarin.Forms and I have developed a service that works only when the application is open or minimized.
I've added some logs and the service keeps running even with the application closed, but part of my code that is on Portable does not run.
Code MainActivity
var alarmIntent = new Intent(context.ApplicationContext, typeof(Receiver.AlarmReceiver));
var broadcast = PendingIntent.GetBroadcast(context.ApplicationContext, 0, alarmIntent, PendingIntentFlags.NoCreate);
if (broadcast == null)
{
var pendingIntent = PendingIntent.GetBroadcast(context.ApplicationContext, 0, alarmIntent, 0);
var alarmManager = (AlarmManager)context.GetSystemService(Context.AlarmService);
alarmManager.SetRepeating(AlarmType.ElapsedRealtimeWakeup, SystemClock.ElapsedRealtime(), 15000, pendingIntent);
}
Code Alarm Receiver
[BroadcastReceiver]
class AlarmReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
var backgroundServiceIntent = new Intent(context, typeof(ServiceBackground));
context.StartService(backgroundServiceIntent);
}
}
Code Service
[Service]
public class ServiceBackground : Service
{
private const string TAG = "[ServiceBackground]";
private bool _isRunning;
private Context _context;
private Task _task;
public override IBinder OnBind(Intent intent)
{
return null;
}
public override void OnCreate()
{
_context = this;
_isRunning = false;
_task = new Task(RunServiceBackground);
}
public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
{
if (!_isRunning)
{
_isRunning = true;
_task.Start();
}
return StartCommandResult.Sticky;
}
private void RunServiceBackground()
{
Log.Info(TAG, "StartCommandResult");
Task.Run(() =>
{
try
{
Log.Info(TAG, "init background portable");
var serviceOrdersSvc = new ServiceOrdersService();
serviceOrdersSvc.BackgroundExecute()
.ContinueWith(itemResult => {
if (!string.IsNullOrEmpty(itemResult.Result))
{
Log.Info(TAG, "itemResult");
}
});
}
catch (Android.OS.OperationCanceledException ex)
{
Log.Info(TAG, $"ex msg: {ex.Message} | s: {ex.StackTrace}");
}
catch (Exception ex)
{
Log.Info(TAG, $"ex msg: {ex.Message} | s: {ex.StackTrace}");
}
finally
{
StopSelf();
}
});
}
public override void OnDestroy()
{
base.OnDestroy();
}
}
Code portable (This part that does not work)
public async Task<string> BackgroundExecute()
{
//insert sqllite
await LogService.InsertLogAsync("init - BackgroundExecute");
//get sqllite
var list = await BackgroundTaskRequest.GetListAsync();
var rtnBackground = "";
if (list != null && list.Count > 0)
{
LogService.InsertLogAsync("list count: " + list.Count.ToString());
await Task.Run(async () =>
{
foreach (var item in list)
{
//send information web-api
}
});
}
LogService.InsertLogAsync($"end rtn: {rtnBackground}");
return rtnBackground;
}
Is the something i am missing here?
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 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.
Hello everyone i am implementing geofencing feature in my android application to send toast notifications.The thing is when i am inside(where i am making fences) a fence that i have created then the intent is fired but when i try to fire the event again by reentering the location intent is not firing here is my code
protected override void OnHandleIntent (Intent intent)
{
Intent broadcastIntent = new Intent();
var geofencingEvent = GeofencingEvent.FromIntent (intent);
if (geofencingEvent.HasError) {
var errorMessage = GeofenceErrorMessages.GetErrorString (this, geofencingEvent.ErrorCode);
Log.Error (TAG, errorMessage);
return;
}
int geofenceTransition = geofencingEvent.GeofenceTransition;
if (geofenceTransition == Geofence.GeofenceTransitionEnter ||
geofenceTransition == Geofence.GeofenceTransitionExit) {
Toast.MakeText(this, "Service Started", ToastLength.Long).Show();
IList<IGeofence> triggeringGeofences = geofencingEvent.TriggeringGeofences;
string geofenceTransitionDetails = GetGeofenceTransitionDetails (this, geofenceTransition, triggeringGeofences);
SendNotification (geofenceTransitionDetails);
Log.Info (TAG, geofenceTransitionDetails);
} else {
// Log the error.
Log.Error (TAG, GetString (Resource.String.geofence_transition_invalid_type, new [] { new Java.Lang.Integer (geofenceTransition) }));
}
}
string GetGeofenceTransitionDetails (Context context, int geofenceTransition, IList<IGeofence> triggeringGeofences)
{
string geofenceTransitionString = GetTransitionString (geofenceTransition);
var triggeringGeofencesIdsList = new List<string> ();
foreach (IGeofence geofence in triggeringGeofences) {
triggeringGeofencesIdsList.Add (geofence.RequestId);
}
var triggeringGeofencesIdsString = string.Join (", ", triggeringGeofencesIdsList);
return geofenceTransitionString + ": " + triggeringGeofencesIdsString;
}
void SendNotification (string notificationDetails)
{
var notificationIntent = new Intent (ApplicationContext, typeof(MainActivity));
var stackBuilder = Android.Support.V4.App.TaskStackBuilder.Create (this);
stackBuilder.AddParentStack (Java.Lang.Class.FromType (typeof(MainActivity)));
stackBuilder.AddNextIntent (notificationIntent);
var notificationPendingIntent = stackBuilder.GetPendingIntent (0, (int)PendingIntentFlags.UpdateCurrent);
var builder = new NotificationCompat.Builder (this);
builder.SetSmallIcon (Resource.Drawable.icon)
.SetLargeIcon (BitmapFactory.DecodeResource (Resources, Resource.Drawable.icon))
.SetColor (Color.Red)
.SetContentTitle (notificationDetails)
.SetContentText (GetString (Resource.String.geofence_transition_notification_text))
.SetContentIntent (notificationPendingIntent);
builder.SetAutoCancel (true);
var mNotificationManager = (NotificationManager)GetSystemService (Context.NotificationService);
mNotificationManager.Notify (0, builder.Build ());
}
string GetTransitionString (int transitionType)
{
switch (transitionType) {
case Geofence.GeofenceTransitionEnter:
return GetString (Resource.String.geofence_transition_entered);
case Geofence.GeofenceTransitionExit:
return GetString (Resource.String.geofence_transition_exited);
default:
return GetString (Resource.String.unknown_geofence_transition);
}
}
and my main activity is
{
protected const string TAG = "creating-and-monitoring-geofences";
protected GoogleApiClient mGoogleApiClient;
protected IList<IGeofence> mGeofenceList;
bool mGeofencesAdded;
PendingIntent mGeofencePendingIntent;
ISharedPreferences mSharedPreferences;
Button mAddGeofencesButton;
Button mRemoveGeofencesButton;
protected override void OnCreate (Bundle savedInstanceState)
{
base.OnCreate (savedInstanceState);
SetContentView (Resource.Layout.main_activity);
mAddGeofencesButton = FindViewById<Button> (Resource.Id.add_geofences_button);
mRemoveGeofencesButton = FindViewById<Button> (Resource.Id.remove_geofences_button);
mAddGeofencesButton.Click += AddGeofencesButtonHandler;
mRemoveGeofencesButton.Click += RemoveGeofencesButtonHandler;
mGeofenceList = new List<IGeofence> ();
mGeofencePendingIntent = null;
mSharedPreferences = GetSharedPreferences (Constants.SHARED_PREFERENCES_NAME,
FileCreationMode.Private);
mGeofencesAdded = mSharedPreferences.GetBoolean (Constants.GEOFENCES_ADDED_KEY, false);
SetButtonsEnabledState ();
PopulateGeofenceList ();
BuildGoogleApiClient ();
}
protected void BuildGoogleApiClient ()
{
mGoogleApiClient = new GoogleApiClient.Builder (this)
.AddConnectionCallbacks (this)
.AddOnConnectionFailedListener (this)
.AddApi (LocationServices.API)
.Build ();
}
private IntentFilter mIntentFilter;
protected override void OnResume ()
{
base.OnResume();
mGoogleApiClient.Connect ();
}
protected override void OnStart()
{
base.OnStart();
mGoogleApiClient.Connect();
}
protected override void OnStop ()
{
base.OnStop ();
// mGoogleApiClient.Disconnect ();
}
public void OnConnected (Bundle connectionHint)
{
Log.Info (TAG, "Connected to GoogleApiClient");
}
public void OnConnectionSuspended (int cause)
{
Log.Info (TAG, "Connection suspended");
}
public void OnConnectionFailed (Android.Gms.Common.ConnectionResult result)
{
Log.Info (TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.ErrorCode);
}
GeofencingRequest GetGeofencingRequest ()
{
var builder = new GeofencingRequest.Builder ();
builder.SetInitialTrigger (GeofencingRequest.InitialTriggerEnter);
builder.AddGeofences (mGeofenceList);
return builder.Build ();
}
public async void AddGeofencesButtonHandler (object sender, EventArgs e)
{
if (!mGoogleApiClient.IsConnected) {
Toast.MakeText (this, GetString (Resource.String.not_connected), ToastLength.Short).Show ();
return;
}
try {
var status = await LocationServices.GeofencingApi.AddGeofencesAsync (mGoogleApiClient, GetGeofencingRequest (),
GetGeofencePendingIntent ());
HandleResult (status);
} catch (SecurityException securityException) {
LogSecurityException(securityException);
}
}
public async void RemoveGeofencesButtonHandler (object sender, EventArgs e)
{
if (!mGoogleApiClient.IsConnected) {
Toast.MakeText (this, GetString(Resource.String.not_connected), ToastLength.Short).Show ();
return;
}
try {
var status = await LocationServices.GeofencingApi.RemoveGeofencesAsync (mGoogleApiClient,
GetGeofencePendingIntent ());
HandleResult (status);
} catch (SecurityException securityException) {
LogSecurityException (securityException);
}
}
void LogSecurityException (SecurityException securityException)
{
Log.Error (TAG, "Invalid location permission. " +
"You need to use ACCESS_FINE_LOCATION with geofences", securityException);
}
public void HandleResult (Statuses status)
{
if (status.IsSuccess) {
mGeofencesAdded = !mGeofencesAdded;
var editor = mSharedPreferences.Edit ();
editor.PutBoolean (Constants.GEOFENCES_ADDED_KEY, mGeofencesAdded);
editor.Commit ();
SetButtonsEnabledState ();
Toast.MakeText (
this,
GetString (mGeofencesAdded ? Resource.String.geofences_added :
Resource.String.geofences_removed),
ToastLength.Short
).Show ();
} else {
var errorMessage = GeofenceErrorMessages.GetErrorString (this,
status.StatusCode);
Log.Error (TAG, errorMessage);
}
}
PendingIntent GetGeofencePendingIntent ()
{
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
//var intent = new Intent(this, typeof(Test));
//SendBroadcast(intent);
//return PendingIntent.GetBroadcast(this, 0, intent, PendingIntentFlags.UpdateCurrent);
var intent = new Intent(this, typeof(GeofenceTransitionsIntentService));
//SendBroadcast(intent);
return PendingIntent.GetService(this, 0, intent, PendingIntentFlags.UpdateCurrent);
}
public void PopulateGeofenceList ()
{
foreach (var entry in Constants.BAY_AREA_LANDMARKS) {
mGeofenceList.Add (new GeofenceBuilder ()
.SetRequestId (entry.Key)
.SetCircularRegion (
entry.Value.Latitude,
entry.Value.Longitude,
Constants.GEOFENCE_RADIUS_IN_METERS
)
.SetExpirationDuration (Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
.SetTransitionTypes (Geofence.GeofenceTransitionEnter |
Geofence.GeofenceTransitionExit)
.Build ());
}
}
void SetButtonsEnabledState ()
{
if (mGeofencesAdded) {
mAddGeofencesButton.Enabled = false;
mRemoveGeofencesButton.Enabled = true;
} else {
mAddGeofencesButton.Enabled = true;
mRemoveGeofencesButton.Enabled = false;
}
}
}
}
also i have tried making a broadcast reciever but it didnt helped me much
I see your code looks exactly like the sample you pull from the google developer page, and is the one many people is using more commonly at first. I myself was having issues with accuracy and missing fence transitions with that one too. I read that manually adding an instance of the previous location request package (LocationManager) and explicitly specifying GPS as a provider in high update mode can make it more accurate. That's how I have it working now. You can also try making your fences' radii wider, that way you will take into account the minimum wi-fi accuracy which is stated to be around 50m not considering drift.
I have developed a widget which will fetch the data from a server and do some modifications and display in widget.
I have a ALARM manager which starts a service in every 10 sec and service fetches data with async task and display.
It consumes a lot of CPU usage.
Kindly help if I can change the code design and make the widget more effective.
I use Jsoup to connect and fetch data.
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Log.d("Widget : " , "Inside onUpdate widget");
// To prevent any ANR timeouts, we perform the update in a service
final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
final Calendar TIME = Calendar.getInstance();
TIME.set(Calendar.MINUTE, 0);
TIME.set(Calendar.SECOND, 0);
TIME.set(Calendar.MILLISECOND, 0);
final Intent i = new Intent(context, UpdateService.class);
if (service == null)
{
service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
}
m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 100 * 60, service);
}
public static class UpdateService extends Service {
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// System.out.println("Inside config change ");
enableControls(this);
}
#Override
public void onStart(Intent intent, int startId) {
// Build the widget update for today
mContext = this;
Log.d("Widget : " , "Service started");
enableControls(this);
}
public static void enableControls(Context context){
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_status);
Intent active = new Intent(context, MyWidgetProvider.class);
active.setAction(ACTION_WIDGET_REFRESH);
active.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0, active, 0);
pushWidgetUpdate(context, remoteViews);
fetchStatus();
}
public static void fetchStatus(){
new AsyncTask<String, Void, String>() {
#Override
protected String doInBackground(String... urls) {
try {
if(getWiFiStatus(mContext) == true ){
boolean getRedirectedURL = false;
String url,finalURL;
finalURL = "http://mobile.server.status";
Document doc = Jsoup.connect(finalURL).get();
while(getRedirectedURL == false){
Log.d(LOG_TAG,"inside while loop ---- : " + getRedirectedURL);
doc = Jsoup.connect(finalURL).get();
Log.d(LOG_TAG,"Complete doc: " + doc);
// System.out.println("Found the doc : " +doc.toString().contains("status"));
// Log.d(LOG_TAG,"Whole data third :"+doc);
// System.out.println("Printing redirected URL " + (docHead.select("meta")));
if(doc.toString().contains("status")){
getRedirectedURL = true;
break;
}
else
getRedirectedURL = false;
Elements docHead = doc.select("meta");
for(Element emt :docHead) {
url =null;
//Log.d(LOG_TAG,"Value boolean :"+emt.getElementsByAttribute("http-equiv").toString().toLowerCase().contains("url"));
if(emt.getElementsByAttribute("http-equiv").toString().toLowerCase().contains("url") ){
//getRedirectedURL = true;
url = emt.getElementsByAttribute("http-equiv").toString().toLowerCase().split("url=")[1].toString();
if (emt.getElementsByAttribute("http-equiv").toString().toLowerCase().contains("http://")){
finalURL = null;
finalURL = url.split("\"")[0].toString();
}
else
finalURL = finalURL + url.split("\"")[0].toString();
//Log.d(LOG_TAG,"Final URL :"+finalURL);
}
// else
// getRedirectedURL = false;
}
}
Log.d(LOG_TAG,"Final URL :"+finalURL);
doc = Jsoup.connect(finalURL).get();
Document noFramesDoc = Jsoup.parseBodyFragment(doc.toString());
}
else{
refreshStatus(mContext);
}
} catch (UnknownHostException exception){
System.out.println("Inside unknown host : ");
}
catch (Exception e) {
Log.d(LOG_TAG,"other Exception found :"+e.toString());
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
if(mContext != null)
}
#Override
protected void onCancelled() {
}
}.execute();
}
In my application I want to call service from Receiver.
This is my NotificationReceiver.java
public class NotificationReceiver extends BroadcastReceiver {
NotificationReceiver _this = this;
private static Context _context;
public static final String ACTION_REFRESH_SCHEDULE_ALARM = "com.example.receiver.ACTION_REFRESH_SCHEDULE_ALARM";
String SERVER_URL = "http://192.168.1.7:8080";
#Override
public void onReceive(final Context context, Intent intent) {
_context = context;
initClient();
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(_context);
if (settings.getString("userId",null) != null){
gotNotification(new ClientListener(){
#Override
public void onSuccess(String response) {
try {
JSONObject object = new JSONObject(response);
System.out.println("Service object = "+ object);
} catch (JSONException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
#Override
public void onFail(int error) {
}
#Override
public void onCancel() {
}
},settings.getString("userId",null));
}
}
private void initClient(){
NotifierRestClient.init(SERVER_URL + "/api");
}
private void gotNotification (final ClientListener clientListener, final String uId) {
new Thread() {
#Override
public void run() {
try {
final String responseText = NotifierRestClient.getUserNotifications(uId,null);
if (clientListener != null) {
clientListener.onSuccess(responseText);
}
} catch (final Exception e) {
e.printStackTrace();
if (clientListener != null) {
clientListener.onFail(505);
}
}
}
}.start();
}
}
And this is my NotifiactionService.java
public class NotificationService extends Service {
private AlarmManager alarmManagerPositioning;
private PendingIntent pendingIntent;
#Override
public void onCreate() {
super.onCreate();
alarmManagerPositioning = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
final Intent intentToNotificate = new Intent(NotificationReceiver.ACTION_REFRESH_SCHEDULE_ALARM);
pendingIntent = PendingIntent.getBroadcast(this, 0, intentToNotificate, 0);
}
#Override
public void onStart(Intent intent, int startId) {
try {
long notificationInterval = 5002;
alarmManagerPositioning.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), notificationInterval, pendingIntent);
} catch (NumberFormatException e) {
Toast.makeText(this, "error running services: " + e.getMessage(), Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(this, "error running services: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onDestroy() {
this.alarmManagerPositioning.cancel(pendingIntent);
}
}
My question is how to call NotificationService in NotificationReceiver and change interval? Any help will be useful Thanks
Start Service in your receiver using
Intent in = new Intent(context,NotificationService.class);
in.putExtra("interval",5001);
context.startService(in);
In your service code,
long notificationInterval = intent.getLongExtra("interval", defaultValue)
to get Data from your receiver, Please use onStartCommand(Intent intent, int flags, int startId), onStart has been deprecated.