Monthly Archives: May 2018

Modify Socket parameters of Mqtt Client

import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import javax.net.SocketFactory;

public class MySocketFactory extends SocketFactory {

    private SocketFactory socketFactory;
    private Socket socket;

    public MySocketFactory() {
        this.socketFactory = SocketFactory.getDefault();
    }

    public MySocketFactory(SocketFactory socketFactory) {
        this.socketFactory = socketFactory;
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException {
        socket = this.socketFactory.createSocket(host, port);
        modifySocket();
        return socket;
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
        socket = socketFactory.createSocket(host, port, localHost, localPort);
        modifySocket();
        return socket;
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        socket = socketFactory.createSocket(host, port);
        modifySocket();
        return socket;
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        socket = socketFactory.createSocket(address, port, localAddress, localPort);
        modifySocket();
        return socket;
    }

    @Override
    public Socket createSocket() throws IOException {
        socket = socketFactory.createSocket();
        modifySocket();
        return socket;
    }

    private void modifySocket() throws IOException {
        socket.setKeepAlive(true);
        socket.setSoTimeout(10 * 1000);
        socket.setSoLinger(true, 0);
        socket.setTcpNoDelay(true);
    }
}
String broker = Statics.broker;
// mqtt paho client id
clientId = MqttClient.generateClientId();
client = new MqttAndroidClient(MyMqttService.this, broker,
                        clientId, new MemoryPersistence());

MqttConnectOptions options = new MqttConnectOptions();
options.setAutomaticReconnect(false);
options.setCleanSession(true);
options.setUserName(""test");
options.setPassword("test".toCharArray());
options.setConnectionTimeout(20);
options.setKeepAliveInterval(0);

MySocketFactory mySocketFactory=new MySocketFactory();
options.setSocketFactory(mySocketFactory);

Saving Android Activity state using Save Instance State

@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
  super.onSaveInstanceState(savedInstanceState);
  // Save UI state changes to the savedInstanceState.
  // This bundle will be passed to onCreate if the process is
  // killed and restarted.
  savedInstanceState.putBoolean("MyBoolean", true);
  savedInstanceState.putDouble("myDouble", 1.9);
  savedInstanceState.putInt("MyInt", 1);
  savedInstanceState.putString("MyString", "Welcome back to Android");
  // etc.
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
  super.onRestoreInstanceState(savedInstanceState);
  // Restore UI state from the savedInstanceState.
  // This bundle has also been passed to onCreate.
  boolean myBoolean = savedInstanceState.getBoolean("MyBoolean");
  double myDouble = savedInstanceState.getDouble("myDouble");
  int myInt = savedInstanceState.getInt("MyInt");
  String myString = savedInstanceState.getString("MyString");
}

References
https://stackoverflow.com/questions/151777/saving-android-activity-state-using-save-instance-state

Android Notification with Sound and Vibratation

            Notification.Builder builder = new Notification.Builder(this)
                    .setContentTitle("مانیتورینگ")
                    .setContentText(content)
                    .setSmallIcon(R.drawable.ic_monitoring)
                    .setContentIntent(pIntent)
                    .setOngoing(true);
            //.setPriority(Notification.PRIORITY_MAX)

            if (count > 0) {
                builder.setSound(alarmSound);
                builder.setOnlyAlertOnce(true);
                builder.setLights(Color.RED, 500, 500);
                // 0 : Start without a delay
                // 400 : Vibrate for 400 milliseconds
                // 200 : Pause for 200 milliseconds
                // 400 : Vibrate for 400 milliseconds
                long[] pattern = new long[]{0, 400, 200, 400};
                builder.setVibrate(pattern);
            }

            Notification notification = builder.build();

References
https://stackoverflow.com/questions/15809399/android-notification-sound
https://gist.github.com/nieldeokar/e05fffe4d639dfabf0d57e96cb8055e2

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

Create a Permanent Notification on Android

On your notification builder use .setOngoing(True) and this will prevent the user from removing your notification.

and

n.flags |= Notification.FLAG_NO_CLEAR;

We can assign the notification to a service and start it as foreground

startForeground(101,notification);

References
https://stackoverflow.com/questions/22555943/android-how-to-create-a-permanent-notification
https://questdot.com/android-foreground-service/

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
        }
    });

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

Check if service is running on Android

private boolean isMyServiceRunning(Class<?> serviceClass) {
  ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
  for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
    if (serviceClass.getName().equals(service.service.getClassName())) {
        return true;
    }
  }
  return false;
}

References
https://stackoverflow.com/questions/17588910/check-if-service-is-running-on-android

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