最近接到一个项目是关于android与tv交互的一个项目,一共分为两个端,一个是控制端(手机端),一个是播放端,现在需求是这样的,手机端从服务器下载文件,播放端开启热点,手机端链接热点,对播放端进行文件上传,文件排序,文件删除等操作,需求接手之后,首先需要考虑的事情是,要怎么样去实现这个功能呢,现在网上找了找是否有相关的例子,基本上都是通过TCP+UDP实现的,然后整理一下思路,基本就是手机端UDP发送请求到播放器端,播放器端返回一个接收成功的状态,手机端接收到这个状态以后,然后分别进行操作,好了废话不多说,上代码;
先贴出播放器端的部分代码:
因为涉及到文件上传,所以此处MyServiceSocket就是文件下载的socket
new UdpSocketUtils(new UdpSocketLintener() { @Override public void onSuccess(final String str) { runOnUiThread(new Runnable() { @Override public void run() { Gson gson = new GsonBuilder().serializeNulls().create(); LoadBean bean = gson.fromJson(str, LoadBean.class); if (bean.getType() == 1) { Remember.putString("dataname", bean.getName()); new MyServiceSocket().start(); } } }); } @Override public void onError(final String msg) { runOnUiThread(new Runnable() { @Override public void run() { showToast(msg); } }); } }).start();
import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.yunbix.myutils.tool.FileUtil; import com.yunbix.ybmeizhonglv.cache.ConstURL; import com.yunbix.ybmeizhonglv.domain.bean.FileDataBean; import com.yunbix.ybmeizhonglv.domain.bean.FileManageBean; import com.yunbix.ybmeizhonglv.domain.bean.LoadBean; import com.yunbix.ybmeizhonglv.domain.event.ControlMsg; import com.yunbix.ybmeizhonglv.domain.event.DownMsg; import java.io.File; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import de.greenrobot.event.EventBus; public class UdpSocketUtils extends Thread { private final UdpSocketLintener udpSocketLintener; DatagramSocket socket; public UdpSocketUtils(UdpSocketLintener udpSocketLintener) { this.udpSocketLintener = udpSocketLintener; } @Override public void run() { super.run(); while (true) { createUdp(); } } private void createUdp() { try { socket = new DatagramSocket(8888); /*接受数据判定是否发送成功*/ byte[] bytes = new byte[1024]; DatagramPacket rpacket = new DatagramPacket(bytes, bytes.length); socket.receive(rpacket); String s = new String(rpacket.getData(), rpacket.getOffset(), rpacket.getLength()); udpSocketLintener.onSuccess(s); Gson gson = new GsonBuilder().serializeNulls().create(); LoadBean bean = gson.fromJson(s, LoadBean.class); if (bean.getType() == 2) { EventBus.getDefault().post(new ControlMsg(bean.getControl())); } else if (bean.getType() == 3) { /*发送文件信息*/ if (bean.getControl() == 1) { s = getFile(); /*删除文件*/ } else if (bean.getControl() == 2) { String data = bean.getDataPath(); String[] split = data.split(","); boolean b = deleteFile(split); if (b) { s="删除成功"; }else{ s="删除失败"; } EventBus.getDefault().post(new DownMsg()); /*文件排序*/ } else if (bean.getControl() == 3) { String data = bean.getDataPath(); String[] split = data.split(","); boolean b = sortFile(split); if (b) { s="排序成功"; }else{ s="排序失败"; } EventBus.getDefault().post(new DownMsg()); } } else if (bean.getType() == 4) { } else if (bean.getType() == 5) { } /*请求成功返回*/ InetAddress address = rpacket.getAddress(); DatagramPacket packet = new DatagramPacket(s.getBytes(), s.getBytes().length, address, 8888); socket.send(packet); } catch (SocketException e) { e.printStackTrace(); udpSocketLintener.onError(e.getMessage()); } catch (UnknownHostException e) { e.printStackTrace(); udpSocketLintener.onError(e.getMessage()); } catch (IOException e) { e.printStackTrace(); udpSocketLintener.onError(e.getMessage()); } finally { if (socket != null) { socket.close(); } } } /*获取文件信息*/ private String getFile() { FileDataBean bean = new FileDataBean(); List<FileManageBean> list = new ArrayList<>(); File file = new File(FileUtil.projectPath); File[] f = file.listFiles(); for (File fs : f) { if (fs.isFile()) { FileManageBean bean1 = new FileManageBean(); FileDateUtils utils = new FileDateUtils(); HashMap<String, String> map = utils.getFileDate(); for (Map.Entry<String, String> e : map.entrySet()) { if (e.getKey().equals(utils.getFileId(fs.getName()))) { bean1.setCreateTime(e.getValue()); } } bean1.setIsChoose("0"); bean1.setName(fs.getName()); list.add(bean1); } } bean.setInfo(list); Gson gson = new GsonBuilder().serializeNulls().create(); String json = gson.toJson(bean); return json; } /*文件删除*/ private boolean deleteFile( String[] split){ boolean isSuccess=true; File file = new File(FileUtil.projectPath); File[] f = file.listFiles(); FileDateUtils utils = new FileDateUtils(); for (File file1 : f) { for (int i = 0; i < split.length; i++) { if (utils.getFileId(file1.getName()).equals(utils.getFileId(split[i]))) { boolean b = file1.delete(); if (!b) { isSuccess=false; } } } } return isSuccess; } /*文件排序*/ private boolean sortFile(String[] split ){ boolean isSuccess=true; File file = new File(FileUtil.projectPath); File[] f = file.listFiles(); FileDateUtils utils = new FileDateUtils(); for (int i = 0; i < split.length; i++) { for (File file1 : f) { if (utils.getFileId(file1.getName()).equals(utils.getFileId(split[i]))) { String s = chongzuFile((i + 1), split[i]); boolean b = writeName(file1.getAbsolutePath().toString(),FileUtil.projectPath+s); if (!b) { isSuccess=false; } } } } return isSuccess; } /*文件重命名*/ private boolean writeName(String oldpath,String newpath){ File oleFile = new File(oldpath); File newFile = new File(newpath); //执行重命名 boolean b = oleFile.renameTo(newFile); return b; } /*文件序号重组名称*/ private String chongzuFile(int number,String name){ String[] split = name.split(ConstURL.DATA_INTERCEPT); split[0]=number+""; StringBuffer buffer = new StringBuffer(); for (int i = 0; i < split.length; i++) { buffer.append(ConstURL.DATA_INTERCEPT+split[i]); } String substring = buffer.substring(ConstURL.DATA_INTERCEPT.length(), buffer.length()); return substring; }
import android.util.Log; import com.yunbix.ybmeizhonglv.domain.bean.LoadBean; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Date; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by Administrator on 2018/6/17. */ public class MyServiceSocket extends Thread { // 端口 public static int port = 8889; private static ServerSocket server = null; private String tag = "sssssssssssss"; // 存放录音文件的 文件夹 private LoadBean bean; private static ExecutorService mExecutors = null; public void run() { if (server == null) { try { //1、新建ServerSocket实例 server = new ServerSocket(port); } catch (IOException e) { e.printStackTrace(); } } if (mExecutors==null) { mExecutors = Executors.newCachedThreadPool(); } Log.e(tag, new Date().toString() + " \n 服务器启动..."); while (true) { try { //2、访问ServerSocket实例的accept方法取得一个客户端Socket对象 Socket client = server.accept(); if (client == null || client.isClosed()) continue; if (mExecutors != null) { mExecutors.execute(new SocketUpLoad(client)); } } catch (IOException ex) { ex.printStackTrace(); } } } }
import android.util.Log; import com.tumblr.remember.Remember; import com.yunbix.myutils.tool.FileUtil; import com.yunbix.ybmeizhonglv.cache.ConstURL; import com.yunbix.ybmeizhonglv.domain.bean.LoadBean; import com.yunbix.ybmeizhonglv.domain.event.DownMsg; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.net.Socket; import java.util.Date; import de.greenrobot.event.EventBus; public class SocketUpLoad extends Thread { // socket对象 private Socket client; private String tag="sssssssssssssss"; //返回路径(相对路径) private String filepath=FileUtil.projectPath; private LoadBean bean; public SocketUpLoad(Socket client ) { this.client = client; } public void run() { if (client == null) return; DataInputStream in = null; BufferedOutputStream fo = null; DataOutputStream out = null; try { // 1、访问Socket对象的getInputStream方法取得客户端发送过来的数据流 in = new DataInputStream(new BufferedInputStream( client.getInputStream())); //返回文件名和路径 String name = Remember.getString("dataname", ""); String s = name.substring(1,name.length()); filepath = filepath+getFileCount()+ ConstURL.DATA_INTERCEPT+s; // 2、将数据流写到文件中 fo = new BufferedOutputStream(new FileOutputStream(filepath)); int bytesRead = 0; byte[] buffer = new byte[1024*10]; while ((bytesRead = in.read(buffer, 0, buffer.length)) != -1) { fo.write(buffer, 0, bytesRead); } fo.flush(); fo.close(); Log.e(tag,new Date().toString() + " \n 数据接收完毕"); EventBus.getDefault().post(new DownMsg()); new FileDateUtils().saveFileDate(name); // 3、获得Socket的输出流,返回一个值给客户端 out = new DataOutputStream(new BufferedOutputStream( client.getOutputStream())); out.writeInt(1); out.writeUTF(filepath); out.flush(); } catch (Exception ex) { ex.printStackTrace(); try { out.writeInt(0); out.flush(); } catch (IOException e) { System.out.println(new Date().toString() + ":" + e.toString()); } } finally { try { if (out!=null) { out.close(); } if (fo!=null) { fo.close(); } if (in!=null) { in.close(); } client.close(); } catch (IOException e) { System.out.println(new Date().toString() + ":" + e.toString()); } } } /*获取文件总个数*/ private int getFileCount(){ File file = new File(FileUtil.projectPath); int count = file.listFiles().length; return count+1; } }
播放器端代码结束,注释也写的相对清楚,有问题的可以评论或者私信;
手机端的代码:文件上传
new UdpSocketUtils(HOST, json, new UdpSocketLintener() { @Override public void onSuccess(final String str) { LoadBean beans = gson.fromJson(str, LoadBean.class); loadData(beans, new onLoadSuccessListener() { @Override public void onSuccess() { int i = count; i++; if (i<(list.size())) { sendUdp(i); }else { runOnUiThread(new Runnable() { @Override public void run() { showToast("上传成功"); } }); } } @Override public void loadError() { runOnUiThread(new Runnable() { @Override public void run() { showToast("上传失败"); } }); } @Override public void onLoadIng(int progress) { seekbar.setProgress(progress); } }); } @Override public void onError(final String msg) { runOnUiThread(new Runnable() { @Override public void run() { showToast(msg); } }); } }).start();
/*上传文件*/ private void loadData(LoadBean bean,onLoadSuccessListener onLoadSuccessListener) { new SocketService(HOST, bean, onLoadSuccessListener).start(); }
import android.util.Log; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; public class UdpSocketUtils extends Thread { private final String str; private final UdpSocketLintener udpSocketLintener; DatagramSocket socket; private String HOST; public UdpSocketUtils(String HOST, String str,UdpSocketLintener udpSocketLintener) { this.HOST = HOST; this.str = str; this.udpSocketLintener = udpSocketLintener; } @Override public void run() { super.run(); createUdp(); } private void createUdp() { try { /*创建并发送数据请求*/ socket = new DatagramSocket(8888); sendMsg(); /*接受数据判定是否发送成功*/ getmsg(); } catch (SocketException e) { e.printStackTrace(); udpSocketLintener.onError(e.getMessage()); } catch (IOException e) { e.printStackTrace(); udpSocketLintener.onError(e.getMessage()); }finally { if (socket!=null) { socket.close(); } } } /*发送消息*/ private void sendMsg(){ InetAddress serverAddress = null; try { serverAddress = InetAddress.getByName(HOST); byte data[] = str.getBytes(); DatagramPacket packet = new DatagramPacket(data, data.length, serverAddress, 8888); socket.send(packet); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /*接受消息*/ private void getmsg(){ try { byte[] bytes = new byte[1024]; DatagramPacket rpacket = new DatagramPacket(bytes, bytes.length); socket.receive(rpacket); String s = new String(rpacket.getData(), rpacket.getOffset(), rpacket.getLength()); udpSocketLintener.onSuccess(s); } catch (IOException e) { e.printStackTrace(); } } }
import android.util.Log; import com.yunbix.projectorcontroller.domain.bean.LoadBean; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; /* * * udp工具类,发送文件列表 * */ public class SocketService extends Thread{ String tag = "ssssssss"; //socket执行结果 public int status; private String host; private LoadBean bean; private onLoadSuccessListener onLoadSuccessListener; public SocketService() { super(); } public SocketService(String host,LoadBean bean ,onLoadSuccessListener onLoadSuccessListener) { super(); this.host = host; this.bean = bean; this.onLoadSuccessListener = onLoadSuccessListener; } public void sendSocket() { String result = null; FileInputStream reader = null; DataOutputStream out = null; DataInputStream in = null; Socket socket = new Socket(); byte[] buf = null; try { // 连接Socket socket.connect(new InetSocketAddress(host, 8889), 1000); // 1. 读取文件输入流 reader = new FileInputStream(bean.getDataPath()); // 2. 将文件内容写到Socket的输出流中 out = new DataOutputStream(socket.getOutputStream()); int bufferSize = 1024*10; // 20K buf = new byte[bufferSize]; int read = 0; int i = reader.available(); int cuprogress=0; // 将文件输入流 循环 读入 Socket的输出流中 while ((read = reader.read(buf, 0, buf.length)) != -1) { out.write(buf, 0, read); int progress = ((cuprogress += read) * 100) / i; onLoadSuccessListener.onLoadIng(progress); } Log.e(tag, "socket执行完成"); out.flush(); // 一定要加上这句,否则收不到来自服务器端的消息返回 socket.shutdownOutput(); // //获取服务器端的相应 in = new DataInputStream(socket.getInputStream()); status = in.readInt(); result = in.readUTF(); Log.e(tag, "返回结果:" + status + "," + result); onLoadSuccessListener.onSuccess(); } catch (Exception e) { onLoadSuccessListener.loadError(); Log.e(tag, "socket执行异常:" + e.toString()); } finally { try { // 结束对象 buf = null; out.close(); in.close(); reader.close(); socket.close(); } catch (Exception e) { onLoadSuccessListener.loadError(); } } } @Override public void run() { super.run(); sendSocket(); } }代码到这里也就结束了,由于是demo所以就简单的先谢了一下,看看此方法是否可行,运行结果也是没问题的,欢迎大家有问题可以随时评论。