Files
assistant-android/app/src/main/java/com/gh/gamecenter/FileReceiverActivity.java

633 lines
24 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.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
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.text.TextUtils;
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.constant.Config;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.NotificationUtils;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.UserIconUtils;
import com.gh.common.util.Utils;
import com.gh.download.DownloadDao;
import com.gh.download.DownloadEntity;
import com.gh.download.DownloadStatus;
import com.gh.gamecenter.adapter.FileReceiverAdapter;
import com.gh.gamecenter.eventbus.EBDownloadChanged;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.eventbus.EBPackage;
import com.gh.gamecenter.kuaichuan.BaseTransfer;
import com.gh.gamecenter.kuaichuan.Constant;
import com.gh.gamecenter.kuaichuan.FileInfo;
import com.gh.gamecenter.kuaichuan.FileReceiver;
import com.gh.gamecenter.kuaichuan.HotspotManager;
import com.gh.gamecenter.kuaichuan.IpPortInfo;
import com.gh.gamecenter.kuaichuan.WifiMgr;
import com.gh.gamecenter.manager.DataCollectionManager;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.ServerSocket;
import java.net.Socket;
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;
import de.greenrobot.event.EventBus;
/**
* Created by khy on 2017/1/20.
*/
public class FileReceiverActivity extends BaseActivity implements FileReceiverAdapter.OnReceiverCancelListener{
@BindView(R.id.sender_rv) RecyclerView mReceiverRv;
@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_bottom) LinearLayout mReceiverBottom;
@BindView(R.id.sender_keep_send) RelativeLayout mKeepReceiver;
@BindView(R.id.sender_keep_send_tv) TextView mKeepReceiverTv;
@BindView(R.id.sender_bottom_hint) TextView mReceiverBottomHint;
@BindView(R.id.sender_bottom_control) LinearLayout mReceiverControl;
private FileReceiverAdapter mFileReceiverAdapter;
private FileInfo mCurFileInfo;
private List<FileInfo> mFileInfos;
private List<Map<String, String>> sendData; // 传送成绩单数据
private IpPortInfo mIpPortInfo;
private ServerRunnable mReceiverServer;
private FileReceiver mFileReceiver;
private DatagramSocket mDatagramSocket;
private SharedPreferences sp;
private boolean isReceivesOver;
private boolean isOpenWifi; //记录开热点前的WiFi状态
private boolean isDestroy;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (mFileInfos == null) {
Utils.log("接收器出现异常");
return;
}
int index = getCurrentFileInfoIndex();
if (index == -100) {
Utils.toast(FileReceiverActivity.this, "接收失败");
colsePage();
return;
}
if (index == -1) {
// Utils.toast(FileReceiverActivity.this, " 获取刷新位置异常");
return;
}
FileInfo fileInfo = mFileInfos.get(index);
if (msg.what == FileInfo.FLAG_DEFAULT) { // 传输中更新界面
long progress = (long) msg.obj;
fileInfo.setProgress(progress);
fileInfo.setResult(FileInfo.FLAG_DEFAULT);
} else if (msg.what == FileInfo.FLAG_SUCCESS) { // 传输成功更新界面
fileInfo.setResult(FileInfo.FLAG_SUCCESS);
if (index == mFileInfos.size() -1) initSenderHint(false);
} else if (msg.what == FileInfo.FLAG_FAILURE) { // 传输失败更新界面
fileInfo.setResult(FileInfo.FLAG_FAILURE);
if (index == mFileInfos.size() -1) initSenderHint(false);
} else if (msg.what == FileInfo.FLAG_CANCEL) { // 传输取消更新界面
fileInfo.setResult(FileInfo.FLAG_CANCEL);
if (index == mFileInfos.size() -1) initSenderHint(false);
} else if (msg.what == FileInfo.FLAG_NO_MEMORY) {
Utils.toast(FileReceiverActivity.this, "手机空间不足");
fileInfo.setResult(FileInfo.FLAG_NO_MEMORY); // 接收方内存不足
if (index == mFileInfos.size() -1) initSenderHint(true);
}
Utils.log("FileReceiverActivity:: 刷新位置::" + index + "刷新状态::" + msg.what);
mFileReceiverAdapter.notifyItemChanged(index);
}
};
private int getCurrentFileInfoIndex() {
for (int i = 0; i < mFileInfos.size(); i++) {
FileInfo fileInfo = mFileInfos.get(i);
if (mCurFileInfo == null) {
return -100;
}
if (fileInfo.getFileTag().equals(mCurFileInfo.getFileTag())) {
return i;
}
}
Utils.log("FileReceiverActivity:: 获取刷新位置异常" + mFileInfos.size());
mFileInfos.add(mCurFileInfo);
return mFileInfos.size() - 1;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View contentView = View.inflate(this, R.layout.activity_file_sender, null);
init(contentView, "接收游戏");
isDestroy = false;
// mFileInfos = (List<FileInfo>) AppController.get("FileInfo", false);
sendData = new ArrayList<>();
mIpPortInfo = (IpPortInfo) getIntent().getSerializableExtra(Constant.KEY_IP_PORT_INFO);
isOpenWifi = getIntent().getBooleanExtra("isOpenWifi", false);
ArrayList<Parcelable> list = getIntent().getParcelableArrayListExtra(Constant.KEY_IP_FILE_INFO);
mFileInfos = (List<FileInfo>) list.get(0);
mFileReceiverAdapter = new FileReceiverAdapter(this, mFileInfos);
mReceiverRv.setLayoutManager(new LinearLayoutManager(this));
mReceiverRv.setAdapter(mFileReceiverAdapter);
mKeepReceiverTv.setText("继续接收");
sp = getSharedPreferences(Config.PREFERENCE, Context.MODE_PRIVATE);
initUserData();
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 200);
} else {
initServer(); //启动接收服务
}
findViewById(R.id.actionbar_rl_back).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
backHint();
}
});
}
private void initUserData() {
isReceivesOver = 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("来自 " + mIpPortInfo.getSenderName());
mSenderUserIcon.setImageURI(UserIconUtils.getUserIcon(mIpPortInfo.getSenderIcon()));
mReceiverBottom.setVisibility(View.GONE);
mSenderHint.setText("已连接");
}
/**
* 开启文件接收端服务
*/
private void initServer() {
mReceiverServer = new ServerRunnable(Constant.DEFAULT_SERVER_PORT);
new Thread(mReceiverServer).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
receiverData();
} catch (Exception e) {
Utils.log("FileReceiverActivity:: UDP请求异常" + e.toString() );
e.printStackTrace();
}
}
}).start();
}
private void receiverData() throws Exception {
if (mDatagramSocket == null) {
mDatagramSocket = new DatagramSocket(Constant.DEFAULT_SERVER_SENDING_PORT);
mDatagramSocket.setBroadcast(true);
}
byte[] receiveData = new byte[1024];
Utils.log("FileReceiverActivity:: 开始接收UDP请求::" + Constant.DEFAULT_SERVER_SENDING_PORT + "::" +mDatagramSocket.getInetAddress());
while (!isDestroy) {
Utils.log("FileReceiverActivity:: 开始接收UDP请求" );
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
mDatagramSocket.receive(receivePacket);
String response = new String(receivePacket.getData(), 0, receivePacket.getLength()).trim();
Utils.log("FileReceiverActivity:: 接收UDP请求" + response);
if (response != null && response.equals(Constant.MSG_ADD_DATA_OVER)) {
handler.post(new Runnable() {
@Override
public void run() {
mFileReceiverAdapter.update();
initUserData();
}
});
sendMessageToSender(Constant.MSG_ADD_DATA_OVER);
Utils.log("FileReceiverActivity:: 回复信息" + Constant.MSG_ADD_DATA_OVER);
} else if (response != null) {
parseFileInfo(response);
}
}
}
/**
* 解析FileInfo
* @param msg
*/
private void parseFileInfo(String msg) {
// mFileInfos = (List<FileInfo>) AppController.get("FileInfo", false); // mFileInfos 数据异常 需要重新获取
FileInfo fileInfo = FileInfo.toObject(msg);
if(fileInfo != null && fileInfo.getFilePath() != null){
mFileInfos.add(fileInfo);
Utils.log("FileReceiverActivity 添加一条数据::" + msg);
// AppController.put("FileInfo", mFileInfos);
}
}
@Override
public void OnCancelPosition(final int position) {
// if (position == getCurrentFileInfoIndex()) {
// mFileReceiver.cancel();
// } else {
// Utils.toast(this, "在传送中的游戏才可以取消");
// }
Utils.log("接收方发送取消消息 让发送方取消");
try {
// 接收方更改界面
FileInfo fileInfo = mFileInfos.get(position);
fileInfo.setResult(FileInfo.FLAG_CANCEL);
mFileReceiverAdapter.notifyItemChanged(position);
// 发消息让发送方取消
JSONObject jsonObject = new JSONObject();
jsonObject.put("controlStatus", Constant.MSG_RECEIVER_CANCEL);
jsonObject.put("controlTag", position);
sendMessageToSender(jsonObject.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
//安装事件
public void onEventMainThread(EBPackage busFour) {
if ("安装".equals(busFour.getType())) {
for (int i = 0; i < mFileInfos.size(); i++) {
FileInfo fileInfo = mFileInfos.get(i);
if (fileInfo.getResult() == FileInfo.FLAG_SUCCESS &&
fileInfo.getPackageName().equals(busFour.getPackageName())) {
fileInfo.setResult(FileInfo.FLAG_INSTALLED);
mFileReceiverAdapter.notifyItemChanged(i);
}
}
}
}
private void sendMessageToSender(final String sendData) throws Exception {
new Thread(new Runnable() {
@Override
public void run() {
try {
byte[] bytes = sendData.getBytes(BaseTransfer.UTF_8);
DatagramPacket sendPacket = new DatagramPacket(bytes, bytes.length, mIpPortInfo.getInetAddress(), Constant.DEFAULT_SERVER_SENDING_PORT);
mDatagramSocket.send(sendPacket);
Utils.log("接收方消息已发送至接收方:" + sendData + "==" + mIpPortInfo.getInetAddress() + "==" + Constant.DEFAULT_SERVER_SENDING_PORT);
} catch (Exception e) {
Utils.log("接收方发送消息异常。。" + e.toString());
e.printStackTrace();
}
}
}).start();
}
/**
* ServerSocket启动线程
*/
class ServerRunnable implements Runnable {
ServerSocket serverSocket;
private int port;
public ServerRunnable(int port) {
this.port = port;
}
@Override
public void run() {
Utils.log("接收线程Socket已经开启");
try {
serverSocket = new ServerSocket(Constant.DEFAULT_SERVER_PORT);
while (!Thread.currentThread().isInterrupted()){
Socket socket = serverSocket.accept();
mFileReceiver = new FileReceiver(socket, FileReceiverActivity.this);
mFileReceiver.setOnReceiveListener(new FileReceiver.OnReceiveListener() {
private long mStartTime;
private long mNormalStartTime;
@Override
public void onStart() {
Utils.log("快传文件接收onStart");
mStartTime = Utils.getTime(FileReceiverActivity.this);
mNormalStartTime = System.currentTimeMillis();
}
@Override
public void onGetFileInfo(FileInfo fileInfo) { // 获取FileInfo
mCurFileInfo = fileInfo;
for (int i = 0; i < mFileInfos.size(); i++) {
FileInfo info = mFileInfos.get(i);
if (info.getName(). //NullPointerException
equals(mCurFileInfo.getName())) {
info.setBitmap(fileInfo.getBitmap());
}
}
}
@Override
public void onProgress(long progress, long total) { // 获取传输进度
// Utils.log("快传文件接收中..." + progress + "==" + total);
Message message = new Message();
message.what = FileInfo.FLAG_DEFAULT;
message.obj = progress;
handler.sendMessage(message);
}
@Override
public void onSuccess() { // 获取传输成功
handler.sendEmptyMessage(FileInfo.FLAG_SUCCESS);
String ghVersion = (String) PackageUtils.getMetaData(FileReceiverActivity.this
, mCurFileInfo.getPackageName(), "gh_version");
if (TextUtils.isEmpty(ghVersion)) {
ghVersion = "";
}
long sendTime = Utils.getTime(FileReceiverActivity.this) - mStartTime;
Map<String, Object> hashMap = new HashMap<>();
hashMap.put("send_time", mStartTime);
hashMap.put("receive_time", Utils.getTime(FileReceiverActivity.this));
hashMap.put("game_name", mCurFileInfo.getName());
hashMap.put("package_name", mCurFileInfo.getPackageName());
hashMap.put("package_size", mCurFileInfo.getSize());
hashMap.put("expend_time", sendTime);
hashMap.put("send_nickname", mIpPortInfo.getSenderName());
hashMap.put("receive_nickname", mIpPortInfo.getReceiverName());
hashMap.put("receive_token", sp.getString("token", null));
hashMap.put("package_gh_version", ghVersion);
DataCollectionManager.onEvent(FileReceiverActivity.this, "transfer", hashMap, false);
Utils.log("快传文件接收成功onSuccess:: 发送事件::" + sendTime);
long sendNormalTime = System.currentTimeMillis() - mNormalStartTime;
Map<String, String> map = new HashMap<>();
map.put("sendTime", String.valueOf(sendNormalTime));
map.put("apkPath",Environment.getExternalStorageDirectory() + "/GH-KC/" + mCurFileInfo.getName() + ".apk");
map.put("apkSize", String.valueOf(mCurFileInfo.getSize()));
sendData.add(map);
NotificationUtils.showKuaiChuanDoneNotification(FileReceiverActivity.this,
Environment.getExternalStorageDirectory() + "/GH-KC/" + mCurFileInfo.getName() + ".apk",
mCurFileInfo.getName(), mCurFileInfo.getPackageName());
}
@Override
public void onFailure(Throwable t) { // 获取传输失败
Utils.log("快传文件接收失败onFailure");
handler.sendEmptyMessage(FileInfo.FLAG_FAILURE);
}
@Override
public void onCancel() { // 获取传输取消
Utils.log("快传文件接收取消onCancel");
handler.sendEmptyMessage(FileInfo.FLAG_CANCEL);
}
@Override
public void onNoMemory() {
handler.sendEmptyMessage(FileInfo.FLAG_NO_MEMORY);
}
});
AppController.MAIN_EXECUTOR.execute(mFileReceiver);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 关闭Socket 通信
*/
public void close(){
if(serverSocket != null){
try {
serverSocket.close();
serverSocket = null;
} catch (IOException e) {
}
}
}
}
private void initSenderHint(boolean isNoMemory) {
for (FileInfo mFileInfo : mFileInfos) {
if (mFileInfo.getResult() == 0 || mFileInfo.getResult() == 1) { // 还有没完成的任务
return;
}
}
mReceiverBottom.setVisibility(View.VISIBLE);
mReceiverControl.setVisibility(View.VISIBLE);
isReceivesOver = true;
int sendSuccess = 0;
for (FileInfo mFileInfo : mFileInfos) {
if (mFileInfo.getResult() == FileInfo.FLAG_SUCCESS) {
sendSuccess ++;
}
}
if (isNoMemory) {
mKeepReceiverTv.setText("手机空间清理");
}
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 onBackPressed() {
backHint();
}
@Override
protected void onDestroy() {
super.onDestroy();
isDestroy = true;
handler.removeCallbacksAndMessages(null);
}
@OnClick({R.id.actionbar_rl_back, R.id.sender_keep_send, R.id.sender_back})
public void back(View view) {
switch (view.getId()) {
case R.id.actionbar_rl_back:
backHint();
break;
case R.id.sender_back:
backHint();
break;
case R.id.sender_keep_send:
if ("继续接收".equals(mKeepReceiverTv.getText())) {
// mReceiverControl.setVisibility(View.GONE);
mKeepReceiverTv.setBackgroundResource(R.drawable.game_item_btn_pause_style);
Utils.toast(FileReceiverActivity.this, "无需操作,请让对方继续发送即可");
} else { // 跳转安装包清理
Intent intent = new Intent(this, CleanApkActivity.class);
startActivity(intent);
}
break;
}
}
private void colsePage() {
if(mDatagramSocket != null) {
// mDatagramSocket.disconnect();
mDatagramSocket.close();
mDatagramSocket = null;
}
//关闭热点
HotspotManager.initUserAp(getApplicationContext());
if (isOpenWifi) {
WifiMgr.getInstance(this).openWifi();
}
for (FileInfo fileInfo : mFileInfos) {
if (fileInfo.getResult() == FileInfo.FLAG_SUCCESS) {
DownloadEntity entry = new DownloadEntity();
entry.setName(fileInfo.getName());
entry.setSize(fileInfo.getSize());
entry.setPackageName(fileInfo.getPackageName());
entry.setPath(Environment.getExternalStorageDirectory() + "/GH-KC/" + fileInfo.getName() + ".apk");
entry.setPercent(100.0);
entry.setUrl(fileInfo.getFilePath()); //url拿 路径替代
entry.setStatus(DownloadStatus.done);
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("KuaiChuanIcon", Environment.getExternalStorageDirectory() + "/GH-KC/" + fileInfo.getName() + ".apk");
} catch (JSONException e) {
e.printStackTrace();
}
entry.setIcon(jsonObject.toString());
DownloadDao.getInstance(this).newOrUpdate(entry);
}
}
List<DownloadEntity> all = DownloadDao.getInstance(this).getAll();
EventBus.getDefault().post(new EBDownloadChanged("download", View.VISIBLE, all.size()));
EventBus.getDefault().post(new EBDownloadStatus("download"));
mReceiverServer.close();
// AppController.remove("FileInfo");
mFileInfos.clear();
AppController.put("sendData", sendData);
finish();
}
private void backHint() {
if (isReceivesOver) {
colsePage();
} else {
DialogUtils.showWarningDialog(FileReceiverActivity.this, "退出提示", "退出会中断接收,确定要退出吗?"
, "取消", "确定"
, new DialogUtils.ConfiremListener() {
@Override
public void onConfirem() {
colsePage();
}
}, null);
}
}
}