安卓手機wifi面對面快傳的實現

上圖

這裏寫圖片描述
這裏寫圖片描述

先說說大致的佈局框架吧!

主頁面使用tablayout+viewpager實現,

因爲TabLayout和ViewPager分別是屬於design和v4包下的,所以我們先在app的build.gradle中添加:

compile 'com.android.support:design:23.1.1'

然後具體的佈局就自己解決吧!
如果佈局不懂就看這個博客吧
http://www.jianshu.com/p/adf7a994613a

傳輸

這個頁面不多說

發現

發現模塊是一個fragment,裏面一樣放了tablayout+viewpager+fragment。listview裏面放的是design包下面的cardview,看起來新聞也挺美觀的,點擊進去是一個activity,裏面寫了一個Webview和進度條,具體新聞是通過聚合數據解析的。

記錄

裏面是一個gridview裏面放的item,主要是傳輸完後的文件瀏覽
下面是一個自定義view的圓心統計表,記錄接收的流量和發送的流量。

我要發送

進去使用contentprovider掃描手機裏面的音樂、視頻、圖片,自制的一個簡單的文件管理器

好了下面進入正題

我們需要使用面對面快傳,就是一個手機開熱點一個手機開wifi,組件成一個局域網,然後一個手機當client,一個手機當server。所以我們的問題是兩個:

1.wifi的連接。

2.數據的傳輸。

然後我們來一個一個實現

1.wifi的連接

首先需要打開和關閉wifi

下面是app所有需要的權限

    <!-- 創建和刪除 -->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
    <!-- 寫入數據 -->
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
    <!-- 從SDCard讀取數據權限 -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <!-- 以下是使用wifi訪問網絡所需要的權限 -->
    <!-- 修改網絡狀態的權限 -->
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <!-- 修改wifi狀態的權限 -->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <!-- 訪問wifi權限 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!-- 訪問網絡狀態權限 -->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <!-- 訪問網絡權限 -->
    <uses-permission android:name="android.permission.INTERNET" />

關於wifi我自己封裝了一些類
這裏寫圖片描述
所以我就放出主要的調用代碼

打開wifi並且連接到wifi

public class is_Sending extends Activity implements View.OnClickListener {

    private WifiLib wifiLib;//wifi管理類
    private String connectSsid = "My_kuaichuan";//熱點名字
    private boolean isSuccess;
    private TextView textIsConnect;
    boolean flag = true;
    private String received_date;
    private RadarView radarView;
    private Button send_button;
    private Button research_button;


