package io.github.mayubao.kuaichuan.ui; import android.Manifest; import android.content.pm.PackageManager; import android.net.wifi.ScanResult; import android.os.Build; 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.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.ListView; import android.widget.TextView; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import butterknife.Bind; import butterknife.ButterKnife; import butterknife.OnClick; import io.github.mayubao.kuaichuan.AppContext; import io.github.mayubao.kuaichuan.Constant; import io.github.mayubao.kuaichuan.R; import io.github.mayubao.kuaichuan.common.BaseActivity; import io.github.mayubao.kuaichuan.core.BaseTransfer; import io.github.mayubao.kuaichuan.core.entity.FileInfo; import io.github.mayubao.kuaichuan.core.utils.ToastUtils; import io.github.mayubao.kuaichuan.core.utils.WifiMgr; import io.github.mayubao.kuaichuan.ui.adapter.WifiScanResultAdapter; import io.github.mayubao.kuaichuan.ui.view.RadarScanView; import io.github.mayubao.kuaichuan.utils.ListUtils; import io.github.mayubao.kuaichuan.utils.NavigatorUtils; import io.github.mayubao.kuaichuan.utils.NetUtils; /** * Created by mayubao on 2016/11/28. * Contact me 345269374@qq.com */ public class ChooseReceiverActivity extends BaseActivity { private static final String TAG = ChooseReceiverActivity.class.getSimpleName(); /** * Topbar相关UI */ @Bind(R.id.tv_back) TextView tv_back; /** * 其他UI */ @Bind(R.id.radarView) RadarScanView radarScanView; // @Bind(R.id.tab_layout) // TabLayout tab_layout; // @Bind(R.id.view_pager) // ViewPager view_pager; /** * 扫描结果 */ @Bind(R.id.lv_result) ListView lv_result; List<ScanResult> mScanResultList; WifiScanResultAdapter mWifiScanResultAdapter; /** * 与 文件发送方 通信的 线程 */ Runnable mUdpServerRuannable; public static final int MSG_TO_FILE_SENDER_UI = 0X88; //消息:跳转到文件发送列表UI public static final int MSG_TO_SHOW_SCAN_RESULT = 0X99; //消息:更新扫描可连接Wifi网络的列表 Handler mHandler = new Handler(){ @Override public void handleMessage(Message msg) { if(msg.what == MSG_TO_FILE_SENDER_UI){ ToastUtils.show(getContext(), "进入文件发送列表"); NavigatorUtils.toFileSenderListUI(getContext()); finishNormal(); }else if(msg.what == MSG_TO_SHOW_SCAN_RESULT){ getOrUpdateWifiScanResult(); mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TO_SHOW_SCAN_RESULT), 1000); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_choose_receiver); ButterKnife.bind(this); init(); } @Override public void onBackPressed() { super.onBackPressed(); closeSocket(); //断开当前的Wifi网络 WifiMgr.getInstance(getContext()).disconnectCurrentNetwork(); this.finish(); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { if (requestCode == REQUEST_CODE_OPEN_GPS) { if (grantResults.length>0&&grantResults[0] == PackageManager.PERMISSION_GRANTED){ // 允许 updateUI(); } else { // Permission Denied ToastUtils.show(this, getResources().getString(R.string.tip_permission_denied_and_not_get_wifi_info_list)); } return; } super.onRequestPermissionsResult(requestCode, permissions, grantResults); } /** * 成功进入 文件发送列表UI 调用的finishNormal() */ private void finishNormal(){ closeSocket(); this.finish(); } /** * 初始化 */ private void init(){ radarScanView.startScan(); // if(WifiMgr.getInstance(getContext()).isWifiEnable()){//wifi打开的情况 // }else{//wifi关闭的情况 // WifiMgr.getInstance(getContext()).openWifi(); // } if(!WifiMgr.getInstance(getContext()).isWifiEnable()) {//wifi未打开的情况 WifiMgr.getInstance(getContext()).openWifi(); } //Android 6.0 扫描wifi 需要开启定位 if (Build.VERSION.SDK_INT >= 23 ) { //Android 6.0 扫描wifi 需要开启定位 if (ContextCompat.checkSelfPermission(this, Manifest.permission_group.LOCATION)!=PackageManager.PERMISSION_GRANTED){ // 获取wifi连接需要定位权限,没有获取权限 ActivityCompat.requestPermissions(this, new String[]{ Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_WIFI_STATE, }, REQUEST_CODE_OPEN_GPS); return; } }else{//Android 6.0 以下的直接开启扫描 updateUI(); } } /** * 更新UI */ private void updateUI(){ getOrUpdateWifiScanResult(); mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_TO_SHOW_SCAN_RESULT), 1000); } /** * 获取或者更新wifi扫描列表 */ private void getOrUpdateWifiScanResult(){ WifiMgr.getInstance(getContext()).startScan(); mScanResultList = WifiMgr.getInstance(getContext()).getScanResultList(); mScanResultList = ListUtils.filterWithNoPassword(mScanResultList); if(mScanResultList != null){ mWifiScanResultAdapter = new WifiScanResultAdapter(getContext(),mScanResultList); lv_result.setAdapter(mWifiScanResultAdapter); lv_result.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //TODO 进入文件传输部分 ScanResult scanResult = mScanResultList.get(position); Log.i(TAG, "###select the wifi info ======>>>" + scanResult.toString()); //1.连接网络 String ssid = Constant.DEFAULT_SSID; ssid = scanResult.SSID; WifiMgr.getInstance(getContext()).openWifi(); WifiMgr.getInstance(getContext()).addNetwork(WifiMgr.createWifiCfg(ssid, null, WifiMgr.WIFICIPHER_NOPASS)); //2.发送UDP通知信息到 文件接收方 开启ServerSocketRunnable mUdpServerRuannable = createSendMsgToServerRunnable(WifiMgr.getInstance(getContext()).getIpAddressFromHotspot()); AppContext.MAIN_EXECUTOR.execute(mUdpServerRuannable); } }); } } @OnClick({R.id.tv_back, R.id.radarView}) public void onClick(View view){ switch (view.getId()){ case R.id.tv_back:{ onBackPressed(); break; } case R.id.radarView:{ Log.i(TAG, "radarView ------>>> click!"); mUdpServerRuannable = createSendMsgToServerRunnable(WifiMgr.getInstance(getContext()).getIpAddressFromHotspot()); AppContext.MAIN_EXECUTOR.execute(mUdpServerRuannable); break; } } } /** * 创建发送UDP消息到 文件接收方 的服务线程 * @param serverIP */ private Runnable createSendMsgToServerRunnable(final String serverIP){ Log.i(TAG, "receiver serverIp ----->>>" + serverIP); return new Runnable(){ @Override public void run() { try { startFileSenderServer(serverIP, Constant.DEFAULT_SERVER_COM_PORT); } catch (Exception e) { e.printStackTrace(); } } }; } /** * 开启 文件发送方 通信服务 (必须在子线程执行) * @param targetIpAddr * @param serverPort * @throws Exception */ DatagramSocket mDatagramSocket; private void startFileSenderServer(String targetIpAddr, int serverPort) throws Exception{ // Thread.sleep(3*1000); // 确保Wifi连接上之后获取得到IP地址 int count = 0; while(targetIpAddr.equals(Constant.DEFAULT_UNKOWN_IP) && count < Constant.DEFAULT_TRY_TIME){ Thread.sleep(1000); targetIpAddr = WifiMgr.getInstance(getContext()).getIpAddressFromHotspot(); Log.i(TAG, "receiver serverIp ----->>>" + targetIpAddr); count ++; } // 即使获取到连接的热点wifi的IP地址也是无法连接网络 所以采取此策略 count = 0; while(!NetUtils.pingIpAddress(targetIpAddr) && count < Constant.DEFAULT_TRY_TIME){ Thread.sleep(500); Log.i(TAG, "try to ping ----->>>" + targetIpAddr + " - " + count ); count ++; } mDatagramSocket = new DatagramSocket(serverPort); byte[] receiveData = new byte[1024]; byte[] sendData = null; InetAddress ipAddress = InetAddress.getByName(targetIpAddr); //0.发送 即将发送的文件列表 到文件接收方 sendFileInfoListToFileReceiverWithUdp(serverPort, ipAddress); //1.发送 文件接收方 初始化 sendData = Constant.MSG_FILE_RECEIVER_INIT.getBytes(BaseTransfer.UTF_8); DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, ipAddress, serverPort); mDatagramSocket.send(sendPacket); Log.i(TAG, "Send Msg To FileReceiver######>>>" + Constant.MSG_FILE_RECEIVER_INIT); // sendFileInfoListToFileReceiverWithUdp(serverPort, ipAddress); //2.接收 文件接收方 初始化 反馈 while(true) { DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length); mDatagramSocket.receive(receivePacket); String response = new String( receivePacket.getData(), BaseTransfer.UTF_8).trim(); Log.i(TAG, "Get the msg from FileReceiver######>>>" + response); if(response != null && response.equals(Constant.MSG_FILE_RECEIVER_INIT_SUCCESS)){ // 进入文件发送列表界面 (并且通知文件接收方进入文件接收列表界面) mHandler.obtainMessage(MSG_TO_FILE_SENDER_UI).sendToTarget(); } } } /** * 发送即将发送的文件列表到文件接收方 * @param serverPort * @param ipAddress * @throws IOException */ private void sendFileInfoListToFileReceiverWithUdp(int serverPort, InetAddress ipAddress) throws IOException { //1.1将发送的List<FileInfo> 发送给 文件接收方 //如何将发送的数据列表封装成JSON Map<String, FileInfo> sendFileInfoMap = AppContext.getAppContext().getFileInfoMap(); List<Map.Entry<String, FileInfo>> fileInfoMapList = new ArrayList<Map.Entry<String, FileInfo>>(sendFileInfoMap.entrySet()); List<FileInfo> fileInfoList = new ArrayList<FileInfo>(); //排序 Collections.sort(fileInfoMapList, Constant.DEFAULT_COMPARATOR); for(Map.Entry<String, FileInfo> entry : fileInfoMapList){ if(entry.getValue() != null ){ FileInfo fileInfo = entry.getValue(); String fileInfoStr = FileInfo.toJsonStr(fileInfo); DatagramPacket sendFileInfoListPacket = new DatagramPacket(fileInfoStr.getBytes(), fileInfoStr.getBytes().length, ipAddress, serverPort); try{ mDatagramSocket.send(sendFileInfoListPacket); Log.i(TAG, "sendFileInfoListToFileReceiverWithUdp------>>>" + fileInfoStr + "=== Success!"); }catch (Exception e){ Log.i(TAG, "sendFileInfoListToFileReceiverWithUdp------>>>" + fileInfoStr + "=== Failure!"); } } } } /** * 关闭UDP Socket 流 */ private void closeSocket(){ if(mDatagramSocket != null){ mDatagramSocket.disconnect(); mDatagramSocket.close(); mDatagramSocket = null; } } }