Scheduling of tasks with the Android JobScheduler

The new JobService must be registered in the Android manifest with the BIND_JOB_SERVICE permission.

<service
            android:name=".TestJobService"
            android:label="Word service"
            android:permission="android.permission.BIND_JOB_SERVICE" >

</service>

Create the receiver

Create the following utility class.

package com.vogella.android.localservice;

import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.ComponentName;
import android.content.Context;

public class Util {

    // schedule the start of the service every 10 - 30 seconds
    public static void scheduleJob(Context context) {
        ComponentName serviceComponent = new ComponentName(context, TestJobService.class);
        JobInfo.Builder builder = new JobInfo.Builder(0, serviceComponent);
        builder.setMinimumLatency(1 * 1000); // wait at least
        builder.setOverrideDeadline(3 * 1000); // maximum delay
        //builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED); // require unmetered network
        //builder.setRequiresDeviceIdle(true); // device should be idle
        //builder.setRequiresCharging(false); // we don't care if the device is charging or not
        JobScheduler jobScheduler = context.getSystemService(JobScheduler.class);
        jobScheduler.schedule(builder.build());
    }

}

Create the following receiver

package com.vogella.android.localservice;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class MyStartServiceReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Util.scheduleJob(context);
    }
}

Register the receiver in the Android manifest for the BOOT_COMPLETED event.

<receiver android:name="MyStartServiceReceiver" >
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>
</receiver>

Create your job

package com.vogella.android.localservice;

import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Intent;

/**
 * JobService to be scheduled by the JobScheduler.
 * start another service
 */
public class TestJobService extends JobService {
    private static final String TAG = "SyncService";

    @Override
    public boolean onStartJob(JobParameters params) {
        Intent service = new Intent(getApplicationContext(), LocalWordService.class);
        getApplicationContext().startService(service);
        Util.scheduleJob(getApplicationContext()); // reschedule the job
        return true;
    }

    @Override
    public boolean onStopJob(JobParameters params) {
        return true;
    }

}

References
http://www.vogella.com/tutorials/AndroidTaskScheduling/article.html
https://code.tutsplus.com/tutorials/using-the-jobscheduler-api-on-android-lollipop–cms-23562
https://medium.com/google-developers/scheduling-jobs-like-a-pro-with-jobscheduler-286ef8510129

Android Foreground Service

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
 
            Toast.makeText(this,"Start Service",Toast.LENGTH_SHORT).show();
 
            Intent notificationIntent = new Intent(this, MainActivity.class);
            notificationIntent.setAction(MainActivity.MAIN_ACTION);
            notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                    | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
                    notificationIntent, 0);
 
            RemoteViews notificationView = new RemoteViews(this.getPackageName(),R.layout.notification);
 
 
            Intent buttonCloseIntent = new Intent(this, NotificationCloseButtonHandler.class);
            buttonCloseIntent.putExtra("action", "close");
 
            PendingIntent buttonClosePendingIntent = pendingIntent.getBroadcast(this, 0, buttonCloseIntent, 0);
            notificationView.setOnClickPendingIntent(R.id.notification_button_close, buttonClosePendingIntent);
 
            Bitmap icon = BitmapFactory.decodeResource(getResources(),
                    R.mipmap.ic_launcher);
 
            Notification notification = new NotificationCompat.Builder(this)
                    .setContentTitle("Test")
                    .setTicker("Test")
                    .setContentText("Test")
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setLargeIcon(
                            Bitmap.createScaledBitmap(icon, 128, 128, false))
                    .setContent(notificationView)
                    .setOngoing(true).build();
 
 
 
            startForeground(101,
                    notification);
 
 
 
        return START_STICKY;
    }

References
https://questdot.com/android-foreground-service/
https://stackoverflow.com/questions/24479860/foreground-service-to-prevent-process-kill

Sort a list of objects by a certain value within the object

Collections.sort(myList, new Comparator<EmployeeClass>(){
    public int compare(EmployeeClass obj1, EmployeeClass obj2) {
        // ## Ascending order
        return obj1.firstName.compareToIgnoreCase(obj2.firstName); // To compare string values
        // return Integer.valueOf(obj1.empId).compareTo(obj2.empId); // To compare integer values

        // ## Descending order
        // return obj2.firstName.compareToIgnoreCase(obj1.firstName); // To compare string values
        // return Integer.valueOf(obj2.empId).compareTo(obj1.empId); // To compare integer values
        }
    });
responseDto.getValues().sort((o1, o2) -> o1.getTime().compareTo(o2.getTime()));
responseDto.getValues().sort(Comparator.comparing(ItemTableResponseDto.Value::getTime));

References
https://stackoverflow.com/questions/9109890/android-java-how-to-sort-a-list-of-objects-by-a-certain-value-within-the-object

