Java Modbus Client

Modbus TCP Client Example

public class run {
	public static void main(String[] args)
	{
		ModbusClient modbusClient = new ModbusClient("127.0.0.1",502);
		try
		{
			modbusClient.Connect();
			modbusClient.WriteSingleCoil(0, true);
			modbusClient.WriteSingleRegister(0, 1234);
			modbusClient.WriteMultipleRegisters(11, ModbusClient.ConvertFloatToTwoRegisters((float) 123.56));
			System.out.println(modbusClient.ReadCoils(0, 1)[0]);
			System.out.println(modbusClient.ReadHoldingRegisters(0, 1)[0]);
			System.out.println(ModbusClient.ConvertRegistersToFloat(modbusClient.ReadHoldingRegisters(11, 2)));
		}
		catch (Exception e)
		{		
		}	
	}
}

Read an Write 32 Bit Values

    public static void main(String[] args) 
    {
        ModbusClient modbusClient = new ModbusClient("127.0.0.1", 1536);
        try
        {
            modbusClient.Connect();
            //Write Float value to Register 10 and 11
            modbusClient.WriteMultipleRegisters(9, ModbusClient.ConvertFloatToTwoRegisters((float)(1323.55)));
            //Write 32 bit value to Register 12 and 13
            modbusClient.WriteMultipleRegisters(11, ModbusClient.ConvertDoubleToTwoRegisters((1323554)));
            //Read Float Value from Register 10 and 11
            System.out.println(ModbusClient.ConvertRegistersToFloat(modbusClient.ReadHoldingRegisters(9, 2)));
            //Read 32 Bit Value from Register 12 and 13
            System.out.println(ModbusClient.ConvertRegistersToDouble(modbusClient.ReadHoldingRegisters(11, 2)));
        }
        catch (Exception e)
        {
        System.out.println(e.toString());
        }   
    }

References
https://www.youtube.com/user/emileackbarali/videos
https://www.udemy.com/the-1-hour-modbus-rs485-primer/
https://www.rtaautomation.com/technologies/modbus-rtu/
http://easymodbustcp.net/java-modbus-tcp-client-example
http://easymodbustcp.net/java-read-an-write-32-bit-values
https://en.wikipedia.org/wiki/Modbus

Badge for TabLayout using setCustomView

layout/tab_header_badge.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/relativeLayoutTabHeader"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/imageViewTabHeader"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_bell" />

    <TextView
        android:id="@+id/textViewActiveAlarmBadge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toEndOf="@+id/imageViewTabHeader"
        android:text="1"
        android:textColor="@color/accent" />

</RelativeLayout>
            viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());

            viewPagerAdapter.addFragment(moreFragment); // 3
            viewPagerAdapter.addFragment(alarmHistoryFragment); // 2
            viewPagerAdapter.addFragment(activeAlarmsFragment); // 1
            viewPagerAdapter.addFragment(mainFragment); // 0


            viewPagerMain.setAdapter(viewPagerAdapter);
            viewPagerMain.setCurrentItem(3); // set default view on open
            tabLayoutMain.setupWithViewPager(viewPagerMain);

            tabLayoutMain.getTabAt(3).setIcon(R.drawable.ic_home);
            //tabLayoutMain.getTabAt(2).setIcon(R.drawable.ic_bell);
            tabLayoutMain.getTabAt(1).setIcon(R.drawable.ic_envelope_open);
            tabLayoutMain.getTabAt(0).setIcon(R.drawable.ic_bars);


            View tabHeader = LayoutInflater.from(this).inflate(R.layout.tab_header_badge, null);
            TextView textViewBadge = tabHeader.findViewById(R.id.textViewActiveAlarmBadge);
            textViewBadge.setText("10");
            tabLayoutMain.getTabAt(2).setCustomView(tabHeader);

            // endregion

References
https://mobikul.com/make-custom-tabs-icons-android/
https://stackoverflow.com/questions/41530141/how-to-show-notification-counter-in-a-tablayout
https://stackoverflow.com/questions/43266079/how-to-add-badge-to-android-tablayout

Tablayout with Icons on Android

mTabLayout.setupWithViewPager(mViewPager);
for (int i = 0; i < mTabLayout.getTabCount(); i++) {
  mTabLayout.getTabAt(i).setIcon(R.drawable.your_icon);
}

or

<android.support.design.widget.TabLayout
         app:tabTextColor="@color/gray"
         app:tabMode="fixed"
         app:tabBackground="@color/red"
         app:tabIndicatorHeight="4dp"
         app:tabIndicatorColor="@color/purple"
         app:tabPadding="2dp"
         app:tabSelectedTextColor="@color/white"
         app:tabMinWidth="64dp"
         android:layout_height="wrap_content"
         android:layout_width="match_parent">

     <!--add height and width to TabItem -->
     <android.support.design.widget.TabItem 
             android:text="@string/tab_text"/>

     <android.support.design.widget.TabItem
             android:icon="@drawable/ic_android"/>

 </android.support.design.widget.TabLayout>

