Files
assistant-android/app/src/main/java/com/gh/gamecenter/FileReceiverActivity.java
CsHeng 352d7d032e 1、解决toolbar上面文字的问题。。。简直6
2、解决快传文件的一个bug
2017-12-21 17:01:29 +08:00

658 lines
25 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.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.preference.PreferenceManager;
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.BaseActivity;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.PackageUtils;
import com.gh.common.util.StringUtils;
import com.gh.common.util.UserIconUtils;
import com.gh.common.view.VerticalItemDecoration;
import com.gh.gamecenter.adapter.FileReceiverAdapter;
import com.gh.gamecenter.adapter.FileReceiverAdapter.OnReceiverCancelListener;
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.KuaichuanNotification;
import com.gh.gamecenter.kuaichuan.WifiMgr;
import com.gh.gamecenter.manager.DataCollectionManager;
import com.halo.assistant.HaloApp;
import com.lightgame.download.DownloadDao;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
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;
/**
* Created by khy on 2017/1/20.
*/
public class FileReceiverActivity extends BaseActivity implements 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状态
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, "接收失败");
closePage();
return;
}
if (index == -1) {
// Utils.toast(FileReceiverActivity.this, " 获取刷新位置异常");
return;
}
FileInfo fileInfo = mFileInfos.get(index);
switch (msg.what) {
case FileInfo.FLAG_DEFAULT:// 传输中更新界面
long progress = (long) msg.obj;
fileInfo.setProgress(progress);
fileInfo.setResult(FileInfo.FLAG_DEFAULT);
break;
case FileInfo.FLAG_SUCCESS:// 传输成功更新界面
fileInfo.setResult(FileInfo.FLAG_SUCCESS);
if (index == mFileInfos.size() - 1) initSenderHint(false);
break;
case FileInfo.FLAG_FAILURE: // 传输失败更新界面
fileInfo.setResult(FileInfo.FLAG_FAILURE);
if (index == mFileInfos.size() - 1) initSenderHint(false);
break;
case FileInfo.FLAG_CANCEL: // 传输取消更新界面
fileInfo.setResult(FileInfo.FLAG_CANCEL);
if (index == mFileInfos.size() - 1) initSenderHint(false);
break;
case FileInfo.FLAG_NO_MEMORY:
Utils.toast(FileReceiverActivity.this, "手机空间不足");
fileInfo.setResult(FileInfo.FLAG_NO_MEMORY); // 接收方内存不足
if (index == mFileInfos.size() - 1) initSenderHint(true);
break;
}
Utils.log("FileReceiverActivity:: 刷新位置::" + index + "刷新状态::" + msg.what);
mFileReceiverAdapter.notifyItemChanged(index);
}
};
private boolean isDestroy;
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 int getLayoutId() {
return R.layout.activity_receive_send;
}
@Override
public boolean onHandleBackPressed() {
backHint();
return true;
}
private void backHint() {
if (isReceivesOver) {
closePage();
} else {
DialogUtils.showWarningDialog(FileReceiverActivity.this, "退出提示", "退出会中断接收,确定要退出吗?"
, "取消", "确定"
, new DialogUtils.ConfirmListener() {
@Override
public void onConfirm() {
closePage();
}
}, null);
}
}
private void closePage() {
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();
if (all.size() > 0) {
EventBus.getDefault().post(new EBDownloadChanged("download", View.VISIBLE, all.size()));
}
EventBus.getDefault().post(new EBDownloadStatus("download"));
mReceiverServer.close();
// HaloApp.remove(KcSelectGameActivity.KEY_FILE_INFO);
mFileInfos.clear();
HaloApp.put("sendData", sendData);
finish();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setNavigationTitle(R.string.title_file_receive, android.R.color.white);
isDestroy = false;
// mFileInfos = (List<FileInfo>) HaloApp.get(KcSelectGameActivity.KEY_FILE_INFO, 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, this, mFileInfos);
mReceiverRv.setLayoutManager(new LinearLayoutManager(this));
mReceiverRv.addItemDecoration(new VerticalItemDecoration(this, 8, true));
mReceiverRv.setAdapter(mFileReceiverAdapter);
mKeepReceiverTv.setText("继续接收");
sp = PreferenceManager.getDefaultSharedPreferences(this);
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(); //启动接收服务
}
}
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(StringUtils.buildString("来自 ", mIpPortInfo.getSenderName()));
mSenderUserIcon.setImageURI(UserIconUtils.getUserIcon(mIpPortInfo.getSenderIcon()));
mReceiverBottom.setVisibility(View.GONE);
mSenderHint.setText("已连接");
}
/**
* 开启文件接收端服务
*/
private void initServer() {
mReceiverServer = new ServerRunnable(Constant.DEFAULT_SERVER_PORT);
HaloApp.getInstance().getMainExecutor().execute(mReceiverServer);
HaloApp.getInstance().getMainExecutor().execute(new Runnable() {
@Override
public void run() {
try {
receiverData();
} catch (Exception e) {
Utils.log("FileReceiverActivity:: UDP请求异常" + e.toString());
e.printStackTrace();
}
}
});
}
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);
}
}
}
private void sendMessageToSender(final String sendData) throws Exception {
HaloApp.getInstance().getMainExecutor().execute(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();
}
}
});
}
/**
* 解析FileInfo
*
* @param msg
*/
private void parseFileInfo(String msg) {
// mFileInfos = (List<FileInfo>) HaloApp.get(KcSelectGameActivity.KEY_FILE_INFO, false); // mFileInfos 数据异常 需要重新获取
FileInfo fileInfo = FileInfo.toObject(msg);
if (fileInfo != null && fileInfo.getFilePath() != null) {
mFileInfos.add(fileInfo);
Utils.log("FileReceiverActivity 添加一条数据::" + msg);
// HaloApp.put(KcSelectGameActivity.KEY_FILE_INFO, mFileInfos);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
isDestroy = true;
handler.removeCallbacksAndMessages(null);
}
@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();
}
}
//安装事件
@Subscribe(threadMode = ThreadMode.MAIN)
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 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
protected boolean onNavigationIconClicked() {
backHint();
return true;
}
@OnClick({R.id.sender_keep_send, R.id.sender_back})
public void back(View view) {
switch (view.getId()) {
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 { // 跳转安装包清理
startActivity(CleanApkActivity.getIntent(this));
}
break;
}
}
/**
* ServerSocket启动线程
*/
class ServerRunnable implements Runnable {
ServerSocket serverSocket;
private int port;
public ServerRunnable(int port) {
this.port = port;
}
/**
* 关闭Socket 通信
*/
public void close() {
if (serverSocket != null) {
try {
serverSocket.close();
serverSocket = null;
} catch (IOException e) {
}
}
}
@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);
KuaichuanNotification.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);
}
});
HaloApp.getInstance().getMainExecutor().execute(mFileReceiver);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}