Prevent Snackbar from closing on Android

Snackbar is now part of the new Android Support Design library. you can use LENGTH_INDEFINITE as duration if you want to show it indefinitely. . You should drop the third party library you are using for it

Old answer

final SnackBar tmp = new SnackBar(ActSplash.this,
      "Do you want change color of this button to red?",
      "yes", 
       new View.OnClickListener() {
          @Override
          public void onClick(View v) {
              ButtonFlat btn = (ButtonFlat) findViewById(R.id.buttonSnackBar);
             //btn.setTextColor(Color.RED);
        }
});
tmp.setIndeterminate(true);
tmp.show();

References
https://stackoverflow.com/questions/29921663/how-to-prevent-snackbar-from-closing

Color animation using ValueAnimator on Android

int colorFrom = getResources().getColor(R.color.red);
int colorTo = getResources().getColor(R.color.blue);
ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(), colorFrom, colorTo);
colorAnimation.setDuration(250); // milliseconds
colorAnimation.addUpdateListener(new AnimatorUpdateListener() {

    @Override
    public void onAnimationUpdate(ValueAnimator animator) {
        textView.setBackgroundColor((int) animator.getAnimatedValue());
    }

});
colorAnimation.start();

References
https://stackoverflow.com/questions/2614545/animate-change-of-view-background-color-on-android

Prevent services of Android app from being killed using Intent.ACTION_TIME_TICK

// register intent time tick receiver which ticks every minute
registerReceiver(timeTickReceiver, new IntentFilter(Intent.ACTION_TIME_TICK));
    /**
     * restart service every minute if it's killed
     */
    private BroadcastReceiver timeTickReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                boolean isServiceRunning = false;

                if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) {

                    ActivityManager manager = (ActivityManager) getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);

                    if (manager != null) {
                        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
                            if ("net.pupli.monitoring.MyMqttService".equals(service.service.getClassName())) {
                                isServiceRunning = true;
                            }
                        }
                    }

                    if (!isServiceRunning) {
                        Intent i = new Intent(context, MyMqttService.class);
                        context.startService(i);
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    };

References
https://llin233.github.io/2015/11/16/How-to-prevent-service/
https://developer.android.com/reference/android/content/Intent#action_time_tick
https://medium.com/google-developers/who-lives-and-who-dies-process-priorities-on-android-cb151f39044f
http://sourabhsoni.com/how-to-use-intent-action_time_tick/

Detect Outlier values in Java Using BoxPlot formula and Apache Commons Math Library

public boolean isOutlier(List<RawItem> rawItems, String value) {

        DescriptiveStatistics descriptiveStatistics = new DescriptiveStatistics();
        double dValue = Double.parseDouble(value);

        for (RawItem rawItem : rawItems) {
            double d = Double.parseDouble(rawItem.getValue());

            descriptiveStatistics.addValue(d);
        }

        double Q1 = descriptiveStatistics.getPercentile(25);
        double Q3 = descriptiveStatistics.getPercentile(75);
        double IQR = Q3 - Q1;

        double highRange = Q3 + 3 * IQR;
        double lowRange = Q1 - 3 * IQR;

        if (dValue > highRange || dValue < lowRange) {
            return true;
        }

        return true;
    }

References
https://www.shmoop.com/basic-statistics-probability/box-whisker-plots.html
http://www.baeldung.com/apache-commons-math
https://stackoverflow.com/questions/22888902/get-median-from-number-series-using-apache-commons-math

Guide to Guava’s EventBus in Java

Setup

EventBus eventBus = new EventBus();

Creating Listeners

public class EventListener {
 
    private static int eventsHandled;
 
    @Subscribe
    public void stringEvent(String event) {
        eventsHandled++;
    }
}

Registering Listeners

EventListener listener = new EventListener();
eventBus.register(listener);

Unregistering Listeners

eventBus.unregister(listener);

Posting Events

@Test
public void givenStringEvent_whenEventHandled_thenSuccess() {
    eventBus.post("String Event");
    assertEquals(1, listener.getEventsHandled());
}

Posting Custom Events

public class CustomEvent {
    private String action;
 
    // standard getters/setters and constructors
}
@Subscribe
public void someCustomEvent(CustomEvent customEvent) {
    eventsHandled++;
}
@Test
public void givenCustomEvent_whenEventHandled_thenSuccess() {
    CustomEvent customEvent = new CustomEvent("Custom Event");
    eventBus.post(customEvent);
 
    assertEquals(1, listener.getEventsHandled());
}

Handling an Unsubscribed Event

@Subscribe
public void handleDeadEvent(DeadEvent deadEvent) {
    eventsHandled++;
}

References
http://www.baeldung.com/guava-eventbus