Android socket如何實現(xiàn)文件列表動態(tài)訪問

idea服務(wù)端更新

為了防止代碼量上升可能帶來的結(jié)構(gòu)雜亂,我們對服務(wù)端架構(gòu)進行優(yōu)化,server包負責(zé)socket服務(wù)基礎(chǔ)實現(xiàn),data包負責(zé)處理各種安卓端的命令。
將readSocketMsg,writeBackMsg方法單獨拿出,創(chuàng)建一個SocketMsg方法類,專門負責(zé)數(shù)據(jù)流的讀取與寫入。
SocketMsg.java
package lrz.server;
import java.io.*;
import java.net.Socket;
import java.util.ArrayList;
public class SocketMsg {
public static ArrayList<String> readSocketMsg(Socket socket) throws IOException {
ArrayList<String> msgList=new ArrayList<String>();
InputStream inputStream = socket.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader=new BufferedReader(reader);
String lineNumStr = bufferedReader.readLine();
int lineNum=Integer.parseInt(lineNumStr);
for(int i=0;i<lineNum;i++){
String str = bufferedReader.readLine();
msgList.add(str);
}
//讀取結(jié)束后,輸入流不能關(guān)閉,此時關(guān)閉,會將socket關(guān)閉,從而導(dǎo)致后續(xù)對socket寫操作無法實現(xiàn)
return msgList;
}
public static void writeBackMsg(Socket socket, ArrayList<String> msgBackList) throws IOException {
BufferedOutputStream os = new BufferedOutputStream(socket.getOutputStream());
OutputStreamWriter writer=new OutputStreamWriter(os,"UTF-8");
writer.write(""+msgBackList.size()+"\n"); //未真正寫入的輸出流,僅僅在內(nèi)存中
writer.flush(); //寫入輸出流,真正將數(shù)據(jù)傳輸出去
for(int i=0;i<msgBackList.size();i++){
writer.write(msgBackList.get(i)+"\n");
writer.flush();
}
}
}
創(chuàng)建NetFileData.java作為文件夾訪問的方法類,將exeDir()方法放入其中。
NetFileData.java
package lrz.data;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
public class NetFileData {
public static ArrayList<String> exeDir(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");//給時間格式,例如:2018-03-16 09:50:23
String fileDate = dateFormat.format(new Date(lastModified));//取得文件最后修改時間,并按格式轉(zhuǎn)為字符串
String fileSize="0";
String isDir="1";
if(!mfile.isDirectory()){//判斷是否為目錄
isDir="0";
fileSize=""+mfile.length();
}
backList.add(fileName+">"+fileDate+">"+fileSize+">"+isDir+">");
}
return backList;
}
}
ServerSocket01.java主函數(shù)則將以上方法移除,改為調(diào)用
package lrz.server;
import lrz.data.NetFileData;
import java.io.*;
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;// 自定義一個端口,端口號盡可能挑選一些不被其他服務(wù)占用的端口,祥見http://blog.csdn.net/hsj521li/article/details/7678880
static int connect_count = 0;// 連接次數(shù)統(tǒng)計
ArrayList<String> msgBackList;
public ServerSocket01() {
// TODO Auto-generated constructor stub
}
public ServerSocket01(int port) {
super();
this.port = port;
}
private void printLocalIp(ServerSocket serverSocket) {// 枚舉打印服務(wù)端的IP
try {
System.out.println("服務(wù)端命令端口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("本機IP地址為:" + hostAddress);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void work() throws IOException {
// 注意:由于Socket的工作是阻塞式,Android端Socket的工作必須在新的線程中實現(xiàn),若在UI主線程中工作會報錯
ServerSocket serverSocket = new ServerSocket(port);
printLocalIp(serverSocket);
while (true) {// 無限循環(huán),使之能結(jié)束當(dāng)前socket服務(wù)后,準(zhǔn)備下一次socket服務(wù)
System.out.println("Waiting client to connect.....");
Socket socket = serverSocket.accept();// 阻塞式,直到有客戶端連接進來,才會繼續(xù)往下執(zhí)行,否則一直停留在此代碼
System.out.println("Client connected from: "
+ socket.getRemoteSocketAddress().toString());
ArrayList<String> cmdList= SocketMsg.readSocketMsg(socket);
cmdList.forEach(s -> System.out.println(s));
String cmdbody=cmdList.get(0);
try {
msgBackList= NetFileData.exeDir(cmdbody);
} catch (Exception e) {
e.printStackTrace();
}
msgBackList.forEach(s -> System.out.println(s));
SocketMsg.writeBackMsg(socket,msgBackList);
socket.close();
System.out.println("當(dāng)前Socket服務(wù)結(jié)束");
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
new ServerSocket01().work();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
安卓端更新
使用listview顯示文件夾內(nèi)容,并且實現(xiàn)動態(tài)訪問。
MainActivity.java更新了簡單的listview顯示,設(shè)立互動事件,在點擊某個列表部分時向服務(wù)端發(fā)動指定命令,返回結(jié)果后更新列表,實現(xiàn)互動效果。
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;
@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);
handler=new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
Bundle data_bundle = msg.getData();
data=data_bundle.getStringArrayList(KEY_SERVER_ACK_MSG);
data=dataMaker();
printAdapter(data);
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);
}
}
SocketClient.java無變動
activity_main.xml布局添加listview,代替原先的textview
<?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="服務(wù)端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"/>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/listview"/>
</LinearLayout>
補充一點:
安卓端訪問的ip在服務(wù)端中查看,ip為服務(wù)端網(wǎng)絡(luò)ip,我是紅色圈中的,可以都試一下,一般都是倒數(shù)第二個長得像ip的這個,port在服務(wù)端主函數(shù)中設(shè)置,可以是任何數(shù),8019為常用端

