Files
assistant-android/app/src/main/java/com/gh/gamecenter/FileSenderActivity.java
2017-03-07 09:46:54 +08:00

465 lines
18 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}
}
}