    private void assignViews() {
        research_button = (Button) findViewById(R.id.research_button);
        research_button.setOnClickListener(this);
        View title = findViewById(R.id.title);
        Button button = (Button) title.findViewById(R.id.back_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        TextView textView = (TextView) title.findViewById(R.id.title_tv);
        textView.setText("連接");
        TextView textView1 = (TextView) title.findViewById(R.id.title_lianjie);
        textView1.setText("連接不上?");
        textView1.setVisibility(View.VISIBLE);
        textView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                android.app.AlertDialog.Builder builder = new android.app.AlertDialog.Builder(is_Sending.this);
                builder.setTitle("連接不上");
                builder.setIcon(R.drawable.lw);
                builder.setMessage("如果連接不上My_kuaichuan可以手動連接,密碼爲12345678,再打開該應用,重新連接設備即可!");
                builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                    }
                });
                builder.create();
                builder.show();
            }
        });
        textIsConnect = (TextView) findViewById(R.id.text_is_connect);
        radarView = (RadarView) findViewById(R.id.RadarView);
        radarView.setSearching(true);
        send_button = (Button) findViewById(R.id.send_button);
        send_button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                //連接上了設備後將connected設置爲true,並更新界面提示連接成功,顯示發送按鈕
                SharedPreferences.Editor editor = getSharedPreferences("judge",
                        MODE_PRIVATE).edit();
                editor.putBoolean("connected", true);
                editor.commit();
                textIsConnect.setText("連接成功!");
                radarView.setSearching(false);//停止掃描動畫
                send_button.setVisibility(View.VISIBLE);
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.is__sending);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//沉浸狀態欄
        assignViews();
        //wifi初始化
        WifiLibInitializer.init(this);
        wifiLib = WifiLib.getInstance();
        boolean b = wifiLib.openWifi();//開啓wifi
        wifiLib.setOnWifiBroadcastReceiveCallback(callback);//連接上了設置監聽
        wifiLib.startScan(500);//掃描wifi,時間間隔0.5s
        new Thread(runnable1).start();//開啓接收者


    }

    private WifiBroadcastReceiver.OnWifiBroadcastReceiveCallback callback = new WifiBroadcastReceiver.OnWifiBroadcastReceiveCallback() {
        public void onScanResultsAvailable(
                java.util.List<AccessPoint> accessPoints) {
            WifiUtils.printAccessPoints(accessPoints);
            for (int i = 0; i < accessPoints.size(); i++) {
                AccessPoint ap = accessPoints.get(i);
                if (!TextUtils.isEmpty(connectSsid)
                        && ap.getSsid().equals(connectSsid)) {//如果遍歷到了下面點擊了連接給的ssid就會執行開始連接
                    isSuccess = wifiLib.connectToAccessPoint(ap,
                            "12345678");
                    Log.i("HCY", isSuccess ? "連接熱點成功" : "連接熱點失敗");//三木運算符
                    if (isSuccess) {
                        textIsConnect.setText("正在嘗試連接");
                        new Thread(runnable).start();//開啓了wifi然後開啓發送udp廣播,當對方接收到了廣播就會回播一條數據告訴我已經成功連接
                    } else {
                        textIsConnect.setText("連接熱點失敗");
                    }
                    wifiLib.stopScan();//連接成功停止掃描
                }
            }
        }

        ;
    };


    Runnable runnable = new Runnable() {
        @Override
        public void run() {

            while (flag) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                send(getip(), "1");//發送udp廣播給對方
            }

        }
    };

    Runnable runnable1 = new Runnable() {
        @Override
        public void run() {
            receive();
        }
    };

    //接收對方回發的udp廣播
    public void receive() {
        // 創建接收端的Socket對象
        DatagramSocket ds = null;
        try {
            ds = new DatagramSocket(54321);
            while (true) {
                // 創建一個包裹
                byte[] bys = new byte[1024];
                DatagramPacket dp = new DatagramPacket(bys, bys.length);
                // 接收數據
                ds.receive(dp);
                // 解析數據
                String ip = dp.getAddress().getHostAddress();
                received_date = new String(dp.getData(), 0, dp.getLength());
                System.out.println("from " + ip + " data is : " + received_date);
                if (received_date.equals("11111")) {
                    flag = false;
                    handler.sendEmptyMessage(1);
                }
            }
            // 釋放資源
            // 接收端應該一直開着等待接收數據,是不需要關閉
            // ds.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    //連接上發送udp廣播
    public void send(String ip, String text) {
        // 創建發送端Socket對象
        // DatagramSocket()
        DatagramSocket ds = null;
        try {
            ds = new DatagramSocket();
            // 創建數據,並把數據打包
            // DatagramPacket(byte[] buf, int length, InetAddress address, int port)
            // 創建數據
            byte[] bys = text.getBytes();
            // 長度
            int length = bys.length;
            // IP地址對象
            System.out.println(ip);
            InetAddress address = InetAddress.getByName(ip);
            // 端口
            int port = 10086;
            DatagramPacket dp = new DatagramPacket(bys, length, address, port);

            // 調用Socket對象的發送方法發送數據包
            // public void send(DatagramPacket p)
            ds.send(dp);

            // 釋放資源
            ds.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 獲得主機地址
    private String getip() {
        WifiManager wifiManager = (WifiManager) this
                .getSystemService(Context.WIFI_SERVICE);
        DhcpInfo info = wifiManager.getDhcpInfo();
        return intToIp(info.serverAddress);
    }

    //ip格式化
    private String intToIp(int i) {
        return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF)
                + "." + ((i >> 24) & 0xFF);
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.research_button:
                startActivityForResult(new Intent(this, CaptureActivity.class), 0);
                break;
        }
    }
/**
*下面是進行二維碼掃描返回的數據
*/
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK) {
            Bundle bundle = data.getExtras();
            String result = bundle.getString("result");//當拿到結果
            String[] split = result.split("-");
            String name = split[0];
            String psd = split[1];
            AccessPoint accessPoint = new AccessPoint(name, AccessPoint.SECURITY_WPA2_PSK);
            isSuccess = wifiLib.connectToAccessPoint(accessPoint,
                    psd);
            Log.i("HCY", isSuccess ? "連接熱點成功" : "連接熱點失敗");//三木運算符
            if (isSuccess) {
                textIsConnect.setText("正在嘗試連接");
                new Thread(runnable).start();//開啓了wifi然後開啓發送udp廣播,當對方接收到了廣播就會回播一條數據告訴我已經成功連接
            } else {
                textIsConnect.setText("連接熱點失敗");
            }
            wifiLib.stopScan();//連接成功停止掃描

        }
    }
}

