先看看电脑上的效果,可以查看磁盘下的文件,可以用鼠标双击MP4,MP3文件会调用系统播放器进行播放,电脑与手机同局域网内无线互传jpg图片与MP4视频文件,其他文件此代码不支持。下面有安卓上的逻辑代码,不运行安卓上的代码无法成功运行此程序。服务器套接字ServerSocket的使用,字符串的使用,数据类型转换,字符集,框架设计,io流灵活运用,安卓开发与电脑服务器通信等等,总之是许多简单基础构建而成,如果基础不夯实,保证像是再看天文,如果真找不到头绪,那就慢慢夯实基础吧,不要说JDK版本都升级到十几了,你还用JTM8,升级只是为了补全之前版本的不足,并不是废弃之前的东西,所以踏实从基础干起。
MainFrame主窗体类代码详细
GamePane类详细代码
MainFrame frame;//主窗体对象
JList<String> jl ;
JScrollPane js ;//滚动面板
int wh = 500 ;//显示尺寸
int hh = 500 ;
JButton jb1;//刷新按钮
JButton jb2;//返回
JButton jb3;//前进
JButton jb4;//发送/接收按钮
String path = "D:\\";//文件路径
JTextField jt1 ;//输入或显示当前选择文件
JTextField jt2 ;//手机ip
JTextArea jla ;//对话框提示显示
ServerSocket ser;//服务器对象
public GamePane(MainFrame frame) {
this.frame = frame;
setLayout(null);
js = new JScrollPane((jl = new JList<String>()));
jl.setFont(new Font("仿宋", Font.BOLD, 25));
add(js);
jt1 = new JTextField(path);
add(jt1);
jt2 = new JTextField("192.168.1.74:3838");
add(jt2);
jb1 = new JButton("刷新");
add(jb1);
jb1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
refresh_jl(new File(path)) ;
}
});
jb2 = new JButton("返回");
add(jb2);
jb2.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
refresh_jl(new File(new File(path).getParent())) ;
} catch (Exception e1) {
System.out.println("已到根目录,不能再返回");
}
}
});
jb3 = new JButton("前进");
add(jb3);
jb3.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
refresh_jl(new File(jt1.getText())) ;
}
});
jb4 = new JButton("发送/接收");
add(jb4);
jb4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
open_jdia();
}
});
jl.addMouseListener(new MouseListener() {
public void mouseReleased(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {
// System.out.println("选择" + jl.getSelectedValue());
jt1.setText(path+jl.getSelectedValue());
if(e.getClickCount()==2) {
open_file();
}
}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseClicked(MouseEvent e) {}
});
}
//双击鼠标左键打开文件
public void open_file() {
String str = path+jl.getSelectedValue();
if(str.endsWith(".jpg") || str.endsWith(".png") || str.endsWith(".mp3") || str.endsWith(".mp4") || str.endsWith(".MP4")) {
String thePlayerPath = "C:\\Program Files\\Windows Media Player\\wmplayer.exe "+str; /*播放器的路径*/
try{
Process ps = Runtime.getRuntime().exec(thePlayerPath);
}catch (IOException e){
e.printStackTrace();
}
}else {
// System.out.println("不是媒体格式");
refresh_jl(new File(jt1.getText())) ;//尝试打开文件夹
}
}
//打开对话框
public void open_jdia() {
JDialog jd = new JDialog(frame, true);
jd.setBounds(frame.getX()+frame.getWidth()/2-250, frame.getY() + frame.getHeight()/2-150, 500, 300);
jd.getContentPane().add(new JScrollPane((jla = new JTextArea())));
jla.setFont(new Font("仿宋", Font.BOLD, 25));
new Thread(new Runnable() {
public void run() {
gettDate();
}
}).start();
//对话框添加监听,关闭对话框关闭服务器
jd.addWindowListener(new WindowListener() {
public void windowOpened(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
public void windowClosing(WindowEvent e) {
if(ser != null) {
try {
ser.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
public void windowClosed(WindowEvent e) {}
public void windowActivated(WindowEvent e) {}
});
jd.setVisible(true);
}
//执行接收或者发送数据
public void gettDate(){
try {
File f = new File(path+jl.getSelectedValue());//获取选择的文件
String ip1 = jt2.getText();//手机ip
String ip2 = InetAddress.getLocalHost().getHostAddress()+":"+3838;
jla.setText("手机ip:"+ip1 + "\n" + "本机ip:"+ip2);
//读取ip
String[] str1 = ip1.split(":");
String[] str2 = ip2.split(":");
ser = new ServerSocket(Integer.parseInt(str2[1]), 1, InetAddress.getByName(str2[0]));
jla.setText(jla.getText() + "\n" + "服务器创建成功,等待连接");
Socket soc = ser.accept();
jla.setText(jla.getText() + "\n" + "已有设备连接,读取请求命令");
InputStream input = soc.getInputStream();
OutputStream output = soc.getOutputStream();
//接收手机机发过来的数据,是接收文件还是发送文件
byte[] b = new byte[1024];
int a = input.read(b, 0, b.length);//尝试读取1024字节数据
int ca = a;
//如果没有读满,继续读,
String stcv = new String(b, 0, a,"utf-8");
String sttr = stcv;
jla.setText(jla.getText() + "\n" + "本次读取到数据:"+ca + "数据详细如下\n"+sttr+"\n分析请求数据中");
//把电脑准备发送的文件发送给手机
String sssr = "ok" + "\r\n" + f.getName() + "\r\n" + f.length()+"\r\n";
OutputStreamWriter or = new OutputStreamWriter(output,"utf-8");
or.write(sssr);//发送指令
or.flush();
//分析请求数据
String[] stty = sttr.split("\r\n");
b = new byte[1024*1000];
if(stty[0].equals("接收") || stty[0].equals("发送")) {
jla.setText(jla.getText() + "\n" + "指令:"+stty[0] + "\n文件名:" + stty[1] + "\n大小:" + stty[2]);
if(stty[0].equals("接收")) {//执行电脑发送数据给手机
InputStream infile = new FileInputStream(f);
jla.setText(jla.getText() + "\n" + "尝试发送数据至手机\r\n文件名:"+f.getName() + "\r\n总共:" + f.length());
a=0;
int alr = 0;
String strlle = jla.getText();
while(a != -1) {
a = infile.read(b);//读取文件数据
if(a != -1) {
alr += a;//记录已发送数据长度
output.write(b, 0, a);//发送文件数据
jla.setText(strlle + "\n" + "已发送:" + alr + "\t总共:" + f.length());
}
}
infile.close();
jla.setText(jla.getText()+ "\n" + "文件已发送");
}else {//接收手机发送过来的文件写入磁盘
OutputStream out1 = new FileOutputStream(new File(path+"/"+stty[1]));
a=0;
int alr = 0 ;
jla.setText(jla.getText() + "\n" + "正在写入文件到磁盘");
String strlle = jla.getText();
while(a != -1) {
a = input.read(b);//获取发送过来的数据
if(a != -1) {
alr+=a;
out1.write(b,0,a);//写入数据至磁盘
jla.setText(strlle + "\n" + "已写入:" + alr + "\t总共:" + stty[2]);
}
}
out1.close();
jla.setText(jla.getText()+ "\n" + "文件已写入磁盘:");
}
}else {
jla.setText(jla.getText() + "\n" + "错误的指令,无法识别");
}
output.close();
input.close();
soc.close();
ser.close();
jla.setText(jla.getText() + "\n" + "程序执行完毕,关闭弹窗即可");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//刷新列表中的内容
public void refresh_jl(File f) {
jl.setListData(gett1(f));
jl.setSelectedIndex(0);
}
//获取指定文件夹下的文件名
public String[] gett1(File file) {
String[] strf = {"文件夹为空"};
if(file.isDirectory()) {
strf = file.list();
path = file.getAbsolutePath();
jt1.setText((path+="/"));
}else {
// System.out.println("该文件不是文件夹");
open_jdia();
jla.setText("不是文件夹,或不支持改媒体文件");
}
return strf;
}
//改变控件大小位置,自适应
public void sett1() {
js.setBounds(getWidth()/2-(int)(getWidth()*(18d/20d))/2, getHeight()/2-(int)(getHeight()*(18d/20d))/2+(int)(getHeight()*(1d/20d)), (int)(getWidth()*(18d/20d)), (int)(getHeight()*(18d/20d)));
jb1.setBounds(10, 10, 100, 30);
jb2.setBounds(120, 10, 100, 30);
jb3.setBounds(230, 10, 100, 30);
jt1.setBounds(340, 10, 300, 30);
jt2.setBounds(650, 10, 200, 30);
jb4.setBounds(860, 10, 100, 30);
}
public void paint(Graphics g) {
super.paint(g);
if(getWidth() != 500 || getHeight() != hh) {
wh = getWidth();
hh = getHeight();
sett1();
}
}
安卓控件布局
控件布局详细代码
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="0dp"
android:layout_height="480dp"
android:layout_marginTop="1dp"
android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ListView
android:id="@+id/list1"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<EditText
android:id="@+id/edit1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="192.168.1.22:3838" />
<TextView
android:id="@+id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/bu1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="发送" />
<Button
android:id="@+id/bu2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="接收" />
</LinearLayout>
</LinearLayout>
安卓逻辑代码MainActivity.java类的详细代码
TextView text1;//提示选择项
String fileName;//选择项文件名
String[] filename ;//存储所有文件名字符串
String path = "sdcard/DCIM/Camera/";//相册路径
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text1 = (TextView) findViewById(R.id.text1);
text1.setText("本机ip:"+getIpAddress(MainActivity.this)+":3838");
ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1,
(filename=gett1(new File("sdcard/DCIM/Camera"))));
ListView listView = (ListView) findViewById(R.id.list1);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
text1.setText("当前选择:"+(fileName=filename[position]));
}
});
Button bu1 = (Button) findViewById(R.id.bu1);
Button bu2 = (Button) findViewById(R.id.bu2);
bu1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
try {
sett1("发送");
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
});
bu2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
new Thread(new Runnable() {
public void run() {
try {
sett1("接收");
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
});
}
//发送或接收文件
public void sett1(String str) throws IOException {//传入指令
//连接电脑
EditText et1 = (EditText) findViewById(R.id.edit1) ;
String[] strt = (et1.getText()+"").split(":");
int port = Integer.parseInt(strt[1]);
Socket soc = new Socket(InetAddress.getByName(strt[0]), port);//连接服务器
InputStream input = soc.getInputStream();
OutputStream out1 = soc.getOutputStream();
File f1 = new File(path+fileName);//本机选择文件
//把文件数据发送到电脑
String sssr = str + "\r\n" + f1.getName() + "\r\n" + f1.length()+"\r\n";
OutputStreamWriter or = new OutputStreamWriter(out1,"utf-8");
or.write(sssr);//发送指令
or.flush();
//接收服务器发过来的文件信息
byte[] b = new byte[1024];
int a = input.read(b, 0, b.length);//尝试读取1024字节数据
int ca = a;
String stcv = new String(b, 0, a,"utf-8");
String sttr = stcv;//读取到的数据,包括真实数据
//分析请求数据
String[] stty = sttr.split("\r\n");
b = new byte[1024*500];
if(str.equals("接收")){
if(stty[0].equals("ok")){
File fil = new File(path+stty[1]);//创建文件
OutputStream out11 = new FileOutputStream(fil);
a=0;
while(a!=-1){
a = input.read(b);
if(a!=-1){
out11.write(b, 0, a);
}
}
out11.close();
}
}
if(str.equals("发送")){
if(stty[0].equals("ok")){
InputStream in1 = new FileInputStream(f1);
b = new byte[1024];
a= 0;
while(a!=-1){
a = in1.read(b);
if(a!=-1){
out1.write(b, 0 , a);
}
}
in1.close();
}
}
input.close();
out1.close();
soc.close();
}
//读取相册文件夹内所有文件返回文件名
//获取指定文件夹下的文件名
public String[] gett1(File file) {
String[] strf = {""};
if(file.isDirectory()) {
strf = file.list();
}else {
System.out.println("该文件不是文件夹");
strf[0] = "不是文件夹";
}
return strf;
}
//获取ip
public static String getIpAddress(Context context) {
// 获取WiFi服务
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// 判断WiFi是否开启
if (wifiManager.isWifiEnabled()) {
// 已经开启了WiFi
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
String ip = intToIp(ipAddress);
return ip;
} else {
// 未开启WiFi
return getIpAddress();
}
}
private static String intToIp(int ipAddress) {
return (ipAddress & 0xFF) + "." +
((ipAddress >> 8) & 0xFF) + "." +
((ipAddress >> 16) & 0xFF) + "." +
(ipAddress >> 24 & 0xFF);
}
private static String getIpAddress() {
try {
NetworkInterface networkInterface;
InetAddress inetAddress;
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
networkInterface = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = networkInterface.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && !inetAddress.isLinkLocalAddress()) {
return inetAddress.getHostAddress();
}
}
}
return null;
} catch (SocketException ex) {
ex.printStackTrace();
return null;
}
}
声明所需权限,因为没有写动态申请权限,需手动给App存储权限才能运行,不然会奔溃,安卓10还要特别注意图中注释