以上就是Android socket如何實現(xiàn)文件列表動態(tài)訪問的詳細內(nèi)容,更多關(guān)于Android socket實現(xiàn)列表動態(tài)訪問的資料請關(guān)注腳本之家其它相關(guān)文章!
- 在Android中使用WebSocket實現(xiàn)消息通信的方法詳解
- Android中socket通信的簡單實現(xiàn)
- 使用Android WebSocket實現(xiàn)即時通訊功能
- Android使用MulticastSocket實現(xiàn)多點廣播圖片
- Android通過Socket與服務(wù)器之間進行通信的示例
- android使用Socket通信實現(xiàn)多人聊天應(yīng)用
- Android Socket通信實現(xiàn)簡單聊天室
- Android使用Websocket實現(xiàn)聊天室
- android利用websocket協(xié)議與服務(wù)器通信
- Android完整Socket解決方案
- 詳解Android 基于TCP和UDP協(xié)議的Socket通信
相關(guān)文章
Android如何實現(xiàn)一個DocumentProvider示例詳解
這篇文章主要為大家介紹了Android如何實現(xiàn)一個DocumentProvider示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
Android 中自定義ContentProvider與ContentObserver的使用簡單實例
這篇文章主要介紹了Android 中自定義ContentProvider與ContentObserver的使用簡單實例的相關(guān)資料,這里提供實例幫助大家學(xué)習(xí)理解這部分內(nèi)容,需要的朋友可以參考下2017-09-09
Android TextView實現(xiàn)跑馬燈效果的方法
這篇文章主要介紹了Android TextView跑馬燈效果實現(xiàn)方法,涉及Android布局文件中相關(guān)屬性的設(shè)置技巧,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-01-01
Android App端與PHP Web端的簡單數(shù)據(jù)交互實現(xiàn)示例
本篇文章主要介紹了Android App端與PHP Web端的簡單數(shù)據(jù)交互實現(xiàn)示例,詳細的介紹了交互的代碼,非常具有實用價值,有興趣的可以了解一下2017-10-10
Android開發(fā)中類加載器DexClassLoader的簡單使用講解
這篇文章主要介紹了Android開發(fā)中類加載器DexClassLoader的簡單使用講解,DexClassLoader可以看作是一個特殊的Java中的ClassLoader,需要的朋友可以參考下2016-04-04
Android自定義可循環(huán)的滾動選擇器CycleWheelView
Android自定義可循環(huán)的滾動選擇器CycleWheelView替代TimePicker/NumberPicker/WheelView,很實用的一篇文章分享給大家,感興趣的小伙伴們可以參考一下2016-07-07