創建熱點

/*
開啓熱點,並且接受文件頁面
 */
public class received_activity extends Activity implements View.OnClickListener {
    private WifiLib wifiLib;
    private ImageView imageView;
    private TextView info;
    private String ip;
    private WhewView whewView;
    HorizontalProgressBarWithNumber progressBar;
    FrameLayout frameLayout;
    LinearLayout linearLayout;
    TextView connect_name;
    ListView list_con;

    private File fileDirectory;
    private File[] listFile;
    List<file_item> list = new ArrayList<>();
    private myadapter myadapter;
    private float leng;
    private ImageView code_image;//二維碼展示
    private RelativeLayout relative_rece;//水波紋界面
    private Button receive_zx;//掃碼發送

    boolean isfirst = false;

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.receive_zx:
                if (!isfirst) {
                    receive_zx.setText("等待連接");
                    Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.lw);
                    Bitmap bitamp = EncodingUtils.createQRCode("My_kuaichuan-12345678", 300, 300, bitmap);
                    code_image.setImageBitmap(bitamp);
                    code_image.setVisibility(View.VISIBLE);
                    relative_rece.setVisibility(View.GONE);
                    isfirst = true;
                } else {
                    receive_zx.setText("掃碼連接");
                    code_image.setVisibility(View.GONE);
                    relative_rece.setVisibility(View.VISIBLE);
                    isfirst = false;
                }

                break;
        }
    }

    private void assignViews() {
        receive_zx = (Button) findViewById(R.id.receive_zx);
        receive_zx.setOnClickListener(this);
        relative_rece = (RelativeLayout) findViewById(R.id.relative_rece);
        code_image = (ImageView) findViewById(R.id.code_image);
        list_con = (ListView) findViewById(R.id.list_con);
        connect_name = (TextView) findViewById(R.id.connect_name);
        linearLayout = (LinearLayout) findViewById(R.id.LinearLayout);
        frameLayout = (FrameLayout) findViewById(R.id.framelayout);
        progressBar = (HorizontalProgressBarWithNumber) findViewById(R.id.connect_pb);
        View view = findViewById(R.id.title);
        TextView textView = (TextView) view.findViewById(R.id.title_tv);
        Button button = (Button) view.findViewById(R.id.back_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tuichu();
            }
        });
        whewView = (WhewView) findViewById(R.id.whewview);
        textView.setText("接收文件");
        info = (TextView) findViewById(R.id.info);
        imageView = (ImageView) findViewById(R.id.imageView);
    }//初始化數據

    /**
     * 退出
     */
    public void tuichu() {
        android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(this);
        builder.setTitle("提示");
        builder.setIcon(R.drawable.lw);
        builder.setMessage("是否關閉熱點並退出??");
        builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                wifiLib.closeWifiAp();
                stopService(new Intent(received_activity.this, Receive_service.class));//關閉接收服務
                finish();
            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
            }
        });
        builder.create();
        builder.show();

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.received_activity);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        assignViews();//初始化數據
        setWifi();//開啓熱點
        whewView.start();//開啓水波紋咻一咻的效果
        new Thread(new Runnable() {
            @Override
            public void run() {
                receive_udp();
            }
        }).start();//開啓udp接收者接收udp,如果連接上了就能接收到
        list_con.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                int length = listFile.length;
                fileDirectory = listFile[length - position - 1];
                openFile(fileDirectory);
            }
        });
        list_con.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
            @Override
            public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
                AlertDialog.Builder builder = new AlertDialog.Builder(received_activity.this);
                builder.setTitle("提示");
                builder.setIcon(R.drawable.lw);
                builder.setMessage("確定刪除??");
                builder.setPositiveButton("確定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        File file = listFile[position];
                        file.delete();
                        show_file_list(fileDirectory);

                    }
                });
                builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        Toast.makeText(received_activity.this, "點擊了取消", Toast.LENGTH_SHORT).show();
                    }
                });
                builder.create();
                builder.show();
                return true;
            }
        });

    }


    //查找當前文件路徑的子文件夾,並顯示在listview列表上
    public void show_file_list(File file) {

        //判斷當前文件目錄下是否有子文件

        if (file.isDirectory()) {
            listFile = file.listFiles();// 返回一個抽象路徑名數組,這些路徑名錶示此抽象路徑名錶示的目錄中的文件
            if (list.size() > 0) {
                list.clear();
            }
            for (int i = 0; i < listFile.length; i++) {
                file_item item = new file_item();//實例化對象


                if (listFile[i].isDirectory()) {
                    //是文件時設置圖標
                    item.setDrawable_int(R.drawable.ll);
                } else {
                    String name = listFile[i].getName();

                    if (name.indexOf(".") == -1) {
                        item.setDrawable_int(R.drawable.le);
                    } else {
                        String[] names = name.split("\\.");
                        if (names[1].equals("txt")) {
                            item.setDrawable_int(R.drawable.m_);
                        } else if (names[1].equals("zip")) {
                            item.setDrawable_int(R.drawable.me);
                        } else if (names[1].equals("jpg")) {
                            item.setDrawable_int(R.drawable.lq);
                        } else if (names[1].equals("mp4")) {
                            item.setDrawable_int(R.drawable.mv);
                        } else if (names[1].equals("mp3")) {
                            item.setDrawable_int(R.drawable.lo);
                        } else {
                            item.setDrawable_int(R.drawable.le);
                        }
                    }


                }
                item.setFile_name(listFile[i].getName());
                list.add(0, item);


            }

            if (myadapter == null) {

                myadapter = new myadapter(list, this);
                list_con.setAdapter(myadapter);
            } else {
                myadapter.notifyDataSetChanged();
            }
        } else {


        }
    }

    /**
     * 打開文件
     *
     * @param file
     */
    private void openFile(File file) {

        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        //設置intent的Action屬性
        intent.setAction(Intent.ACTION_VIEW);
        //獲取文件file的MIME類型
        String type = getMIMEType(file);
        //設置intent的data和Type屬性。
        intent.setDataAndType(/*uri*/Uri.fromFile(file), type);
        //跳轉
        startActivity(intent);

    }

    /**
     * 根據文件後綴名獲得對應的MIME類型。
     *
     * @param file
     */
    private String getMIMEType(File file) {

        String type = "*/*";
        String fName = file.getName();
        //獲取後綴名前的分隔符"."在fName中的位置。
        int dotIndex = fName.lastIndexOf(".");
        if (dotIndex < 0) {
            return type;
        }
    /* 獲取文件的後綴名 */
        String end = fName.substring(dotIndex, fName.length()).toLowerCase();
        if (end == "") return type;
        //在MIME和文件類型的匹配表中找到對應的MIME類型。
        for (int i = 0; i < MIME_MapTable.length; i++) { //MIME_MapTable??在這裏你一定有疑問,這個MIME_MapTable是什麼?
            if (end.equals(MIME_MapTable[i][0]))
                type = MIME_MapTable[i][1];
        }
        return type;
    }

    /**
     * 數組
     */
    private final String[][] MIME_MapTable = {
            //{後綴名,MIME類型}
            {".3gp", "video/3gpp"},
            {".apk", "application/vnd.android.package-archive"},
            {".asf", "video/x-ms-asf"},
            {".avi", "video/x-msvideo"},
            {".bin", "application/octet-stream"},
            {".bmp", "image/bmp"},
            {".c", "text/plain"},
            {".class", "application/octet-stream"},
            {".conf", "text/plain"},
            {".cpp", "text/plain"},
            {".doc", "application/msword"},
            {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
            {".xls", "application/vnd.ms-excel"},
            {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
            {".exe", "application/octet-stream"},
            {".gif", "image/gif"},
            {".gtar", "application/x-gtar"},
            {".gz", "application/x-gzip"},
            {".h", "text/plain"},
            {".htm", "text/html"},
            {".html", "text/html"},
            {".jar", "application/java-archive"},
            {".java", "text/plain"},
            {".jpeg", "image/jpeg"},
            {".jpg", "image/jpeg"},
            {".js", "application/x-javascript"},
            {".log", "text/plain"},
            {".m3u", "audio/x-mpegurl"},
            {".m4a", "audio/mp4a-latm"},
            {".m4b", "audio/mp4a-latm"},
            {".m4p", "audio/mp4a-latm"},
            {".m4u", "video/vnd.mpegurl"},
            {".m4v", "video/x-m4v"},
            {".mov", "video/quicktime"},
            {".mp2", "audio/x-mpeg"},
            {".mp3", "audio/x-mpeg"},
            {".mp4", "video/mp4"},
            {".mpc", "application/vnd.mpohun.certificate"},
            {".mpe", "video/mpeg"},
            {".mpeg", "video/mpeg"},
            {".mpg", "video/mpeg"},
            {".mpg4", "video/mp4"},
            {".mpga", "audio/mpeg"},
            {".msg", "application/vnd.ms-outlook"},
            {".ogg", "audio/ogg"},
            {".pdf", "application/pdf"},
            {".png", "image/png"},
            {".pps", "application/vnd.ms-powerpoint"},
            {".ppt", "application/vnd.ms-powerpoint"},
            {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
            {".prop", "text/plain"},
            {".rc", "text/plain"},
            {".rmvb", "audio/x-pn-realaudio"},
            {".rtf", "application/rtf"},
            {".sh", "text/plain"},
            {".tar", "application/x-tar"},
            {".tgz", "application/x-compressed"},
            {".txt", "text/plain"},
            {".wav", "audio/x-wav"},
            {".wma", "audio/x-ms-wma"},
            {".wmv", "audio/x-ms-wmv"},
            {".wps", "application/vnd.ms-works"},
            {".xml", "text/plain"},
            {".z", "application/x-compress"},
            {".zip", "application/x-zip-compressed"},
            {"", "*/*"}
    };

    /**
     * 開啓熱點
     */
    public void setWifi() {
        WifiLibInitializer.init(this);
        wifiLib = WifiLib.getInstance();
        wifiLib.closeWifi();
        wifiLib.createAccessPoint(WifiApManager.WifiApType.TYPE_WPA_PSK, "My_kuaichuan", "12345678");
    }

    @Override
    public void onBackPressed() {
        tuichu();
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == 1) {
                info.setText("連接成功,等待發送文件");
                code_image.setVisibility(View.GONE);
                relative_rece.setVisibility(View.VISIBLE);
                startService(new Intent(received_activity.this, Receive_service.class));//連接成功開啓服務接收數據

                ////////註冊廣播接收數據更新發過來的實時進度條
                MyRceiver1 myRceiver1 = new MyRceiver1();
                IntentFilter filter1 = new IntentFilter();
                filter1.addAction("com.rec.leng");//數據總長度
                received_activity.this.registerReceiver(myRceiver1, filter1);

                MyRceiver2 myRceiver2 = new MyRceiver2();
                IntentFilter filter2 = new IntentFilter();
                filter2.addAction("com.rec.total");//數據實時進度
                received_activity.this.registerReceiver(myRceiver2, filter2);
                whewView.stop();//動畫停止
                whewView.setVisibility(View.GONE);
                new Thread(runnable).start();//接收成功就回傳udp通知發送端可以發送了
            }


        }
    };

    boolean flag = true;
    Runnable runnable = new Runnable() {
        @Override
        public void run() {

            while (flag) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                sendudp(ip, "11111");
            }
        }
    };//


    public void sendudp(String ip, String text) {
        // 創建發送端Socket對象
        // DatagramSocket()
        DatagramSocket ds = null;
        try {
            ds = new DatagramSocket();
            // 創建數據,並把數據打包
            // DatagramPacket(byte[] buf, int length, InetAddress address, int port)
            // 創建數據
            byte[] bys = text.getBytes();
            // 長度
            int length = bys.length;
            // IP地址對象
            InetAddress address = InetAddress.getByName(ip);
            // 端口
            int port = 54321;
            DatagramPacket dp = new DatagramPacket(bys, length, address, port);

            // 調用Socket對象的發送方法發送數據包
            // public void send(DatagramPacket p)
            ds.send(dp);

            // 釋放資源
            ds.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }//發送udp廣播通知已經接收到了廣播


    public void receive_udp() {
        // 創建接收端的Socket對象
        DatagramSocket ds = null;
        boolean flag = true;
        try {
            ds = new DatagramSocket(10086);
            while (flag) {
                // 創建一個包裹
                byte[] bys = new byte[1024];
                DatagramPacket dp = new DatagramPacket(bys, bys.length);
                // 接收數據
                ds.receive(dp);
                // 解析數據
                ip = dp.getAddress().getHostAddress();
                String received_udpdate = new String(dp.getData(), 0, dp.getLength());

                System.out.println(received_udpdate);

                if (received_udpdate.equals("1")) {
                    Message message = new Message();
                    message.what = 1;
                    handler.sendMessage(message);
                    flag = false;
                }
                System.out.println("from " + ip + " data is : " + received_udpdate);
            }
            // 釋放資源
            // 接收端應該一直開着等待接收數據,是不需要關閉
            ds.close();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }//接收發送過來的廣播

    public static String getPrintSize(long size) {
        size = size / 1024 / 1024;
        size = size * 100;
        return String.valueOf((size / 100)) + "."
                + String.valueOf((size % 100)) + "-MB";
    }//字節轉換

    //廣播1接收數據的長度
    public class MyRceiver1 extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            flag = false;
            frameLayout.setVisibility(View.GONE);
            linearLayout.setVisibility(View.VISIBLE);


            String state = Environment.getExternalStorageState();
            if (state.equals(Environment.MEDIA_MOUNTED)) {
                //獲取shanchuanw文件夾目錄
                fileDirectory = Environment.getExternalStorageDirectory();
                fileDirectory = new File(Environment.getExternalStorageDirectory().getPath() + "/" + "shanchuan");
                show_file_list(fileDirectory);
            }


            Bundle extras = intent.getExtras();
            leng = extras.getInt("leng");
            String fileName = extras.getString("fileName");
            connect_name.setText(fileName);
            progressBar.setMax((int) leng);

            //接收節省的流量
            SharedPreferences pref = getSharedPreferences("judge",
                    MODE_PRIVATE);
            float receivesize = pref.getLong("receivesize", 0);
            float rece_size = receivesize + leng;
            SharedPreferences.Editor editor = getSharedPreferences("judge",
                    MODE_PRIVATE).edit();
            editor.putLong("receivesize", (long) rece_size);
            editor.commit();
        }
    }

    //廣播2接收不停發送過來的實時進度
    public class MyRceiver2 extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            Bundle extras = intent.getExtras();
            float total = extras.getInt("total");

            progressBar.setProgress((int) total);
            if (total == leng) {
//                myadapter.notifyDataSetChanged();
                progressBar.setProgress(0);
                String state = Environment.getExternalStorageState();
                if (state.equals(Environment.MEDIA_MOUNTED)) {
                    //獲取shanchuanw文件夾目錄
                    fileDirectory = Environment.getExternalStorageDirectory();
                    fileDirectory = new File(Environment.getExternalStorageDirectory().getPath() + "/" + "shanchuan");
                    show_file_list(fileDirectory);
                }
            }

        }
    }

    class myadapter extends BaseAdapter {
        List<file_item> list;
        ViewHolder viewHolder;
        private LayoutInflater mLayoutInflater;

        public myadapter(List<file_item> list, Context context) {
            this.list = list;
            mLayoutInflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public Object getItem(int position) {
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                viewHolder = new ViewHolder();
                convertView = mLayoutInflater.inflate(R.layout.frag1_file, null);//填充view對象
                viewHolder.textView = (TextView) convertView
                        .findViewById(R.id.textView);
                viewHolder.imageView = (ImageView) convertView.findViewById(R.id.imageView);

                convertView.setTag(viewHolder);
            } else {

                viewHolder = (ViewHolder) convertView.getTag();
            }
            file_item item = list.get(position);
            viewHolder.textView.setText(item.getFile_name());
            viewHolder.imageView.setImageResource(item.getDrawable_int());
            return convertView;
        }

        public class ViewHolder {
            ImageView imageView;
            TextView textView;
        }
    }


}