References
https://stackoverflow.com/questions/30892545/tablayout-with-icons-only

How the activity should be launched with android:launchMode

Use Cases Launch Mode Multiple Instances? Comments
Normal launches for most activities standard Yes Default. The system always creates a new instance of the activity in the target task and routes the intent to it.
singleTop Conditionally If an instance of the activity already exists at the top of the target task, the system routes the intent to that instance through a call to its onNewIntent() method, rather than creating a new instance of the activity.
Specialized launches
(not recommended for general use)
singleTask No The system creates the activity at the root of a new task and routes the intent to it. However, if an instance of the activity already exists, the system routes the intent to existing instance through a call to its onNewIntent()method, rather than creating a new one.
singleInstance No Same as “singleTask", except that the system doesn’t launch any other activities into the task holding the instance. The activity is always the single and only member of its task.

References
https://developer.android.com/guide/topics/manifest/activity-element#lmode

Check Google Play Services Availability on Android

It should be called on onResume:

    /**
     * A utility method to validate that the appropriate version of the Google Play Services is
     * available on the device. If not, it will open a dialog to address the issue. The dialog
     * displays a localized message about the error and upon user confirmation (by tapping on
     * dialog) will direct them to the Play Store if Google Play services is out of date or
     * missing, or to system settings if Google Play services is disabled on the device.
     */
    public static boolean checkGooglePlayServices(final Activity activity) {
        final int googlePlayServicesCheck = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
                activity);
        switch (googlePlayServicesCheck) {
            case ConnectionResult.SUCCESS:
                return true;
            default:

                Dialog dialog = GoogleApiAvailability.getInstance().getErrorDialog(activity, googlePlayServicesCheck, 0);
                dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        activity.finish();
                    }
                });

                dialog.show();
        }
        return false;
    }

References
https://www.programcreek.com/java-api-examples/?api=com.google.android.gms.common.GoogleApiAvailability

Interprocess Communication between Activity and Service using Messenger on Android

MyService

public class MyService extends Service {

    private final int JOB1 = 1;
    private final int JOB1Response = 2;
    private final int JOB2 = 3;
    private final int JOB2Response = 4;
    Messenger messenger = new Messenger(new MyServiceHandler());

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return messenger.getBinder();
    }


    class MyServiceHandler extends Handler {

        Message MSG;
        String message;
        Bundle bundle = new Bundle();

        @Override
        public void handleMessage(Message msg) {

            try {

                switch (msg.what) {
                    case JOB1:

                        message = "This is the first message from service";
                        MSG = Message.obtain(null, JOB1Response);
                        bundle.putString("responseMessage", message);
                        MSG.setData(bundle);
                        msg.replyTo.send(MSG);

                        break;

                    case JOB2:

                        message = "This is the second message from service";
                        MSG = Message.obtain(null, JOB2Response);
                        bundle.putString("responseMessage", message);
                        MSG.setData(bundle);
                        msg.replyTo.send(MSG);

                        break;

                    default:
                        super.handleMessage(msg);
                }

            } catch (Exception ex) {
                ex.printStackTrace();
            }

        }
    }
}

MainActivity

public class MainActivity extends AppCompatActivity {

    private final int JOB1 = 1;
    private final int JOB1Response = 2;
    private final int JOB2 = 3;
    private final int JOB2Response = 4;
    Messenger messenger = null;
    boolean isBound = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Intent intent = new Intent(this, MyService.class);
        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
    }


    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            messenger = new Messenger(service);
            isBound = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            messenger = null;
            isBound = false;
        }
    };

    // JOB1
    private void sendMessage1() {
        try {
            if (isBound){
                  Message msg = Message.obtain(null, JOB1);
                  msg.replyTo = new Messenger(new MainActivityHandler());
                  messenger.send(msg);
            }
           
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    // JOB2
    private void sendMessage2() {
        try {
            if (isBound){
                  Message msg = Message.obtain(null, JOB2);
                  msg.replyTo = new Messenger(new MainActivityHandler());
                  messenger.send(msg);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private void LogMessage1(String msg)
    {
        Log.d("MSG",msg);
    }

    @Override
    protected void onStop() {

        unbindService(serviceConnection);
        isBound = false;
        messenger = null;

        super.onStop();
    }

    class MainActivityHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {

            String message;

            switch (msg.what) {
                case JOB1Response:
                    message = msg.getData().getString("responseMessage");

                    // do something here

                    LogMessage1(message);

                    break;
                case JOB2Response:
                    message = msg.getData().getString("responseMessage");

                    // do something here
                    break;
                default:
                    super.handleMessage(msg);
            }


        }
    }
}

AndroidManifest.xml

<service android:name=".MyService" android:process=":remote"/>

References
https://www.youtube.com/watch?v=yAmnirP0d4U&t=0s&list=PLshdtb5UWjSp0879mLeCsDQN6L73XBZTk
https://developer.android.com/guide/components/bound-services