├── .gitattributes ├── .gitignore ├── README.md ├── apk ├── app-debug-unaligned.apk └── app-debug.apk ├── app ├── .gitignore ├── app.iml ├── build.gradle ├── libs │ ├── modbus4J.jar │ └── seroUtils.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── example │ │ └── administrator │ │ └── modbustcp │ │ ├── Interface │ │ └── ResultListener.java │ │ ├── activity │ │ ├── MainActivity.java │ │ └── TestActivity.java │ │ ├── fragment │ │ ├── Fragment_Setting.java │ │ └── ReadWriteFragment.java │ │ ├── modbus │ │ ├── Coil_Status.java │ │ ├── Holding_Register.java │ │ ├── Input_Registers.java │ │ └── Input_Status.java │ │ ├── model │ │ └── DataModel.java │ │ ├── service │ │ └── ReadService.java │ │ └── utils │ │ ├── ByteHex.java │ │ ├── CustomDialog.java │ │ ├── LogUtils.java │ │ ├── StatusBarCompat.java │ │ └── ToastUtil.java │ └── res │ ├── drawable-xhdpi │ ├── quanbu.png │ ├── quanbu2.png │ ├── shezhi.png │ ├── shezhi2.png │ ├── zaidu.png │ └── zaidu2.png │ ├── drawable │ ├── attribute_tab.xml │ ├── bg_edittext.xml │ ├── bg_edittext_focused.xml │ ├── bg_edittext_normal.xml │ ├── bottom_text.xml │ ├── read_tab.xml │ └── setting_tab.xml │ ├── layout │ ├── activity_main.xml │ ├── custom_dialog.xml │ ├── edit_item.xml │ ├── fragment_read.xml │ ├── fragment_setting.xml │ ├── item_recycler_view.xml │ ├── radio_group_item.xml │ ├── spinner_item.xml │ ├── tab_item.xml │ └── toolbar_item.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml └── image ├── 1.png ├── 2.png └── 3.png /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ModbusTCP 2 | 基于TCP的Modbus可读写的Android客户端 3 | 系统: 4.1.2-6.0 4 | GitHub 5 | GitHub 6 | GitHub 7 | 8 | ****** 9 | # About Me 10 |   **博客: www.idtkm.com**
11 |   **GitHub: https://github.com/Idtk**
12 |   **微博: http://weibo.com/Idtk**
13 |   **邮箱: IdtkMa@gmail.com**
14 | -------------------------------------------------------------------------------- /apk/app-debug-unaligned.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Idtk/ModbusTCP/8e35b06f17278742fee827530e961af882185ed0/apk/app-debug-unaligned.apk -------------------------------------------------------------------------------- /apk/app-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Idtk/ModbusTCP/8e35b06f17278742fee827530e961af882185ed0/apk/app-debug.apk -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/app.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 8 | 9 | 10 | 11 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.example.administrator.modbustcp" 9 | minSdkVersion 16 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.1.1' 26 | compile 'com.android.support:support-v4:23.1.1' 27 | compile 'com.android.support:design:23.1.1' 28 | compile 'com.android.support:recyclerview-v7:23.1.1' 29 | compile files('libs/seroUtils.jar') 30 | compile files('libs/modbus4J.jar') 31 | compile files('libs/RXTXcomm.jar') 32 | } 33 | -------------------------------------------------------------------------------- /app/libs/modbus4J.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Idtk/ModbusTCP/8e35b06f17278742fee827530e961af882185ed0/app/libs/modbus4J.jar -------------------------------------------------------------------------------- /app/libs/seroUtils.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Idtk/ModbusTCP/8e35b06f17278742fee827530e961af882185ed0/app/libs/seroUtils.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/Interface/ResultListener.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.Interface; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * Created by DoBest on 2016/4/1. 7 | */ 8 | public interface ResultListener { 9 | public ArrayList result(ArrayList dataList,String ip, int port, int slaveId, 10 | int start, int type); 11 | public void onToast(String msg); 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.design.widget.TabLayout; 5 | import android.support.v4.app.FragmentTransaction; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.widget.ImageView; 10 | import android.widget.TextView; 11 | 12 | import com.example.administrator.modbustcp.R; 13 | import com.example.administrator.modbustcp.fragment.Fragment_Setting; 14 | import com.example.administrator.modbustcp.fragment.ReadWriteFragment; 15 | import com.example.administrator.modbustcp.utils.StatusBarCompat; 16 | 17 | 18 | public class MainActivity extends AppCompatActivity { 19 | 20 | private TabLayout tabLayout; 21 | private Fragment_Setting fragment_setting; 22 | private ReadWriteFragment readWriteFragment; 23 | private String[] bottomTitles = {"设置","读写","关于"}; 24 | private int[] bottomDrawable = {R.drawable.setting_tab, R.drawable.read_tab, 25 | R.drawable.attribute_tab}; 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState){ 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_main); 31 | //设置状态栏颜色 32 | StatusBarCompat.compat(this, getResources().getColor(R.color.white)); 33 | initView(); 34 | } 35 | 36 | private void initView(){ 37 | tabLayout = (TabLayout) findViewById(R.id.main_tabs); 38 | 39 | View view1= LayoutInflater.from(this).inflate(R.layout.tab_item,null); 40 | ImageView imageView1 = (ImageView) view1.findViewById(R.id.tab_imageView); 41 | TextView textView1 = (TextView) view1.findViewById(R.id.tab_textView); 42 | imageView1.setImageResource(bottomDrawable[0]); 43 | textView1.setText(bottomTitles[0]); 44 | tabLayout.addTab(tabLayout.newTab().setCustomView(view1), 0); 45 | 46 | View view2= LayoutInflater.from(this).inflate(R.layout.tab_item,null); 47 | ImageView imageView2 = (ImageView) view2.findViewById(R.id.tab_imageView); 48 | TextView textView2 = (TextView) view2.findViewById(R.id.tab_textView); 49 | imageView2.setImageResource(bottomDrawable[1]); 50 | textView2.setText(bottomTitles[1]); 51 | tabLayout.addTab(tabLayout.newTab().setCustomView(view2), 1); 52 | 53 | tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 54 | @Override 55 | public void onTabSelected(TabLayout.Tab tab) { 56 | FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction(); 57 | hideFragment(fragmentTransaction); 58 | switch (tab.getPosition()) { 59 | case 0: 60 | if (fragment_setting == null) { 61 | fragment_setting = new Fragment_Setting(); 62 | fragmentTransaction.add(R.id.main_fragment, fragment_setting); 63 | } else { 64 | fragmentTransaction.show(fragment_setting); 65 | } 66 | break; 67 | case 1: 68 | if (readWriteFragment==null){ 69 | readWriteFragment= ReadWriteFragment.getInstance(true,getApplicationContext()); 70 | fragmentTransaction.add(R.id.main_fragment,readWriteFragment); 71 | }else 72 | { 73 | fragmentTransaction.show(readWriteFragment); 74 | } 75 | break; 76 | } 77 | fragmentTransaction.commit();//提交事务 78 | } 79 | 80 | @Override 81 | public void onTabUnselected(TabLayout.Tab tab) { 82 | 83 | } 84 | 85 | @Override 86 | public void onTabReselected(TabLayout.Tab tab) { 87 | 88 | } 89 | }); 90 | tabLayout.getTabAt(1).select(); 91 | tabLayout.getTabAt(0).select(); 92 | } 93 | 94 | private void hideFragment(FragmentTransaction fragmentTransaction){ 95 | 96 | if (fragment_setting != null){ 97 | fragmentTransaction.hide(fragment_setting); 98 | } 99 | if (readWriteFragment != null){ 100 | fragmentTransaction.hide(readWriteFragment); 101 | } 102 | } 103 | 104 | @Override 105 | public void onBackPressed() { 106 | super.onBackPressed(); 107 | finish(); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/activity/TestActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.activity; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.util.Log; 6 | 7 | import com.example.administrator.modbustcp.Interface.ResultListener; 8 | import com.example.administrator.modbustcp.R; 9 | import com.serotonin.modbus4j.ModbusFactory; 10 | import com.serotonin.modbus4j.ModbusMaster; 11 | import com.serotonin.modbus4j.exception.ModbusInitException; 12 | import com.serotonin.modbus4j.exception.ModbusTransportException; 13 | import com.serotonin.modbus4j.ip.IpParameters; 14 | import com.serotonin.modbus4j.msg.ModbusRequest; 15 | import com.serotonin.modbus4j.msg.ModbusResponse; 16 | import com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest; 17 | import com.serotonin.modbus4j.msg.WriteRegistersRequest; 18 | import com.serotonin.modbus4j.msg.WriteRegistersResponse; 19 | import com.serotonin.util.queue.ByteQueue; 20 | 21 | import java.util.ArrayList; 22 | 23 | 24 | public class TestActivity extends AppCompatActivity implements ResultListener { 25 | 26 | 27 | 28 | @Override 29 | protected void onCreate(Bundle savedInstanceState){ 30 | super.onCreate(savedInstanceState); 31 | setContentView(R.layout.activity_main); 32 | final short[] shorts = new short[2]; 33 | shorts[0]=1; 34 | shorts[1]=2; 35 | final boolean[] values = new boolean[2]; 36 | values[0]=true; 37 | values[1]=true; 38 | // modbusWTCP("192.168.1.200",502,1,100,shorts); 39 | // modbusRTCP("192.168.1.158",502, 100,10); 40 | new Thread(new Runnable() { 41 | @Override 42 | public void run() { 43 | // Coil_Status.coilStatusWrite("192.168.1.158", 502, 1, 100, values); 44 | // Coil_Status.coilStatusRead("192.168.1.158",502,1,100,10,TestActivity.this); 45 | // Input_Status.inputStatusRead("192.168.1.158", 502, 1, 100, 10); 46 | // Holding_Register.holdingRegisterRead("192.168.1.158", 502, 1, 100, 10); 47 | // Holding_Register.holdingRegisterWrite("192.168.1.158", 502, 1, 100, shorts); 48 | // Input_Registers.inputRegisterRead("192.168.1.158", 502, 1, 100, 10); 49 | // Log.e("TAG","==========================="); 50 | } 51 | }).start(); 52 | } 53 | 54 | 55 | 56 | public void modbusWTCP(String ip, int port, int slaveId, int start, short[] values) { 57 | ModbusFactory modbusFactory = new ModbusFactory(); 58 | // 设备ModbusTCP的Ip与端口,如果不设定端口则默认为502 59 | IpParameters params = new IpParameters(); 60 | params.setHost(ip); 61 | if (502 != port) { 62 | params.setPort(port); 63 | }// 设置端口,默认502 64 | ModbusMaster tcpMaster = null; 65 | // 参数1:IP和端口信息 参数2:保持连接激活 66 | tcpMaster = modbusFactory.createTcpMaster(params, true); 67 | try { 68 | tcpMaster.init(); 69 | System.out.println("===============" + 1111111); 70 | } catch (ModbusInitException e) { 71 | System.out.println("11111111111111==" + "此处出现问题了啊!"); 72 | // 如果出现了通信异常信息,则保存到数据库中 73 | // CommunityExceptionRecord cer = new CommunityExceptionRecord(); 74 | // cer.setDate(new Date()); 75 | //cer.setIp(ip); 76 | // cer.setRemark(bgName+"出现连接异常"); 77 | // batteryGroupRecordService.saveCommunityException(cer); 78 | } 79 | try { 80 | WriteRegistersRequest request = new WriteRegistersRequest(slaveId, start, values); 81 | WriteRegistersResponse response = (WriteRegistersResponse) tcpMaster.send(request); 82 | if (response.isException()) 83 | System.out.println("Exception response: message=" + response.getExceptionMessage()); 84 | else 85 | System.out.println("Success"); 86 | } catch (ModbusTransportException e) { 87 | e.printStackTrace(); 88 | } 89 | finally { 90 | tcpMaster.destroy(); 91 | } 92 | } 93 | 94 | public ByteQueue modbusRTCP(String ip, int port, int start,int readLenth) { 95 | ModbusFactory modbusFactory = new ModbusFactory(); 96 | // 设备ModbusTCP的Ip与端口,如果不设定端口则默认为502 97 | IpParameters params = new IpParameters(); 98 | params.setHost(ip); 99 | if(502!=port){params.setPort(port);}//设置端口,默认502 100 | ModbusMaster tcpMaster = null; 101 | tcpMaster = modbusFactory.createTcpMaster(params, true); 102 | try { 103 | tcpMaster.init(); 104 | System.out.println("==============="+1111111); 105 | } catch (ModbusInitException e) { 106 | Log.e("TAG",e.getMessage()); 107 | return null; 108 | } 109 | ModbusRequest modbusRequest=null; 110 | try { 111 | modbusRequest = new ReadHoldingRegistersRequest(1, start, readLenth);//功能码03 112 | } catch (ModbusTransportException e) { 113 | Log.e("TAG","2"); 114 | e.printStackTrace(); 115 | } 116 | ModbusResponse modbusResponse=null; 117 | try { 118 | modbusResponse = tcpMaster.send(modbusRequest); 119 | } catch (ModbusTransportException e) { 120 | Log.e("TAG","3"); 121 | e.printStackTrace(); 122 | } 123 | ByteQueue byteQueue= new ByteQueue(12); 124 | modbusResponse.write(byteQueue); 125 | Log.e("TAG", "功能码:" + modbusRequest.getFunctionCode()); 126 | Log.e("TAG","从站地址:"+modbusRequest.getSlaveId()); 127 | Log.e("TAG","收到的响应信息大小:"+byteQueue.size()); 128 | Log.e("TAG", "收到的响应信息值:" + byteQueue); 129 | Log.e("TAG", "收到的数值:" + modbusResponse.getExceptionCode()); 130 | Log.e("TAG", "收到的数值:" + modbusResponse.getExceptionMessage()); 131 | Log.e("TAG", "收到的数值:" + modbusResponse.getFunctionCode()); 132 | Log.e("TAG", "收到的数值:" + byteQueue.pop()); 133 | return byteQueue; 134 | } 135 | 136 | @Override 137 | public ArrayList result(ArrayList dataList, String ip, int port, int slaveId, int start, int type) { 138 | return null; 139 | } 140 | 141 | @Override 142 | public void onToast(String msg) { 143 | 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/fragment/Fragment_Setting.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.fragment; 2 | 3 | 4 | import android.os.Bundle; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v7.widget.Toolbar; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.AdapterView; 11 | import android.widget.ArrayAdapter; 12 | import android.widget.EditText; 13 | import android.widget.LinearLayout; 14 | import android.widget.Spinner; 15 | import android.widget.TextView; 16 | 17 | import com.example.administrator.modbustcp.R; 18 | 19 | 20 | /** 21 | * Created by DoBest on 2016/3/30. 22 | */ 23 | public class Fragment_Setting extends Fragment { 24 | 25 | private View view; 26 | private Toolbar toolbar_setting; 27 | private TextView title_text; 28 | 29 | private LinearLayout read_ip; 30 | private TextView read_ip_text; 31 | private static EditText read_ip_edit; 32 | 33 | private LinearLayout read_port; 34 | private TextView read_port_text; 35 | private static EditText read_port_edit; 36 | 37 | private LinearLayout read_slaveId; 38 | private TextView read_slaveId_text; 39 | private static EditText read_slaveId_edit; 40 | 41 | private LinearLayout read_start; 42 | private TextView read_start_text; 43 | private static EditText read_start_edit; 44 | 45 | private LinearLayout read_length; 46 | private TextView read_length_text; 47 | private static EditText read_length_edit; 48 | 49 | private Spinner function_spinner; 50 | // private static TextView spinner_text; 51 | 52 | private static int type=3; 53 | private static final String[] spinner_string={"01 Coil Status [0x]","02 Input Status [1x]", 54 | "03 Holding Register [4x]","04 Input Registers [3x]"}; 55 | private ArrayAdapter adapter; 56 | 57 | @Override 58 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 59 | Bundle savedInstanceState) { 60 | initView(container); 61 | return view; 62 | } 63 | 64 | private void initView(ViewGroup container){ 65 | view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_setting,container,false); 66 | 67 | toolbar_setting = (Toolbar)view.findViewById(R.id.toolbar_setting); 68 | title_text = (TextView)toolbar_setting.findViewById(R.id.text_title); 69 | 70 | read_ip = (LinearLayout)view.findViewById(R.id.read_ip); 71 | read_ip_text = (TextView)read_ip.findViewById(R.id.textView); 72 | read_ip_edit = (EditText)read_ip.findViewById(R.id.editText); 73 | 74 | read_port = (LinearLayout)view.findViewById(R.id.read_port); 75 | read_port_text = (TextView)read_port.findViewById(R.id.textView); 76 | read_port_edit = (EditText)read_port.findViewById(R.id.editText); 77 | 78 | read_slaveId = (LinearLayout)view.findViewById(R.id.read_slaveId); 79 | read_slaveId_text = (TextView)read_slaveId.findViewById(R.id.textView); 80 | read_slaveId_edit = (EditText)read_slaveId.findViewById(R.id.editText); 81 | 82 | read_start = (LinearLayout)view.findViewById(R.id.read_start); 83 | read_start_text = (TextView)read_start.findViewById(R.id.textView); 84 | read_start_edit = (EditText)read_start.findViewById(R.id.editText); 85 | 86 | read_length = (LinearLayout)view.findViewById(R.id.read_length); 87 | read_length_text = (TextView)read_length.findViewById(R.id.textView); 88 | read_length_edit = (EditText)read_length.findViewById(R.id.editText); 89 | 90 | function_spinner = (Spinner)view.findViewById(R.id.function_spinner); 91 | // spinner_text = (TextView)function_spinner.findViewById(R.id.spinner_text); 92 | 93 | settingView(); 94 | } 95 | 96 | private void settingView(){ 97 | 98 | title_text.setText("设置"); 99 | 100 | read_ip_text.setText("IP地址/IP"); 101 | read_ip_edit.setText("192.168.1.100"); 102 | 103 | read_port_text.setText("端口号/Port"); 104 | read_port_edit.setText("502"); 105 | 106 | read_slaveId_text.setText("客户端ID/SlaveId"); 107 | read_slaveId_edit.setText("1"); 108 | 109 | read_start_text.setText("设备地址/Addr"); 110 | read_start_edit.setText("100"); 111 | 112 | read_length_text.setText("字节长度/Bytes"); 113 | read_length_edit.setText("1"); 114 | 115 | adapter = new ArrayAdapter(getActivity(), R.layout.spinner_item,spinner_string); 116 | function_spinner.setAdapter(adapter); 117 | 118 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 119 | function_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 120 | @Override 121 | public void onItemSelected(AdapterView parent, View view, int position, long id) { 122 | type = position + 1; 123 | // Toast.makeText(getActivity(),type+"",Toast.LENGTH_SHORT).show(); 124 | } 125 | 126 | @Override 127 | public void onNothingSelected(AdapterView parent) { 128 | 129 | } 130 | }); 131 | function_spinner.setSelection(2); 132 | } 133 | 134 | public static String getRead_ip_value() { 135 | return read_ip_edit.getText().toString(); 136 | } 137 | 138 | public static int getRead_port_value() { 139 | return Integer.parseInt(read_port_edit.getText().toString()); 140 | } 141 | 142 | public static int getRead_slaveId_value(){ 143 | return Integer.parseInt(read_slaveId_edit.getText().toString()); 144 | } 145 | 146 | public static int getRead_start_value(){ 147 | return Integer.parseInt(read_start_edit.getText().toString()); 148 | } 149 | 150 | public static int getRead_length_value(){ 151 | return Integer.parseInt(read_length_edit.getText().toString()); 152 | } 153 | 154 | public static int getFunction_type(){ 155 | return type; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/fragment/ReadWriteFragment.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.fragment; 2 | 3 | 4 | import android.content.ComponentName; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.content.ServiceConnection; 8 | import android.os.Bundle; 9 | import android.os.Handler; 10 | import android.os.IBinder; 11 | import android.os.Message; 12 | import android.support.v4.app.Fragment; 13 | import android.support.v7.widget.LinearLayoutManager; 14 | import android.support.v7.widget.RecyclerView; 15 | import android.support.v7.widget.Toolbar; 16 | import android.util.Log; 17 | import android.view.LayoutInflater; 18 | import android.view.View; 19 | import android.view.ViewGroup; 20 | import android.widget.Button; 21 | import android.widget.TextView; 22 | import android.widget.Toast; 23 | 24 | import com.example.administrator.modbustcp.Interface.ResultListener; 25 | import com.example.administrator.modbustcp.R; 26 | import com.example.administrator.modbustcp.model.DataModel; 27 | import com.example.administrator.modbustcp.service.ReadService; 28 | import com.example.administrator.modbustcp.utils.CustomDialog; 29 | import com.example.administrator.modbustcp.utils.LogUtils; 30 | import com.example.administrator.modbustcp.utils.ToastUtil; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | 36 | /** 37 | * Created by DongBang on 2016/3/31. 38 | */ 39 | public class ReadWriteFragment extends Fragment implements ResultListener,View.OnClickListener{ 40 | 41 | private static boolean isTest; 42 | private static Context context; 43 | private RecyclerView recyclerView; 44 | private String TAG =ReadWriteFragment.this.getClass().getSimpleName(); 45 | private View rootView; 46 | private Toolbar toolbar; 47 | private TextView textView; 48 | private Button buttonConnect; 49 | private Button buttonDisconnect; 50 | private ArrayList data = new ArrayList<>(); 51 | private MyAdapter mAdapter = null; 52 | 53 | private String ip; 54 | private int port; 55 | private int slaveId; 56 | private int start; 57 | private int length; 58 | private int type; 59 | 60 | private int UPDATE = 1; 61 | private int TOAST = 2; 62 | private int flag = 0; 63 | private Intent intentService; 64 | private ReadService.ServiceBinder mServiceBinder = null; 65 | private ServiceConnection readConnection = new ServiceConnection() { 66 | @Override 67 | public void onServiceConnected(ComponentName name, IBinder service) { 68 | mServiceBinder = (ReadService.ServiceBinder)service; 69 | try{ 70 | ((ReadService.ServiceBinder) service).setData(ReadWriteFragment.this); 71 | }catch (Exception e){ 72 | e.printStackTrace(); 73 | } 74 | } 75 | 76 | @Override 77 | public void onServiceDisconnected(ComponentName name) { 78 | 79 | } 80 | }; 81 | 82 | static class MyHandler extends Handler{ 83 | ReadWriteFragment handlerReadWriteFragment; 84 | MyHandler(ReadWriteFragment readWriteFragment){ 85 | handlerReadWriteFragment = readWriteFragment; 86 | } 87 | 88 | @Override 89 | public void handleMessage(Message msg) { 90 | super.handleMessage(msg); 91 | if (handlerReadWriteFragment != null){ 92 | switch (msg.what){ 93 | case 2: 94 | ToastUtil.showToast(ReadWriteFragment.context, msg.obj.toString(), Toast.LENGTH_SHORT); 95 | break; 96 | } 97 | } 98 | } 99 | } 100 | 101 | MyHandler handler = new MyHandler(this); 102 | 103 | public static ReadWriteFragment getInstance(boolean isTest ,Context context) 104 | { 105 | ReadWriteFragment instance=new ReadWriteFragment(); 106 | instance.isTest=isTest; 107 | instance.context=context; 108 | return instance; 109 | } 110 | 111 | @Override 112 | public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 113 | 114 | rootView=inflater.inflate(R.layout.fragment_read,container,false); 115 | intentService = new Intent(getActivity(), ReadService.class); 116 | toolbar = (Toolbar) rootView.findViewById(R.id.toolbar_read); 117 | recyclerView = (RecyclerView) rootView.findViewById(R.id.read_view_recycler); 118 | textView = (TextView) toolbar.findViewById(R.id.text_title); 119 | buttonConnect = (Button) toolbar.findViewById(R.id.connect); 120 | buttonDisconnect = (Button) toolbar.findViewById(R.id.disconnect); 121 | initToolbar(); 122 | initRecyclerView(recyclerView); 123 | // setStartService(); 124 | return rootView; 125 | } 126 | 127 | private void initToolbar(){ 128 | textView.setText("读取数据"); 129 | buttonConnect.setOnClickListener(this); 130 | buttonDisconnect.setOnClickListener(this); 131 | } 132 | private void initRecyclerView(RecyclerView recyclerView) { 133 | recyclerView.setHasFixedSize(true); // 设置固定大小 134 | initRecyclerLayoutManager(recyclerView); // 初始化布局 135 | initRecyclerAdapter(recyclerView); // 初始化适配器 136 | } 137 | 138 | private void initRecyclerAdapter(RecyclerView recyclerView0) 139 | { 140 | mAdapter = new MyAdapter(data); 141 | recyclerView.setAdapter(mAdapter); 142 | } 143 | 144 | 145 | private void initRecyclerLayoutManager(RecyclerView recyclerView) 146 | { 147 | recyclerView.setLayoutManager(new LinearLayoutManager(getActivity())); 148 | } 149 | 150 | public class MyAdapter extends RecyclerView.Adapter { 151 | 152 | private List mDataModels; 153 | private List mHeights; 154 | 155 | MyAdapter(List dataModels) { 156 | if (dataModels == null) { 157 | throw new IllegalArgumentException("DataModel must not be null"); 158 | } 159 | mDataModels = dataModels; 160 | mHeights = new ArrayList<>(); 161 | } 162 | 163 | @Override 164 | public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 165 | View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_recycler_view, parent, false); 166 | return new MyViewHolder(itemView); 167 | } 168 | 169 | @Override 170 | public void onBindViewHolder(final MyViewHolder holder, final int position) { 171 | DataModel dataModel = mDataModels.get(position); 172 | if (holder.mTvValue==null) 173 | { 174 | LogUtils.d(TAG,"onBindViewHolder mTvAlise 为空"); 175 | } 176 | holder.mTvAlise.setText(dataModel.getAlise()); 177 | holder.mTvValue.setText(dataModel.getValue()+""); 178 | holder.itemView.setOnClickListener(new View.OnClickListener() { 179 | @Override 180 | public void onClick(View v) { 181 | Log.e("TAG5", position + ""); 182 | if (position>0){ 183 | CustomDialog dialog = new CustomDialog(getActivity(),R.style.dialog,ip,port, 184 | slaveId, start+position-1,holder.mTvValue.getText().toString(),type); 185 | dialog.show(); 186 | } 187 | } 188 | }); 189 | } 190 | 191 | @Override 192 | public int getItemCount() { 193 | return mDataModels.size(); 194 | } 195 | 196 | public void removeData(int position) { 197 | mDataModels.remove(position); 198 | notifyItemRemoved(position); 199 | } 200 | } 201 | 202 | /** 203 | * ViewHolder 204 | */ 205 | public class MyViewHolder extends RecyclerView.ViewHolder { 206 | 207 | private TextView mTvAlise; // 别名 208 | private TextView mTvValue; //值 209 | 210 | public MyViewHolder(View itemView) { 211 | super(itemView); 212 | mTvAlise = (TextView) itemView.findViewById(R.id.item_alise); 213 | mTvValue = (TextView) itemView.findViewById(R.id.item_value); 214 | } 215 | 216 | public TextView getTvAlise() { 217 | return mTvAlise; 218 | } 219 | 220 | public TextView getTvValue() { 221 | return mTvValue; 222 | } 223 | 224 | } 225 | 226 | @Override 227 | public ArrayList result(ArrayList dataList,String ip, int port, int slaveId, 228 | int start, int type) { 229 | Log.e("回调", dataList.toString()); 230 | this.ip = ip; 231 | this.port = port; 232 | this.slaveId = slaveId; 233 | this.start = start; 234 | this.type = type; 235 | data.clear(); 236 | DataModel modelTitle = new DataModel(); 237 | modelTitle.setAlise("地址/Addr"); 238 | modelTitle.setValue("值/Value"); 239 | data.add(modelTitle); 240 | for (int i = 0; i < dataList.size(); i++) { 241 | DataModel model = new DataModel(); 242 | int count = start + i; 243 | model.setAlise(count + ""); 244 | model.setValue(dataList.get(i)); 245 | data.add(model); 246 | } 247 | //给handler发送消息 248 | getActivity().runOnUiThread(new Runnable() { 249 | @Override 250 | public void run() { 251 | mAdapter.notifyDataSetChanged(); 252 | } 253 | }); 254 | return dataList; 255 | } 256 | 257 | @Override 258 | public void onToast(String string) { 259 | // Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show(); 260 | //给handler发送消息 261 | Message msg = new Message(); 262 | msg.what = TOAST; 263 | msg.obj = string; 264 | handler.sendMessage(msg); 265 | if (flag == 1){ 266 | flag = 0; 267 | getActivity().unbindService(readConnection); 268 | } 269 | } 270 | 271 | @Override 272 | public void onClick(View v) { 273 | switch (v.getId()){ 274 | case R.id.connect: 275 | Log.e("TAG","连接1"); 276 | if (flag == 0){ 277 | flag = 1; 278 | Log.e("TAG","连接2"); 279 | getActivity().bindService(intentService, readConnection, Context.BIND_AUTO_CREATE); 280 | }else { 281 | ToastUtil.showToast(getActivity(), "请先断开连接", Toast.LENGTH_SHORT); 282 | } 283 | break; 284 | case R.id.disconnect: 285 | Log.e("TAG","断开1"); 286 | if (flag == 1) { 287 | flag = 0; 288 | Log.e("TAG","断开2"); 289 | getActivity().unbindService(readConnection); 290 | }else { 291 | ToastUtil.showToast(getActivity(), "连接已断开", Toast.LENGTH_SHORT); 292 | } 293 | break; 294 | 295 | 296 | } 297 | } 298 | 299 | @Override 300 | public void onDestroy() { 301 | if (flag == 1){ 302 | flag = 0; 303 | getActivity().unbindService(readConnection); 304 | } 305 | super.onDestroy(); 306 | } 307 | } 308 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/modbus/Coil_Status.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.modbus; 2 | 3 | import android.util.Log; 4 | 5 | import com.example.administrator.modbustcp.Interface.ResultListener; 6 | import com.example.administrator.modbustcp.utils.ByteHex; 7 | import com.serotonin.modbus4j.ModbusFactory; 8 | import com.serotonin.modbus4j.ModbusMaster; 9 | import com.serotonin.modbus4j.exception.ModbusInitException; 10 | import com.serotonin.modbus4j.exception.ModbusTransportException; 11 | import com.serotonin.modbus4j.ip.IpParameters; 12 | import com.serotonin.modbus4j.msg.ReadCoilsRequest; 13 | import com.serotonin.modbus4j.msg.ReadCoilsResponse; 14 | import com.serotonin.modbus4j.msg.WriteCoilRequest; 15 | import com.serotonin.modbus4j.msg.WriteCoilResponse; 16 | import com.serotonin.modbus4j.msg.WriteCoilsRequest; 17 | import com.serotonin.modbus4j.msg.WriteCoilsResponse; 18 | import com.serotonin.util.queue.ByteQueue; 19 | 20 | /** 21 | * Created by DoBest on 2016/3/28. 22 | */ 23 | public class Coil_Status { 24 | 25 | private static int countRead = 0; 26 | private static int countWrite = 0; 27 | public static void coilStatusRead(String ip, int port,int slaveId, int start,int len,ResultListener resultListener){ 28 | IpParameters params = new IpParameters(); 29 | params.setHost(ip);//地址 30 | params.setPort(port);//端口 31 | ModbusFactory factory = new ModbusFactory(); 32 | ModbusMaster master = factory.createTcpMaster(params, true); 33 | 34 | // 初始化 35 | try { 36 | master.init(); 37 | readCoilStatus(master, ip, port, slaveId, start, len, resultListener); 38 | } catch (ModbusInitException e) { 39 | e.printStackTrace(); 40 | if (countRead<3){ 41 | countRead++; 42 | coilStatusRead(ip, port, slaveId, start, len, resultListener); 43 | }else { 44 | Log.e("TAG","请检查设置后重新连接"); 45 | resultListener.onToast("请检查设置后重新连接"); 46 | } 47 | } finally { 48 | master.destroy(); 49 | } 50 | } 51 | 52 | private static void readCoilStatus(ModbusMaster master, String ip, int port, int slaveId, int start, int len, ResultListener resultListener) { 53 | try { 54 | ReadCoilsRequest request = new ReadCoilsRequest(slaveId, start, len); 55 | ReadCoilsResponse response = (ReadCoilsResponse) master.send(request); 56 | if (response.isException()) { 57 | Log.e("TAG1", "Exception response: message=" + response.getExceptionMessage()); 58 | resultListener.onToast("Exception response: message=" + response.getExceptionMessage()); 59 | } else { 60 | ByteQueue byteQueue= new ByteQueue(12); 61 | response.write(byteQueue); 62 | resultListener.result(ByteHex.allData(byteQueue,len), ip, port, slaveId, start, 1); 63 | Log.e("TAG2", byteQueue + " Size: " + byteQueue.size()); 64 | Log.e("TAG31", ByteHex.allData(byteQueue, len).toString()); 65 | Log.e("TAG32", Integer.toBinaryString((int) byteQueue.peek(3) & 0xff).length()+""); 66 | short[] list = response.getShortData(); 67 | for(int i = 0; i < list.length; i++){ 68 | Log.e("TAG4", list[i]+""); 69 | } 70 | } 71 | } catch (ModbusTransportException e) { 72 | e.printStackTrace(); 73 | if (countRead<3){ 74 | countRead++; 75 | readCoilStatus(master, ip, port, slaveId, start, len,resultListener); 76 | }else { 77 | Log.e("TAG","请检查设置后重新连接"); 78 | resultListener.onToast("请检查设置后重新连接"); 79 | } 80 | } 81 | } 82 | 83 | public static void coilStatusWrite(String ip, int port, int slaveId, int start, boolean[] values){ 84 | ModbusFactory modbusFactory = new ModbusFactory(); 85 | // 设备ModbusTCP的Ip与端口,如果不设定端口则默认为502 86 | IpParameters params = new IpParameters(); 87 | params.setHost(ip); 88 | params.setPort(port); 89 | // 参数1:IP和端口信息 参数2:保持连接激活 90 | ModbusMaster tcpMaster = modbusFactory.createTcpMaster(params, true); 91 | try { 92 | tcpMaster.init(); 93 | writeCoilsStatus(tcpMaster,slaveId,start,values); 94 | Log.e("TAG", "==============="); 95 | } catch (ModbusInitException e) { 96 | e.printStackTrace(); 97 | if (countWrite<3){ 98 | countWrite++; 99 | coilStatusWrite(ip, port, slaveId, start, values); 100 | }else { 101 | Log.e("TAG", "此处出现问题了啊"); 102 | } 103 | } finally { 104 | tcpMaster.destroy(); 105 | } 106 | } 107 | 108 | private static void writeCoilsStatus(ModbusMaster master, int slaveId, int start, boolean[] values){ 109 | try { 110 | WriteCoilsRequest request = new WriteCoilsRequest(slaveId, start, values); 111 | WriteCoilsResponse response = (WriteCoilsResponse) master.send(request); 112 | if (response.isException()){ 113 | Log.e("TAG", "Exception response: message=" + response.getExceptionMessage()); 114 | } 115 | else { 116 | Log.e("TAG","Success"); 117 | } 118 | } catch (ModbusTransportException e) { 119 | e.printStackTrace(); 120 | if (countWrite<3){ 121 | countWrite++; 122 | writeCoilsStatus(master, slaveId, start, values); 123 | }else { 124 | Log.e("TAG","请检查设置后重新写入"); 125 | } 126 | } 127 | finally { 128 | master.destroy(); 129 | } 130 | } 131 | 132 | public static void coilStatusWrite(String ip, int port, int slaveId, int start, boolean value, ResultListener resultListener){ 133 | ModbusFactory modbusFactory = new ModbusFactory(); 134 | // 设备ModbusTCP的Ip与端口,如果不设定端口则默认为502 135 | IpParameters params = new IpParameters(); 136 | params.setHost(ip); 137 | params.setPort(port); 138 | // 参数1:IP和端口信息 参数2:保持连接激活 139 | ModbusMaster tcpMaster = modbusFactory.createTcpMaster(params, true); 140 | try { 141 | tcpMaster.init(); 142 | writeCoilStatus(tcpMaster, slaveId, start, value, resultListener); 143 | Log.e("TAG", "==============="); 144 | } catch (ModbusInitException e) { 145 | e.printStackTrace(); 146 | if (countWrite<3){ 147 | countWrite++; 148 | coilStatusWrite(ip, port, slaveId, start, value, resultListener); 149 | }else { 150 | Log.e("TAG", "此处出现问题了啊"); 151 | resultListener.onToast("请检查设置后重新发送"); 152 | } 153 | } 154 | finally { 155 | tcpMaster.destroy(); 156 | } 157 | } 158 | 159 | private static void writeCoilStatus(ModbusMaster master, int slaveId, int start, boolean value, ResultListener resultListener){ 160 | try { 161 | WriteCoilRequest request = new WriteCoilRequest(slaveId, start, value); 162 | WriteCoilResponse response = (WriteCoilResponse) master.send(request); 163 | if (response.isException()){ 164 | Log.e("TAG", "Exception response: message=" + response.getExceptionMessage()); 165 | resultListener.onToast("Exception response: message=" + response.getExceptionMessage()); 166 | } 167 | else { 168 | Log.e("TAG","Success"); 169 | resultListener.onToast("Success"); 170 | } 171 | } catch (ModbusTransportException e) { 172 | e.printStackTrace(); 173 | if (countWrite<3){ 174 | countWrite++; 175 | writeCoilStatus(master, slaveId, start, value, resultListener); 176 | }else { 177 | Log.e("TAG","请检查设置后重新连接"); 178 | resultListener.onToast("请检查设置后重新发送"); 179 | } 180 | } 181 | finally { 182 | master.destroy(); 183 | } 184 | } 185 | 186 | } 187 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/modbus/Holding_Register.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.modbus; 2 | 3 | import android.util.Log; 4 | 5 | import com.example.administrator.modbustcp.Interface.ResultListener; 6 | import com.example.administrator.modbustcp.utils.ByteHex; 7 | import com.serotonin.modbus4j.ModbusFactory; 8 | import com.serotonin.modbus4j.ModbusMaster; 9 | import com.serotonin.modbus4j.exception.ModbusInitException; 10 | import com.serotonin.modbus4j.exception.ModbusTransportException; 11 | import com.serotonin.modbus4j.ip.IpParameters; 12 | import com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest; 13 | import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse; 14 | import com.serotonin.modbus4j.msg.WriteRegisterRequest; 15 | import com.serotonin.modbus4j.msg.WriteRegisterResponse; 16 | import com.serotonin.modbus4j.msg.WriteRegistersRequest; 17 | import com.serotonin.modbus4j.msg.WriteRegistersResponse; 18 | import com.serotonin.util.queue.ByteQueue; 19 | 20 | import java.util.Arrays; 21 | 22 | /** 23 | * Created by DoBest on 2016/3/28. 24 | */ 25 | public class Holding_Register { 26 | 27 | private static int countRead = 0; 28 | private static int countWrite = 0; 29 | public static void holdingRegisterRead(String ip, int port,int slaveId, int start,int len, 30 | ResultListener resultListener){ 31 | IpParameters params = new IpParameters(); 32 | params.setHost(ip);//地址 33 | params.setPort(port);//端口 34 | ModbusFactory factory = new ModbusFactory(); 35 | ModbusMaster master = factory.createTcpMaster(params, true); 36 | 37 | // 初始化 38 | try { 39 | master.init(); 40 | readHoldingRegisters(master, ip,port,slaveId, start, len, resultListener); 41 | } catch (ModbusInitException e) { 42 | e.printStackTrace(); 43 | if (countRead<3){ 44 | countRead++; 45 | holdingRegisterRead(ip,port,slaveId,start,len, resultListener); 46 | }else { 47 | Log.e("TAG","请检查设置后重新连接"); 48 | resultListener.onToast("请检查设置后重新连接"); 49 | } 50 | } finally { 51 | master.destroy(); 52 | } 53 | } 54 | 55 | private static void readHoldingRegisters(ModbusMaster master,String ip, int port, int slaveId, int start, int len, 56 | ResultListener resultListener) { 57 | try { 58 | ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest( 59 | slaveId, start, len); 60 | ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master 61 | .send(request); 62 | if (response.isException()) { 63 | Log.e("TAG1", "Exception response: message=" + response.getExceptionMessage()); 64 | resultListener.onToast("Exception response: message=" + response.getExceptionMessage()); 65 | } else { 66 | ByteQueue byteQueue= new ByteQueue(12); 67 | response.write(byteQueue); 68 | resultListener.result(ByteHex.allDataR(byteQueue), ip, port, slaveId, start, 3); 69 | Log.e("TAG2", byteQueue + " Size: " + byteQueue.size()); 70 | Log.e("TAG3", Arrays.toString(response.getData())); 71 | Log.e("TAG31", ByteHex.allDataR(byteQueue).toString()); 72 | Log.e("TAG","Count: "+countRead); 73 | short[] list = response.getShortData(); 74 | for(int i = 0; i < list.length; i++){ 75 | Log.e("TAG4", list[i]+""); 76 | } 77 | } 78 | } catch (ModbusTransportException e) { 79 | e.printStackTrace(); 80 | if (countRead<3){ 81 | countRead++; 82 | readHoldingRegisters(master, ip, port, slaveId, start, len, resultListener); 83 | } else { 84 | Log.e("TAG","请检查设置后重新连接"); 85 | resultListener.onToast("请检查设置后重新连接"); 86 | } 87 | } 88 | } 89 | 90 | public static void holdingRegisterWrite(String ip, int port, int slaveId, int start, short[] values){ 91 | ModbusFactory modbusFactory = new ModbusFactory(); 92 | // 设备ModbusTCP的Ip与端口,如果不设定端口则默认为502 93 | IpParameters params = new IpParameters(); 94 | params.setHost(ip); 95 | params.setPort(port); 96 | // 参数1:IP和端口信息 参数2:保持连接激活 97 | ModbusMaster tcpMaster = modbusFactory.createTcpMaster(params, true); 98 | try { 99 | tcpMaster.init(); 100 | writeHoldingRegisters(tcpMaster,slaveId,start,values); 101 | Log.e("TAG", "==============="); 102 | } catch (ModbusInitException e) { 103 | e.printStackTrace(); 104 | if (countWrite<3){ 105 | countWrite++; 106 | holdingRegisterWrite(ip, port, slaveId, start, values); 107 | }else { 108 | Log.e("TAG","此处出现问题了啊"); 109 | } 110 | }finally { 111 | tcpMaster.destroy(); 112 | } 113 | } 114 | 115 | private static void writeHoldingRegisters(ModbusMaster master,int slaveId, int start, short[] values){ 116 | try { 117 | WriteRegistersRequest request = new WriteRegistersRequest(slaveId, start, values); 118 | WriteRegistersResponse response = (WriteRegistersResponse) master.send(request); 119 | if (response.isException()){ 120 | Log.e("TAG", "Exception response: message=" + response.getExceptionMessage()); 121 | } 122 | else { 123 | Log.e("TAG","Success"); 124 | } 125 | } catch (ModbusTransportException e) { 126 | e.printStackTrace(); 127 | if (countWrite<3){ 128 | countWrite++; 129 | writeHoldingRegisters(master, slaveId, start, values); 130 | }else { 131 | Log.e("TAG","请检查设置后重新连接"); 132 | } 133 | } 134 | finally { 135 | master.destroy(); 136 | } 137 | } 138 | 139 | public static void holdingRegisterWrite(String ip, int port, int slaveId, int start, int value, ResultListener resultListener){ 140 | ModbusFactory modbusFactory = new ModbusFactory(); 141 | // 设备ModbusTCP的Ip与端口,如果不设定端口则默认为502 142 | IpParameters params = new IpParameters(); 143 | params.setHost(ip); 144 | params.setPort(port); 145 | // 参数1:IP和端口信息 参数2:保持连接激活 146 | ModbusMaster tcpMaster = modbusFactory.createTcpMaster(params, true); 147 | try { 148 | tcpMaster.init(); 149 | writeHoldingRegister(tcpMaster,slaveId,start,value,resultListener); 150 | Log.e("TAG", "==============="); 151 | } catch (ModbusInitException e) { 152 | e.printStackTrace(); 153 | if (countWrite<3){ 154 | countWrite++; 155 | holdingRegisterWrite(ip, port, slaveId,start, value,resultListener); 156 | }else { 157 | Log.e("TAG","此处出现问题了啊"); 158 | resultListener.onToast("请检查设置后重新发送"); 159 | } 160 | } finally { 161 | tcpMaster.destroy(); 162 | } 163 | } 164 | 165 | private static void writeHoldingRegister(ModbusMaster master,int slaveId, int start, int value, ResultListener resultListener){ 166 | try { 167 | WriteRegisterRequest request = new WriteRegisterRequest(slaveId, start, value); 168 | WriteRegisterResponse response = (WriteRegisterResponse) master.send(request); 169 | if (response.isException()){ 170 | Log.e("TAG", "Exception response: message=" + response.getExceptionMessage()); 171 | resultListener.onToast("Exception response: message=" + response.getExceptionMessage()); 172 | } 173 | else { 174 | Log.e("TAG","Success"); 175 | resultListener.onToast("Success"); 176 | } 177 | } catch (ModbusTransportException e) { 178 | e.printStackTrace(); 179 | if (countWrite<3){ 180 | countWrite++; 181 | writeHoldingRegister(master,slaveId, start, value, resultListener); 182 | }else { 183 | Log.e("TAG","请检查设置后重新连接"); 184 | resultListener.onToast("请检查设置后重新发送"); 185 | } 186 | } 187 | finally { 188 | master.destroy(); 189 | } 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/modbus/Input_Registers.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.modbus; 2 | 3 | import android.util.Log; 4 | 5 | import com.example.administrator.modbustcp.Interface.ResultListener; 6 | import com.example.administrator.modbustcp.utils.ByteHex; 7 | import com.serotonin.modbus4j.ModbusFactory; 8 | import com.serotonin.modbus4j.ModbusMaster; 9 | import com.serotonin.modbus4j.exception.ModbusInitException; 10 | import com.serotonin.modbus4j.exception.ModbusTransportException; 11 | import com.serotonin.modbus4j.ip.IpParameters; 12 | import com.serotonin.modbus4j.msg.ReadInputRegistersRequest; 13 | import com.serotonin.modbus4j.msg.ReadInputRegistersResponse; 14 | import com.serotonin.util.queue.ByteQueue; 15 | 16 | import java.util.Arrays; 17 | 18 | /** 19 | * Created by DoBest on 2016/3/28. 20 | */ 21 | public class Input_Registers { 22 | 23 | private static int countRead = 0; 24 | public static void inputRegisterRead(String ip, int port,int slaveId, int start,int len, ResultListener resultListener){ 25 | IpParameters params = new IpParameters(); 26 | params.setHost(ip);//地址 27 | params.setPort(port);//端口 28 | ModbusFactory factory = new ModbusFactory(); 29 | ModbusMaster master = factory.createTcpMaster(params, true); 30 | 31 | // 初始化 32 | try { 33 | master.init(); 34 | readInputRegisters(master, ip, port, slaveId, start, len, resultListener); 35 | } catch (ModbusInitException e) { 36 | e.printStackTrace(); 37 | if (countRead<3){ 38 | countRead++; 39 | inputRegisterRead(ip, port, slaveId, start, len, resultListener); 40 | }else { 41 | Log.e("TAG","请检查设置后重新连接"); 42 | resultListener.onToast("请检查设置后重新连接"); 43 | } 44 | } finally { 45 | master.destroy(); 46 | } 47 | } 48 | 49 | private static void readInputRegisters(ModbusMaster master, String ip, int port, int slaveId, int start, int len, 50 | ResultListener resultListener) { 51 | try { 52 | ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId, start, len); 53 | ReadInputRegistersResponse response = (ReadInputRegistersResponse) master.send(request); 54 | if (response.isException()) { 55 | Log.e("TAG1", "Exception response: message=" + response.getExceptionMessage()); 56 | resultListener.onToast("Exception response: message=" + response.getExceptionMessage()); 57 | } else { 58 | ByteQueue byteQueue= new ByteQueue(12); 59 | response.write(byteQueue); 60 | resultListener.result(ByteHex.allDataR(byteQueue),ip, port, slaveId, start, 4); 61 | Log.e("TAG2", byteQueue + " Size: "+byteQueue.size()); 62 | Log.e("TAG3", Arrays.toString(response.getShortData())); 63 | short[] list = response.getShortData(); 64 | for(int i = 0; i < list.length; i++){ 65 | Log.e("TAG4", list[i]+""); 66 | } 67 | } 68 | } catch (ModbusTransportException e) { 69 | e.printStackTrace(); 70 | if (countRead<3){ 71 | countRead++; 72 | readInputRegisters(master, ip, port, slaveId, start, len, resultListener); 73 | }else { 74 | Log.e("TAG","请检查设置后重新连接"); 75 | resultListener.onToast("请检查设置后重新连接"); 76 | } 77 | }finally { 78 | master.destroy(); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/modbus/Input_Status.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.modbus; 2 | 3 | import android.util.Log; 4 | 5 | import com.example.administrator.modbustcp.Interface.ResultListener; 6 | import com.example.administrator.modbustcp.utils.ByteHex; 7 | import com.serotonin.modbus4j.ModbusFactory; 8 | import com.serotonin.modbus4j.ModbusMaster; 9 | import com.serotonin.modbus4j.exception.ModbusInitException; 10 | import com.serotonin.modbus4j.exception.ModbusTransportException; 11 | import com.serotonin.modbus4j.ip.IpParameters; 12 | import com.serotonin.modbus4j.msg.ReadDiscreteInputsRequest; 13 | import com.serotonin.modbus4j.msg.ReadDiscreteInputsResponse; 14 | import com.serotonin.util.queue.ByteQueue; 15 | 16 | import java.util.Arrays; 17 | 18 | /** 19 | * Created by DoBest on 2016/3/28. 20 | */ 21 | public class Input_Status { 22 | 23 | private static int countRead = 0; 24 | public static void inputStatusRead(String ip, int port,int slaveId, int start,int len, 25 | ResultListener resultListener){ 26 | IpParameters params = new IpParameters(); 27 | params.setHost(ip);//地址 28 | params.setPort(port);//端口 29 | ModbusFactory factory = new ModbusFactory(); 30 | ModbusMaster master = factory.createTcpMaster(params, true); 31 | 32 | // 初始化 33 | try { 34 | master.init(); 35 | readInputStatus(master, ip, port, slaveId, start, len, resultListener); 36 | } catch (ModbusInitException e) { 37 | e.printStackTrace(); 38 | if (countRead<3){ 39 | countRead++; 40 | inputStatusRead(ip, port, slaveId, start, len, resultListener); 41 | }else { 42 | Log.e("TAG","请检查设置后重新连接"); 43 | resultListener.onToast("请检查设置后重新连接"); 44 | } 45 | } finally { 46 | master.destroy(); 47 | } 48 | } 49 | 50 | private static void readInputStatus(ModbusMaster master,String ip, int port,int slaveId, int start, int len, 51 | ResultListener resultListener) { 52 | try { 53 | ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, start, len); 54 | ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request); 55 | if (response.isException()) { 56 | Log.e("TAG1", "Exception response: message=" + response.getExceptionMessage()); 57 | resultListener.onToast("Exception response: message=" + response.getExceptionMessage()); 58 | } else { 59 | ByteQueue byteQueue= new ByteQueue(12); 60 | response.write(byteQueue); 61 | resultListener.result(ByteHex.allData(byteQueue,len),ip, port, slaveId, start, 2); 62 | Log.e("TAG2", byteQueue + " Size: "+byteQueue.size()); 63 | Log.e("TAG3", Arrays.toString(response.getShortData())); 64 | short[] list = response.getShortData(); 65 | for(int i = 0; i < list.length; i++){ 66 | Log.e("TAG4", list[i]+""); 67 | } 68 | } 69 | } catch (ModbusTransportException e) { 70 | e.printStackTrace(); 71 | if (countRead<3){ 72 | countRead++; 73 | readInputStatus(master, ip, port, slaveId, start, len, resultListener); 74 | }else { 75 | Log.e("TAG","请检查设置后重新连接"); 76 | resultListener.onToast("请检查设置后重新连接"); 77 | } 78 | }finally { 79 | master.destroy(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/model/DataModel.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.model; 2 | 3 | /** 4 | * Created by DongBang on 2016/3/31. 5 | */ 6 | public class DataModel { 7 | 8 | private String alise;//属性名称 9 | private String value;//属性值 10 | 11 | public String getAlise() 12 | { 13 | return alise; 14 | } 15 | 16 | public void setAlise(String alise) 17 | { 18 | this.alise = alise; 19 | } 20 | 21 | public String getValue() 22 | { 23 | return value; 24 | } 25 | 26 | public void setValue(String value) 27 | { 28 | this.value = value; 29 | } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/service/ReadService.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.service; 2 | 3 | import android.app.Service; 4 | import android.content.Intent; 5 | import android.os.Binder; 6 | import android.os.IBinder; 7 | import android.util.Log; 8 | import android.widget.Toast; 9 | 10 | import com.example.administrator.modbustcp.Interface.ResultListener; 11 | import com.example.administrator.modbustcp.fragment.Fragment_Setting; 12 | import com.example.administrator.modbustcp.modbus.Coil_Status; 13 | import com.example.administrator.modbustcp.modbus.Holding_Register; 14 | import com.example.administrator.modbustcp.modbus.Input_Registers; 15 | import com.example.administrator.modbustcp.modbus.Input_Status; 16 | import com.example.administrator.modbustcp.utils.ToastUtil; 17 | 18 | import java.util.Timer; 19 | import java.util.TimerTask; 20 | 21 | /** 22 | * Created by DoBest on 2016/3/31. 23 | */ 24 | public class ReadService extends Service{ 25 | 26 | private String TAG = ReadService.class.getName(); 27 | private ServiceBinder mBinder = new ServiceBinder(); 28 | private int type = Fragment_Setting.getFunction_type(); 29 | private String ip = Fragment_Setting.getRead_ip_value(); 30 | private int port = Fragment_Setting.getRead_port_value(); 31 | private int slaveId = Fragment_Setting.getRead_slaveId_value(); 32 | private int start = Fragment_Setting.getRead_start_value(); 33 | private int length = Fragment_Setting.getRead_length_value(); 34 | private Timer timer = new Timer(); 35 | 36 | @Override 37 | public IBinder onBind(Intent intent) { 38 | return mBinder; 39 | } 40 | 41 | @Override 42 | public int onStartCommand(Intent intent, int flags, int startId) { 43 | return super.onStartCommand(intent, flags, startId); 44 | } 45 | 46 | public class ServiceBinder extends Binder{ 47 | public void setData(final ResultListener resultListener){ 48 | // requestDate(resultListener); 49 | // Coil_Status.coilStatusRead("192.168.1.158", 502, 1, 100, 10, resultListener); 50 | timer.scheduleAtFixedRate(new TimerTask() { 51 | @Override 52 | public void run() { 53 | requestDate(resultListener); 54 | } 55 | }, 0, 1000); //每隔1秒 56 | ToastUtil.showToast(ReadService.this, "开始连接", Toast.LENGTH_SHORT); 57 | } 58 | } 59 | 60 | @Override 61 | public boolean stopService(Intent name) { 62 | Log.e(TAG,"stopService"); 63 | return super.stopService(name); 64 | } 65 | 66 | private void requestDate(ResultListener resultListener){ 67 | switch (type){ 68 | case 1: 69 | Coil_Status.coilStatusRead(ip, port, slaveId, start, length, resultListener); 70 | Log.e("TAG", ip + port + slaveId + start + length+type); 71 | break; 72 | case 2: 73 | Input_Status.inputStatusRead(ip, port, slaveId, start, length, resultListener); 74 | Log.e("TAG", ip + port + slaveId + start + length+type); 75 | break; 76 | case 3: 77 | Holding_Register.holdingRegisterRead(ip, port, slaveId, start, length, resultListener); 78 | Log.e("TAG", ip + port + slaveId + start + length+type); 79 | break; 80 | case 4: 81 | Input_Registers.inputRegisterRead(ip, port, slaveId, start, length, resultListener); 82 | Log.e("TAG", ip + port + slaveId + start + length+type); 83 | break; 84 | } 85 | } 86 | private void stopTimer() { 87 | // timer.cancel(); 88 | if (timer != null) { 89 | timer.cancel(); 90 | timer = null; 91 | } 92 | } 93 | 94 | @Override 95 | public boolean onUnbind(Intent intent) { 96 | stopTimer(); 97 | Log.e("TAG", "停止定时器"); 98 | Toast.makeText(this, "断开连接", Toast.LENGTH_SHORT).show(); 99 | return super.onUnbind(intent); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/utils/ByteHex.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.utils; 2 | 3 | import com.serotonin.util.queue.ByteQueue; 4 | 5 | import java.util.ArrayList; 6 | import java.util.Collections; 7 | 8 | /** 9 | * Created by Administrator on 2016/4/3. 10 | */ 11 | public class ByteHex { 12 | public static ArrayList allData(ByteQueue byteQueue, int len){ 13 | String data = new String(); 14 | ArrayList dataList = new ArrayList(); 15 | for (int i=3;i backData(String data){ 30 | ArrayList dataList = new ArrayList(); 31 | for (int i=data.length();i<8;i++){ 32 | data = 0+data; 33 | } 34 | for (int i=0;i backData2(String data,int length){ 41 | ArrayList dataList = new ArrayList(); 42 | for (int i=data.length();i addData(ArrayList listB,ArrayList listA){ 52 | for (int i =0;i allDataR(ByteQueue byteQueue){ 59 | ArrayList dataList = new ArrayList(); 60 | for (int i=4; i result(ArrayList dataList, String ip, int port, int slaveId, int start, int type) { 227 | return null; 228 | } 229 | 230 | @Override 231 | public void onToast(String string) { 232 | //给handler发送消息 233 | Message msg = new Message(); 234 | msg.what = TOAST; 235 | msg.obj = string; 236 | handler.sendMessage(msg); 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/utils/LogUtils.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.utils; 2 | 3 | import android.util.Log; 4 | 5 | /** 6 | * Created by DongBang on 2016/3/31. 7 | */ 8 | public class LogUtils 9 | { 10 | public static Boolean isLog=true; 11 | 12 | 13 | public static void d(String tag,String msg) 14 | { 15 | if (isLog) 16 | { 17 | Log.d(tag,msg); 18 | } 19 | } 20 | public static void d(String tag,String msg,Throwable thr) 21 | { 22 | if (isLog) 23 | { 24 | Log.d(tag, msg, thr); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/utils/StatusBarCompat.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.utils; 2 | 3 | 4 | import android.app.Activity; 5 | import android.content.Context; 6 | import android.graphics.Color; 7 | import android.os.Build; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | 11 | /** 12 | * Created by DoBest on 2016/3/30. 13 | */ 14 | public class StatusBarCompat { 15 | private static final int INVALID_VAL = -1; 16 | private static final int COLOR_DEFAULT = Color.parseColor("#20000000"); 17 | 18 | public static void compat(Activity activity,int statusColor){ 19 | 20 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){ 21 | 22 | if (statusColor !=INVALID_VAL){ 23 | activity.getWindow().setStatusBarColor(statusColor); 24 | } 25 | return; 26 | } 27 | 28 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && 29 | Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){ 30 | int color = COLOR_DEFAULT; 31 | ViewGroup contenView = (ViewGroup) activity.findViewById(android.R.id.content); 32 | if (statusColor != INVALID_VAL){ 33 | color = statusColor; 34 | } 35 | View statusBarView = contenView.getChildAt(0); 36 | //改变颜色时避免重复添加statusBarView 37 | if (statusBarView != null && statusBarView.getMeasuredHeight() == getStatusBarHeight(activity)) 38 | { 39 | statusBarView.setBackgroundColor(color); 40 | return; 41 | } 42 | statusBarView = new View(activity); 43 | ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams( 44 | ViewGroup.LayoutParams.MATCH_PARENT,getStatusBarHeight(activity)); 45 | statusBarView.setBackgroundColor(color); 46 | contenView.addView(statusBarView,layoutParams); 47 | } 48 | } 49 | 50 | public static void compat(Activity activity){ 51 | compat(activity,INVALID_VAL); 52 | } 53 | 54 | public static int getStatusBarHeight(Context context){ 55 | 56 | int result = 0; 57 | int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); 58 | if (resourceId > 0) 59 | { 60 | result = context.getResources().getDimensionPixelSize(resourceId); 61 | } 62 | return result; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /app/src/main/java/com/example/administrator/modbustcp/utils/ToastUtil.java: -------------------------------------------------------------------------------- 1 | package com.example.administrator.modbustcp.utils; 2 | 3 | import android.content.Context; 4 | import android.widget.Toast; 5 | 6 | /** 7 | * Created by Administrator on 2016/4/9. 8 | */ 9 | public class ToastUtil { 10 | private static Toast mToast; 11 | 12 | /** 13 | * 多次显示不延迟的Toast 14 | */ 15 | public static void showToast(Context context, CharSequence text, int duration) { 16 | if(mToast == null) { 17 | mToast = Toast.makeText(context, text, duration); 18 | } else { 19 | mToast.setText(text); 20 | mToast.setDuration(duration); 21 | } 22 | mToast.show(); 23 | } 24 | 25 | public static void showToast(Context context, int text, int duration) { 26 | if(mToast == null) { 27 | mToast = Toast.makeText(context, text, duration); 28 | } else { 29 | mToast.setText(text); 30 | mToast.setDuration(duration); 31 | } 32 | mToast.show(); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/quanbu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Idtk/ModbusTCP/8e35b06f17278742fee827530e961af882185ed0/app/src/main/res/drawable-xhdpi/quanbu.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/quanbu2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Idtk/ModbusTCP/8e35b06f17278742fee827530e961af882185ed0/app/src/main/res/drawable-xhdpi/quanbu2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/shezhi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Idtk/ModbusTCP/8e35b06f17278742fee827530e961af882185ed0/app/src/main/res/drawable-xhdpi/shezhi.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/shezhi2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Idtk/ModbusTCP/8e35b06f17278742fee827530e961af882185ed0/app/src/main/res/drawable-xhdpi/shezhi2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/zaidu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Idtk/ModbusTCP/8e35b06f17278742fee827530e961af882185ed0/app/src/main/res/drawable-xhdpi/zaidu.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/zaidu2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Idtk/ModbusTCP/8e35b06f17278742fee827530e961af882185ed0/app/src/main/res/drawable-xhdpi/zaidu2.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/attribute_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_edittext.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_edittext_focused.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_edittext_normal.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bottom_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/read_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/setting_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 16 | 17 | 18 | 19 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/custom_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 11 | 14 | 17 | 20 | 21 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/edit_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 22 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_read.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 13 | 17 |