Android Socket instance (2) implementation of file list dynamic access

Next: Android Socket instance (four) determine the target system model, to achieve the dynamic remote open PC folder

This content: implement OPN, DIR operation, optimize the architecture, briefly describe the target system architecture, implement android command operation.

Idea server updated. Procedure

In the previous content, we realized the operation of NetFileData to return the file list on the IDEA server. On this basis, we designed the architecture and set up an Operator class to deal with commands to call various function classes, realize the commands passed in by the server, and return specified information. Then, we performed the following operations on the IDEA server.

Create baseOperator.java and set up the exe () method to be inherited by each function.

package lrz.base;

import java.util.ArrayList;

public abstract class BaseOperator {
    public abstract ArrayList<String> exe(String cmdBody) throws Exception ;
}

Copy the code

Rename netFileData.java to dir.java, inheriting from the BaseOperator class, as follows

package lrz.data; import lrz.base.BaseOperator; import java.io.File; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; public class DIR extends BaseOperator { public ArrayList<String> exe(String cmdBody) throws Exception { // TODO Auto-generated method stub ArrayList<String> backList=new ArrayList<String>(); File file = new File(cmdBody); File[] listFiles = file.listFiles(); for(File mfile:listFiles){ String fileName = mfile.getName(); long lastModified = mfile.lastModified(); SimpleDateFormat dateFormat = new SimpleDateFormat(" YYYY-MM-DD HH: MM :ss"); String fileDate = dateformat. format(new Date(lastModified)); 2018-03-16 09:50:23 String fileDate = dateformat. format(new Date(lastModified)); String fileSize="0"; String isDir="1"; if(! Mfile.isdirectory ()){// Check whether isDir="0"; fileSize=""+mfile.length(); } backList.add(fileName+">"+fileDate+">"+fileSize+">"+isDir+">"); } return backList; }}Copy the code

Create an opn. Java class to open a file

package lrz.data; import lrz.base.BaseOperator; import java.awt.*; import java.io.File; import java.io.IOException; import java.util.ArrayList; public class OPN extends BaseOperator { public ArrayList<String> exe(String cmdBody) throws Exception { ArrayList<String> backList=new ArrayList<String>(); Desktop desk=Desktop.getDesktop(); File file=new File(cmdBody); // Create a Java file system try {desk.open(file); // Call the open (File f) method to open the File backlist.add (" successfully run File: "+cmdBody); } catch (IOException ex) { ex.printStackTrace(); System.out.println(ex.toString()); backList.add(ex.toString()); } return backList; }}Copy the code

Create operator. Java to process the incoming command, invoke the specified function class to realize the command function, and add the command label in the header after obtaining the result returned by the function class, providing convenience for the Android terminal to analyze the returned data.

package lrz.tool; import lrz.data.DIR; import lrz.data.OPN; import java.util.ArrayList; Public class Operator {public static ArrayList<String> exeCmd(String CMD) throws Exception {// All command operations are judged and returned in this static function String[] splitCmd = splitCmd(CMD); String cmdHead = splitCmd[0]; String cmdHead = splitCmd[0]; String cmdBody = splitCmd[1]; ArrayList<String> msgBackList = new ArrayList<String>(); if (cmdHead.equals("dir")) { msgBackList = new DIR().exe(cmdBody); msgBackList.add(0,"dir"); // add "ok" return msgBackList; } if (cmdHead.equals("opn")) { msgBackList = new OPN().exe(cmdBody); Msgbacklist.add (0,"opn"); // add "ok" return msgBackList; } / /... If (msgbacklist.size ()==0){msgbacklist.add (0," invalid command :"+ CMD); } throw new Exception(" invalid command!") ); // If the code executes correctly, it will return. Throws Exception {String[] cmdout = null;} public static String[] splitCmd(String CMD) throws Exception {String[] cmdout = null; int splitIdx = cmd.indexOf(":"); System.out.println(" server accept command: "+ CMD); If (splitIdx < 1) {throw new Exception(" illegal command: "+ CMD); } else {cmdout = new String[2]; String cmdHead = cmd.substring(0, splitIdx); String cmdBody = cmd.substring(splitIdx + 1); cmdout[0] = cmdHead.toLowerCase(); Cmdout [1] = cmdBody; } return cmdout; }}Copy the code

Serversocket01.java changed as follows

package lrz.server; import lrz.tool.Operator; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.Enumeration; public class ServerSocket01 { int port = 8019; / / a custom port, the port number as far as possible choose a few not occupied by other service port, see http://blog.csdn.net/hsj521li/article/details/7678880 ArrayList < String > msgBackList; public ServerSocket01() { // TODO Auto-generated constructor stub } public ServerSocket01(int port) { super(); this.port = port; } private void printLocalIp(ServerSocket ServerSocket) {// Enumerate the IP address of the print server try {system.out. println(" Server command port prot=" + serverSocket.getLocalPort()); Enumeration<NetworkInterface> interfaces = null; interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface ni = interfaces.nextElement(); Enumeration<InetAddress> addresss = ni.getInetAddresses(); while (addresss.hasMoreElements()) { InetAddress nextElement = addresss.nextElement(); String hostAddress = nextElement.getHostAddress(); System.out.println(" The local IP address is: "+ hostAddress); } } } catch (Exception e) { e.printStackTrace(); }} public void work() throws Exception { Because Socket work is blocking, Android Socket work must be implemented in a new thread, if the UI main thread work error ServerSocket ServerSocket = new ServerSocket(port); printLocalIp(serverSocket); While (true) {/ / infinite loop System. Out. The println (" = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = "); System.out.println("| Waiting client to connect..... | "); System.out.println("================================="); Socket socket = serverSocket.accept(); / / block type System. Out. Println (" connection requests from: "+ socket. GetRemoteSocketAddress (). The toString ()); try{ getAndDealCmd(socket); } catch (Exception e) { cmdFail(e.toString()); } SocketMsg.writeBackMsg(socket,msgBackList); System.out.println(".............. The output stream..." ); msgBackList.forEach(s -> System.out.println(s)); System.out.println("................................." ); socket.close(); System.out.println(" This Socket service ends "); System.out.println("---------------------------------"); System.out.println("---------------------------------"); } } public void getAndDealCmd(Socket socket) throws Exception { ArrayList<String> cmdList = SocketMsg.readSocketMsg(socket); If (cmdlist.size ()==0){cmdFail("Cmd input is empty. "); / / if the command line length 0, it returns an error message} System. Out.println ("... The input stream..." ); cmdList.forEach(s -> System.out.println(s)); System.out.println("................................." ); if(cmdList.size()==1){ msgBackList=Operator.exeCmd(cmdList.get(0)); ExeCmd (cmdList);}else{// msgBackList= multioperator.execmd (cmdList); Private void cmdFail(String e) {msgbacklist.clear ();}} private void cmdFail(String e) {msgbacklist.clear (); // String nu="java.lang.NullPointerException"; If (e.quals (nu)){e=" target does not exist "; } msgBackList.add(e); /** * @param args */ public static void main(String[] args) throws Exception {new ServerSocket01().work(); }}Copy the code

Android update

Socketclient. Java adds parsing of the type of the command header returned by the server and sets the type returned by the handler, such as SERVER_MSG_DIR, Mainactivity. Java allows the handler to perform different operations on the data it listens to based on the results of different commands.

package com.example.android_app; import android.os.Bundle; import android.os.Handler; import android.os.Message; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.InetSocketAddress; import java.net.Socket; import java.util.ArrayList; public class SocketClient { public static int SERVER_MSG_OK=0; Public static int SERVER_MSG_ERROR=1; public static int SERVER_MSG_ERROR=1; Public static int SERVER_MSG_DIR=2; Public static int SERVER_MSG_OPN=3; Private int msgType; private String ip; private int port; private int connect_timeout=10000; private Handler handler; private Socket socket; public static final String KEY_SERVER_ACK_MSG = "KEY_SERVER_ACK_MSG"; private OutputStreamWriter writer; private BufferedReader bufferedReader; public SocketClient(String ip, int port, Handler handler) { this.port = port; this.ip = ip; this.handler = handler; } private void connect() throws IOException {// Connect the server function InetSocketAddress address = new InetSocketAddress(IP, port); socket = new Socket(); socket.connect(address, connect_timeout); } private void writeCmd(String cmd) throws IOException { BufferedOutputStream os=new BufferedOutputStream(socket.getOutputStream()); writer=new OutputStreamWriter(os,"UTF-8"); writer.write("1\n"); writer.write(cmd+"\n"); writer.flush(); } private ArrayList<String> readSocketMsg() throws IOException { ArrayList<String> msgList=new ArrayList<>(); InputStreamReader isr=new InputStreamReader(socket.getInputStream(),"UTF-8"); bufferedReader=new BufferedReader(isr); String numStr = bufferedReader.readLine(); int linNum = Integer.parseInt(numStr); msgType=SERVER_MSG_ERROR; If (linNum<1){msgList. Add (" server returns null "); return msgList; } String status = bufferedReader.readLine(); if(status.equalsIgnoreCase("OK")){ msgType=SERVER_MSG_OK; }else if(status.equalsIgnoreCase("DIR")){ msgType=SERVER_MSG_DIR; }else if(status.equalsIgnoreCase("OPN")){ msgType=SERVER_MSG_OPN; }else{ msgList.add(status); } for (int I = 1; i <linNum ; i++) { String s = bufferedReader.readLine(); msgList.add(s); } return msgList; } private void close() throws IOException { bufferedReader.close(); writer.close(); socket.close(); } private void doCmdTask(String cmd){ ArrayList<String> msgList=new ArrayList<>(); try { connect(); writeCmd(cmd); msgList = readSocketMsg(); close(); } catch (IOException e) { msgType=SERVER_MSG_ERROR; msgList.add(e.toString()); e.printStackTrace(); } Message message = handler.obtainMessage(); Bundle bundle = new Bundle(); bundle.putStringArrayList(KEY_SERVER_ACK_MSG,msgList); message.arg2=msgType; message.setData(bundle); handler.sendMessage(message); } public void work(final String cmd){ new Thread(new Runnable() { @Override public void run() { doCmdTask(cmd); } }).start(); }}Copy the code

Activity_main.xml adds a TextView to display action information

<? The XML version = "1.0" encoding = "utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <EditText android:layout_width="0dp" Android :layout_height="wrap_content" Android :layout_weight="3" Android :id="@+ ID/URL "Android :text=" server IP "/> <EditText android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="3" android:id="@+id/way" android:text="8019"/> </LinearLayout> <EditText android:layout_width="match_parent" android:layout_height="wrap_content"  android:id="@+id/dir" android:text="d://"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="submit" android:id="@+id/submit"/> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/show_msg" android:text="show_msg"/> <ListView android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/listview"/> </LinearLayout>Copy the code

Mainactivity.java is changed as follows: Add handler’s decision on different return types and different actions, and display the action results in a Textview

package com.example.android_app; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import androidx.annotation.NonNull; import android.os.Build; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; public class MainActivity extends AppCompatActivity { public static final String KEY_SERVER_ACK_MSG = "KEY_SERVER_ACK_MSG"; private Handler handler = null; EditText url,way,dir; ListView lv; Button submit; SocketClient socketClient=null; String here; ArrayList<String> data; int port; TextView show_msg; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); url=findViewById(R.id.url); way=findViewById(R.id.way); dir=findViewById(R.id.dir); lv=findViewById(R.id.listview); submit=findViewById(R.id.submit); show_msg=findViewById(R.id.show_msg); handler=new Handler(new Handler.Callback() { @Override public boolean handleMessage(@NonNull Message msg) { int fp=msg.arg2; Bundle data_bundle = msg.getData(); data=data_bundle.getStringArrayList(KEY_SERVER_ACK_MSG); if(fp==SocketClient.SERVER_MSG_DIR){ data=dataMaker(); printAdapter(data); Show_msg. setText(" DIR operation succeeded "); }else if(fp== socketClient.server_msg_opn){show_msg_settext (" OPN performed successfully "); } return false; }}); submit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { port=Integer.parseInt(way.getText().toString()); here=dir.getText().toString(); getdata(); }}); lv.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<? > parent, View view, int position, long id) { here=here+"/"+data.get(position); getdata(); }}); } private void getdata() { socketClient=new SocketClient(url.getText().toString(),port,handler); socketClient.work(here); } private ArrayList<String> dataMaker() { ArrayList<String> dataResult=new ArrayList<>(); int i=data.size(); for (int j = 0; j <i ; j++) { String str=data.get(j); str=str.substring(0,str.indexOf(">")); dataResult.add(str); } return dataResult; } private void printAdapter(ArrayList<String> data) { ArrayAdapter<String> arrayAdapter=new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,data); lv.setAdapter(arrayAdapter); }}Copy the code