好了,看到這裏,我們的兩臺手機已經連接成功了,接下來就可以傳輸文件了

2.數據的傳輸

我們先看下發送代碼

/**
 * Created by Administrator on 2016/7/6.
 */
public class connect_tools {

    public final static int PORT_NUMBER=9999;//端口號
    /**
     * 發送文件
     * @param context 上下文
     * @param fileName 文件名
     * @param path 文件地址
     * @param ipAddress ip地址
     * @param length
     * @param progress
     * @return
     */
    synchronized public static String SendFile(Context context,String fileName, String path, String ipAddress, int length, ProgressDialog progress ) {
        int finished = 0;
        try {
            Socket name = new Socket(ipAddress, PORT_NUMBER);
            OutputStream outputName = name.getOutputStream();
            OutputStreamWriter outputWriter = new OutputStreamWriter(outputName);
            BufferedWriter bwName = new BufferedWriter(outputWriter);
            bwName.write(fileName + "x" + length);
            bwName.close();
            outputWriter.close();
            outputName.close();
            name.close();

            Socket data = new Socket(ipAddress, PORT_NUMBER);
            OutputStream outputData = data.getOutputStream();
            FileInputStream fileInput = new FileInputStream(path);
            int size;
            byte[] buffer = new byte[4028];
            while ((size = fileInput.read(buffer)) != -1) {
                outputData.write(buffer, 0, size);
                finished = finished + size;
                Log.e("upload", finished + "");
                if (finished < length) {
                    progress.setProgress(finished/1024/1024);
                } else {
                    progress.dismiss();
                }
            }
            outputData.close();
            fileInput.close();
            data.close();
            SharedPreferences pref = context.getSharedPreferences("judge",
                    context.MODE_PRIVATE);
            long sendsize = pref.getLong("sendsize",length);
            long rece_size=sendsize+length;
            SharedPreferences.Editor editor =  context.getSharedPreferences("judge",
                    context.MODE_PRIVATE).edit();
            editor.putLong("sendsize",rece_size);
            editor.commit();
            return fileName + "發送完成";
        } catch (UnknownHostException e) {
            progress.dismiss();
            e.printStackTrace();
            return "連接已斷開,傳輸失敗,請重新連接!";
        } catch (FileNotFoundException e) {
            progress.dismiss();

            e.printStackTrace();
            return "文件讀取失敗,請重新嘗試!";
        } catch (IOException e) {
            progress.dismiss();
            e.printStackTrace();
            return "傳輸失敗,請重新嘗試!";
        }


    }

//得到ip地址
    public static String getip(Activity activity) {
        WifiManager wifiManager = (WifiManager) activity
                .getSystemService(Context.WIFI_SERVICE);
        DhcpInfo info = wifiManager.getDhcpInfo();
        return intToIp(info.serverAddress);
    }
//格式化ip地址
    private static String intToIp(int i) {
        return (i & 0xFF) + "." + ((i >> 8) & 0xFF) + "." + ((i >> 16) & 0xFF)
                + "." + ((i >> 24) & 0xFF);
    }
}

