465 lines
18 KiB
Java
465 lines
18 KiB
Java
package com.gh.gamecenter;
|
||
|
||
import android.Manifest;
|
||
import android.content.Intent;
|
||
import android.content.pm.PackageManager;
|
||
import android.os.Bundle;
|
||
import android.os.Handler;
|
||
import android.os.Message;
|
||
import android.support.v4.app.ActivityCompat;
|
||
import android.support.v4.content.ContextCompat;
|
||
import android.support.v7.widget.LinearLayoutManager;
|
||
import android.support.v7.widget.RecyclerView;
|
||
import android.view.View;
|
||
import android.widget.LinearLayout;
|
||
import android.widget.RelativeLayout;
|
||
import android.widget.TextView;
|
||
|
||
import com.facebook.drawee.view.SimpleDraweeView;
|
||
import com.gh.base.AppController;
|
||
import com.gh.base.BaseActivity;
|
||
import com.gh.common.util.DialogUtils;
|
||
import com.gh.common.util.UserIconUtils;
|
||
import com.gh.common.util.Utils;
|
||
import com.gh.gamecenter.adapter.FileSenderAdapter;
|
||
import com.gh.gamecenter.kuaichuan.Constant;
|
||
import com.gh.gamecenter.kuaichuan.FileInfo;
|
||
import com.gh.gamecenter.kuaichuan.FileSender;
|
||
import com.gh.gamecenter.kuaichuan.WifiMgr;
|
||
|
||
import org.json.JSONObject;
|
||
|
||
import java.net.DatagramPacket;
|
||
import java.net.DatagramSocket;
|
||
import java.net.InetAddress;
|
||
import java.net.InetSocketAddress;
|
||
import java.text.DecimalFormat;
|
||
import java.util.ArrayList;
|
||
import java.util.HashMap;
|
||
import java.util.List;
|
||
import java.util.Map;
|
||
|
||
import butterknife.BindView;
|
||
import butterknife.OnClick;
|
||
|
||
/**
|
||
* Created by khy on 2017/1/20.
|
||
*/
|
||
public class FileSenderActivity extends BaseActivity implements FileSenderAdapter.OnCancelListener {
|
||
|
||
@BindView(R.id.sender_rv) RecyclerView mSenderRv;
|
||
@BindView(R.id.sender_user_icon) SimpleDraweeView mSenderUserIcon;
|
||
@BindView(R.id.sender_user_name) TextView mSenderUserName;
|
||
@BindView(R.id.sender_user_send_des) TextView mSenderUserDes;
|
||
@BindView(R.id.sender_hint) TextView mSenderHint;
|
||
@BindView(R.id.sender_keep_send) RelativeLayout mKeepSend;
|
||
@BindView(R.id.sender_bottom) LinearLayout mSenderBottom;
|
||
|
||
private FileSenderAdapter mSenderAdapter;
|
||
|
||
private DatagramSocket mDatagramSocket;
|
||
|
||
private List<FileInfo> mFileInfos;
|
||
private List<Map<String, String>> sendData; // 传送成绩单数据
|
||
private List<FileSender> mFileSenderList;
|
||
|
||
private boolean isSendOver;
|
||
private boolean isDestroy;
|
||
|
||
private long mStartTime;
|
||
|
||
private Handler handler = new Handler() {
|
||
@Override
|
||
public void handleMessage(Message msg) {
|
||
super.handleMessage(msg);
|
||
if (msg.what == FileInfo.FLAG_DEFAULT) {
|
||
int position = (int) msg.obj;
|
||
mFileInfos.get(position).setResult(FileInfo.FLAG_DEFAULT);
|
||
mSenderAdapter.notifyItemChanged(position);
|
||
} else if (msg.what == FileInfo.FLAG_SUCCESS) {
|
||
int position = (int) msg.obj;
|
||
mFileInfos.get(position).setResult(FileInfo.FLAG_SUCCESS);
|
||
mSenderAdapter.notifyItemChanged(position);
|
||
if (position == mFileInfos.size() -1) initSenderHint();
|
||
} else if (msg.what == FileInfo.FLAG_FAILURE) {
|
||
int position = (int) msg.obj;
|
||
mFileInfos.get(position).setResult(FileInfo.FLAG_FAILURE);
|
||
mSenderAdapter.notifyItemChanged(position);
|
||
if (position == mFileInfos.size() -1) initSenderHint();
|
||
} else if (msg.what == FileInfo.FLAG_CANCEL) {
|
||
int position = (int) msg.obj;
|
||
mFileInfos.get(position).setResult(FileInfo.FLAG_CANCEL);
|
||
mSenderAdapter.notifyItemChanged(position);
|
||
if (position == mFileInfos.size() -1) initSenderHint();
|
||
}
|
||
|
||
}
|
||
};
|
||
|
||
@Override
|
||
protected void onCreate(Bundle savedInstanceState) {
|
||
super.onCreate(savedInstanceState);
|
||
View contentView = View.inflate(this, R.layout.activity_file_sender, null);
|
||
init(contentView, "发送游戏");
|
||
|
||
mFileInfos = (List<FileInfo>) AppController.get("FileInfo", false);
|
||
|
||
isDestroy = false;
|
||
|
||
sendData = new ArrayList<>();
|
||
mFileSenderList = new ArrayList<>();
|
||
mSenderAdapter = new FileSenderAdapter(this, mFileInfos);
|
||
mSenderRv.setLayoutManager(new LinearLayoutManager(this));
|
||
mSenderRv.setAdapter(mSenderAdapter);
|
||
|
||
init();
|
||
|
||
findViewById(R.id.actionbar_rl_back).setOnClickListener(new View.OnClickListener() {
|
||
@Override
|
||
public void onClick(View v) {
|
||
backHint();
|
||
}
|
||
});
|
||
}
|
||
|
||
@Override
|
||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||
super.onActivityResult(requestCode, resultCode, data);
|
||
if (resultCode == 0x130 && requestCode == 0x178) {
|
||
mSenderAdapter.notifyDataSetChanged();
|
||
initUserData();
|
||
new Thread(new Runnable() {
|
||
@Override
|
||
public void run() {
|
||
try {
|
||
sendFileInfo();
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
}).start();
|
||
}
|
||
}
|
||
|
||
private void sendFileInfo() throws Exception {
|
||
if (mDatagramSocket == null) {
|
||
mDatagramSocket = new DatagramSocket(null);
|
||
mDatagramSocket.setReuseAddress(true);
|
||
mDatagramSocket.bind(new InetSocketAddress(Constant.DEFAULT_SERVER_SENDING_PORT));
|
||
}
|
||
String ipAddress = WifiMgr.getInstance(this).getIpAddressFromHotspot();
|
||
InetAddress ipAddressName = InetAddress.getByName(ipAddress); // 转译
|
||
//发送apk列表
|
||
for (FileInfo fileInfo : mFileInfos) {
|
||
if (fileInfo.getResult() == 0) { // 过滤已发送过的列表
|
||
String fileInfoJson = FileInfo.toJsonStr(fileInfo);
|
||
Utils.log("FileSenderActivity:: 发送的文件列表::" + fileInfoJson );
|
||
DatagramPacket sendFileInfoListPacket = new DatagramPacket(fileInfoJson.getBytes()
|
||
, fileInfoJson.getBytes().length, ipAddressName, Constant.DEFAULT_SERVER_SENDING_PORT);
|
||
mDatagramSocket.send(sendFileInfoListPacket);
|
||
Utils.log("FileSenderActivity:: 发送的文件列表完成::" + ipAddressName + "==" + Constant.DEFAULT_SERVER_SENDING_PORT);
|
||
}
|
||
}
|
||
|
||
DatagramPacket sendFileInfoListPacket = new DatagramPacket(Constant.MSG_ADD_DATA_OVER.getBytes()
|
||
, Constant.MSG_ADD_DATA_OVER.getBytes().length, ipAddressName, Constant.DEFAULT_SERVER_SENDING_PORT);
|
||
mDatagramSocket.send(sendFileInfoListPacket);
|
||
Utils.log("FileSenderActivity:: 发送结束请求完成");
|
||
}
|
||
|
||
|
||
private void init() {
|
||
|
||
Utils.log("FileSenderActivity == init()");
|
||
|
||
initUserData();
|
||
|
||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||
!= PackageManager.PERMISSION_GRANTED) {
|
||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constant.REQUEST_CODE_WRITE_FILE);
|
||
} else{
|
||
Utils.log("FileSenderActivity == initSendServer()" + mFileInfos.size());
|
||
try {
|
||
initSendServer();//开启传送文件
|
||
startReceiver();
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void startReceiver() {
|
||
new Thread(new Runnable() {
|
||
@Override
|
||
public void run() {
|
||
try {
|
||
initTestReceiverData();
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
}).start();
|
||
}
|
||
|
||
private void initTestReceiverData() throws Exception {
|
||
if (mDatagramSocket == null) {
|
||
mDatagramSocket = new DatagramSocket(null);
|
||
mDatagramSocket.setReuseAddress(true);
|
||
mDatagramSocket.bind(new InetSocketAddress(Constant.DEFAULT_SERVER_SENDING_PORT));
|
||
}
|
||
Utils.log("接收方取消Socket端口" + Constant.DEFAULT_SERVER_SENDING_PORT);
|
||
byte[] receiveData = new byte[1024];
|
||
// 主要接收 接收方取消操作
|
||
while (!isDestroy) {
|
||
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
|
||
mDatagramSocket.receive(receivePacket);
|
||
String response = new String( receivePacket.getData(),0 , receivePacket.getLength()).trim();
|
||
Utils.log("====接收取消消息中。。。" + response);
|
||
if(response != null && response.contains(Constant.MSG_RECEIVER_CANCEL)){
|
||
Utils.log("====接收取消消息完毕。。。" + response);
|
||
|
||
// 进入文件发送列表界面 (并且通知文件接收方进入文件接收列表界面)
|
||
JSONObject jsonObject = new JSONObject(response);
|
||
int cancelPosition = (int) jsonObject.get("controlTag");
|
||
FileSender fileSender = mFileSenderList.get(cancelPosition);
|
||
Message message = new Message();
|
||
message.what = FileInfo.FLAG_CANCEL;
|
||
message.obj = cancelPosition;
|
||
handler.sendMessage(message);
|
||
if (fileSender != null && fileSender.isRunning()) {
|
||
Utils.log("接收方取消发送");
|
||
fileSender.cancel();
|
||
}
|
||
} else if (response != null && response.contains(Constant.MSG_ADD_DATA_OVER)) {
|
||
try {
|
||
Utils.log("====收到UDP结束请求 开始传送文件");
|
||
initSendServer();//开启传送文件
|
||
} catch (Exception e) {
|
||
e.printStackTrace();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//初始化用户数据
|
||
private void initUserData() {
|
||
isSendOver = false;
|
||
|
||
Map<String, String> map = (Map<String, String>) AppController.get("userMap", false);
|
||
|
||
long allGameSize = 0;
|
||
for (FileInfo mFileInfo : mFileInfos) {
|
||
allGameSize = allGameSize + mFileInfo.getSize();
|
||
}
|
||
|
||
double size = (((float)allGameSize/1024)/1024);
|
||
DecimalFormat df = new DecimalFormat("#.00");
|
||
String sizeName = df.format(size) + "MB";
|
||
|
||
mSenderUserDes.setText(mFileInfos.size() + "个游戏,共" + sizeName);
|
||
mSenderUserName.setText("发给 " + map.get("receiverName"));
|
||
mSenderUserIcon.setImageURI(UserIconUtils.getUserIcon(Integer.parseInt(map.get("usericon"))));
|
||
|
||
mSenderBottom.setVisibility(View.GONE);
|
||
|
||
mSenderHint.setText("已连接");
|
||
}
|
||
|
||
private void initSendServer() throws Exception {
|
||
String serverIp = WifiMgr.getInstance(this).getIpAddressFromHotspot();
|
||
|
||
Utils.log("====FileSenderActivity传送个数::" + mFileInfos.size());
|
||
|
||
|
||
// TODO: 发送的首个游戏 socket被拒绝的概率较大 延迟0.5秒发送试试
|
||
Thread.sleep(500); //test
|
||
|
||
for (final FileInfo fileInfo : mFileInfos) {
|
||
Utils.log("FileSenderActivity == initSendServer()===" + fileInfo.getName() + "==" + fileInfo.getResult());
|
||
|
||
if (fileInfo.getResult() != 0) continue; // result != 0 是已经传送过的apk
|
||
|
||
FileSender fileSender = new FileSender(this, fileInfo, serverIp, Constant.DEFAULT_SERVER_PORT);
|
||
fileSender.setOnSendListener(new FileSender.OnSendListener() {
|
||
@Override
|
||
public void onStart() {
|
||
mStartTime = System.currentTimeMillis();
|
||
Utils.log("快传文件发送::onStart" + "==" + fileInfo.getName());
|
||
|
||
}
|
||
|
||
@Override
|
||
public void onProgress(long progress, long total) {
|
||
// Utils.log("快传文件发送中..." + progress + "==" + total + "==" + fileInfo.getName());
|
||
fileInfo.setProgress(progress);
|
||
Message message = new Message();
|
||
message.what = FileInfo.FLAG_DEFAULT;
|
||
message.obj = getCurrentFileInfoIndex(fileInfo);
|
||
handler.sendMessage(message);
|
||
}
|
||
|
||
@Override
|
||
public void onSuccess(FileInfo fileInfo) {
|
||
Utils.log("快传文件发送成功::onSuccess" + "==" + fileInfo.getName());
|
||
Message message = new Message();
|
||
message.what = FileInfo.FLAG_SUCCESS;
|
||
message.obj = getCurrentFileInfoIndex(fileInfo);
|
||
handler.sendMessage(message);
|
||
|
||
long sendTime = System.currentTimeMillis() - mStartTime;
|
||
Map<String, String> map = new HashMap<>();
|
||
map.put("sendTime", String.valueOf(sendTime));
|
||
map.put("apkPath", fileInfo.getFilePath());
|
||
map.put("apkSize", String.valueOf(fileInfo.getSize()));
|
||
sendData.add(map);
|
||
}
|
||
|
||
@Override
|
||
public void onFailure(Throwable t, FileInfo fileInfo) {
|
||
Utils.log("快传文件发送失败::onFailure" + "==" + fileInfo.getName());
|
||
Message message = new Message();
|
||
message.what = FileInfo.FLAG_FAILURE;
|
||
message.obj = getCurrentFileInfoIndex(fileInfo);
|
||
handler.sendMessage(message);
|
||
}
|
||
|
||
@Override
|
||
public void onCancel(FileInfo fileInfo) {
|
||
Utils.log("快传文件用户主动取消::onCancel" + "==" + fileInfo.getName());
|
||
Message message = new Message();
|
||
message.what = FileInfo.FLAG_CANCEL;
|
||
message.obj = getCurrentFileInfoIndex(fileInfo);
|
||
handler.sendMessage(message);
|
||
}
|
||
|
||
});
|
||
mFileSenderList.add(fileSender);
|
||
AppController.FILE_SENDER_EXECUTOR.execute(fileSender);
|
||
}
|
||
}
|
||
|
||
private int getCurrentFileInfoIndex(FileInfo curFileInfo) {
|
||
for (int i = 0; i < mFileInfos.size(); i++) {
|
||
FileInfo fileInfo = mFileInfos.get(i);
|
||
if (curFileInfo == null) {
|
||
return -100;
|
||
}
|
||
if (fileInfo.getFileTag().equals(curFileInfo.getFileTag())) {
|
||
Utils.log("FileSenderActivity === index::" + i);
|
||
return i;
|
||
}
|
||
}
|
||
Utils.log("FileReceiverActivity:: 获取刷新位置异常");
|
||
return -1;
|
||
}
|
||
|
||
private void initSenderHint(){
|
||
for (FileInfo mFileInfo : mFileInfos) {
|
||
if (mFileInfo.getResult() == 0 || mFileInfo.getResult() == 1) { // 还有没完成的任务
|
||
return;
|
||
}
|
||
}
|
||
|
||
mSenderBottom.setVisibility(View.VISIBLE);
|
||
|
||
int sendSuccess = 0;
|
||
isSendOver = true;
|
||
for (FileInfo mFileInfo : mFileInfos) {
|
||
if (mFileInfo.getResult() == FileInfo.FLAG_SUCCESS) {
|
||
sendSuccess ++;
|
||
}
|
||
}
|
||
|
||
if (sendSuccess > 0) {
|
||
mSenderHint.setVisibility(View.VISIBLE);
|
||
mSenderHint.setText("传输结束,成功分享" + sendSuccess + "个游戏");
|
||
} else {
|
||
if (mFileInfos.get(mFileInfos.size() - 1).getResult() == FileInfo.FLAG_CANCEL) {
|
||
mSenderHint.setVisibility(View.VISIBLE);
|
||
mSenderHint.setText("传输已取消");
|
||
} else if (mFileInfos.get(mFileInfos.size() - 1).getResult() == FileInfo.FLAG_FAILURE) {
|
||
mSenderHint.setVisibility(View.VISIBLE);
|
||
mSenderHint.setText("传输失败");
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
@Override
|
||
public void OnCancelPosition(int position) {
|
||
FileSender fileSender = mFileSenderList.get(position);
|
||
Utils.log("发送方准备取消发送" + position);
|
||
if (fileSender != null && fileSender.isRunning()) {
|
||
Utils.log("发送方取消发送");
|
||
fileSender.cancel();
|
||
}
|
||
}
|
||
|
||
@Override
|
||
public void onBackPressed() {
|
||
backHint();
|
||
}
|
||
|
||
@Override
|
||
protected void onDestroy() {
|
||
super.onDestroy();
|
||
isDestroy = true;
|
||
}
|
||
|
||
@OnClick({R.id.actionbar_rl_back, R.id.sender_keep_send, R.id.sender_back})
|
||
public void onClick(View view) {
|
||
if (view.getId() == R.id.actionbar_rl_back || view.getId() == R.id.sender_back) {
|
||
backHint();
|
||
} else if (view.getId() == R.id.sender_keep_send) {
|
||
Intent intent = new Intent(this, KcSelectGameActivity.class);
|
||
intent.putExtra("isConn", true);
|
||
startActivityForResult(intent, 0x178);
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 停止所有的文件发送任务
|
||
*/
|
||
private void stopAllFileSendingTask(){
|
||
for(FileSender fileSender : mFileSenderList){
|
||
if(fileSender != null){
|
||
fileSender.cancel();
|
||
fileSender.finish();
|
||
}
|
||
}
|
||
}
|
||
|
||
public void colsePage() {
|
||
if(mDatagramSocket != null) {
|
||
// mDatagramSocket.disconnect();
|
||
mDatagramSocket.close();
|
||
mDatagramSocket = null;
|
||
}
|
||
|
||
stopAllFileSendingTask();
|
||
AppController.remove("FileInfo");
|
||
AppController.put("sendData", sendData);
|
||
|
||
FileSenderActivity.this.finish();
|
||
}
|
||
|
||
private void backHint() {
|
||
if(!isSendOver){
|
||
DialogUtils.showWarningDialog(FileSenderActivity.this, "退出传送", "退出会中断所有游戏的传送,确定要退出吗?"
|
||
, "取消", "确定"
|
||
, new DialogUtils.ConfiremListener() {
|
||
@Override
|
||
public void onConfirem() {
|
||
colsePage();
|
||
|
||
}
|
||
}, null);
|
||
} else {
|
||
colsePage();
|
||
}
|
||
|
||
|
||
}
|
||
}
|