調用代碼

    /*
    開啓線程發送文件
    fileDirectory.getName()是得到文件名
    fileDirectory.getPath()是得到文件地址
     connect_tools.getip(getActivity())得到ip地址
     fileInputStream.available()流
     progress是progressdialog
     */
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                String response = connect_tools.SendFile(getContext(), fileDirectory.getName(),
                        fileDirectory.getPath(),
                        connect_tools.getip(getActivity()),
                         fileInputStream.available(), progress);
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println(e.toString());
            }
        }
    };

好了下面是接收代碼我是開了一個intentservice來接收,每次只能接收一個文件,這是一個很大的不足我也沒有仔細修改

public class Receive_service extends Service {

    private String fileName;
    private int leng;


    public Receive_service() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        received();
    }

    private void received() {
        Thread listener = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    //綁定端口
                    int port = connect_tools.PORT_NUMBER;
                    try {
                        ServerSocket server = new ServerSocket(port);
                        String response = ReceiveFile(server);
                        System.out.println("" + response);
                    } catch (IOException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                }
            }
        });
        listener.start();
    }//tcp接收

    synchronized public String ReceiveFile(ServerSocket server) {
        int total = 0;
        try {
            //接收文件名
            Socket name = server.accept();
            InputStream nameStream = name.getInputStream();
            InputStreamReader streamReader = new InputStreamReader(nameStream);
            BufferedReader br = new BufferedReader(streamReader);
            String fileInformation = br.readLine();
            leng = Integer.parseInt(fileInformation.substring(fileInformation.lastIndexOf("x") + 1));

            fileName = fileInformation.substring(0, fileInformation.lastIndexOf("x"));

            Intent intent=new Intent();
            intent.putExtra("leng",leng);
            intent.putExtra("fileName",fileName);
            intent.setAction("com.rec.leng");
            sendBroadcast(intent);//總進度廣播

            br.close();
            streamReader.close();
            nameStream.close();
            name.close();
            //接收文件數據
            Socket data = server.accept();
            InputStream dataStream = data.getInputStream();
            String savePath = myPath() + "/" + fileName;
            FileOutputStream file = new FileOutputStream(savePath, false);

            byte[] buffer = new byte[1024 * 1024];//文件緩存區大小
            int size = -1;
            while ((size = dataStream.read(buffer)) != -1) {
                file.write(buffer, 0, size);
                total = total + size;
                Log.e("get", total + "");
                Intent intent1=new Intent();
                intent1.putExtra("total",total);
                intent1.setAction("com.rec.total");
                sendBroadcast(intent1);//實時進度發送廣播

            }
            file.close();
            dataStream.close();
            data.close();
            return fileName + " 接收完成";
        } catch (Exception e) {
            return "連接已斷開,傳輸失敗,請重新連接!";
        }
    }


    private String myPath() {
        File file = new File(Environment.getExternalStorageDirectory().getPath() + "/" + "shanchuan");
        if (!file.exists())
            file.mkdir();
        return Environment.getExternalStorageDirectory().getPath() + "/" + "shanchuan";
    }
}

做到這裏,我們接受的文件就已經完成了
本人原創wifi傳輸有許多不足的地方,希望大家提出來
下面是我的wifi傳輸的源碼
http://download.csdn.net/detail/z957250254/9608354
如果大家覺得積分有點多 也可以加我qq交流957250254
或者打擊一起進入我們的學習羣 570047049
這裏不僅僅只有安卓,還有懂各種語言、硬件的朋友。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章