zoukankan      html  css  js  c++  java
  • PC_android通信之传输图片并显示在手机端【转】

    从服务器 (PC 端 ) 发送图片到客户端 (android 手机端 ) ,并在手机页面上显示该图片。(注:本文旨在实现功能,并未考虑效率,有待后续跟进。)

    1、服务器端

    Java代码   
    1. int port=9090;  
    2.   
    3.   
    4. /** 
    5.  * 发送文件的方法 
    6.  * 此处定义服务器端口为9090,ip地址为192.168.1.1 
    7.  * 设定被传输图片的路径为"images/icon.png" 
    8.  * images文件夹放在此工程的根目录下,我们就可以通过相对路径访问这个图片文件了 
    9.  */  
    10.   
    11.   
    12. private void sendPic() {  
    13.   
    14.     try {  
    15.   
    16.         // 创建服务器  
    17.         java.net.ServerSocket ss = new java.net.ServerSocket(port);  
    18.         // 等待客户机接入,此处会阻塞,直到有客户机接入服务器  
    19.         java.net.Socket client = ss.accept();  
    20.         //创建将要被发送的图片的文件输入流  
    21.         java.io.FileInputStream fin = new java.io.FileInputStream("images/icon.png");  
    22.         //获得套接字的输出流,并包装成数据输出流  
    23.         java.io.DataOutputStream dou = new java.io.DataOutputStream(client  
    24.                 .getOutputStream());  
    25.         // 向输出流中写入文件数据长度  
    26.         dou.writeInt(fin.available());//注:此处未考虑图片太大超出int范围,以至于出现内存溢出的情况       
    27.         // 将实际的图片数据读取到byte[] data中  
    28.         byte[] data = new byte[fin.available()];  
    29.         fin.read(data);  
    30.         // 将图片数据写入到输出流中  
    31.         dou.write(data);  
    32.         dou.flush();  
    33.     } catch (IOException e) {  
    34.         e.printStackTrace();  
    35.     }  
    36.   
    37.   
    38. }  

    2 、 客户端(android手机)

    Java代码   
    1. public class FrontPage extends android.app.Activity implements Runnable {  
    2.   
    3.     public void onCreate(android.os.Bundle savedInstanceState) {  
    4.   
    5.         super.onCreate(savedInstanceState);  
    6.         setContentView(R.layout.frontpage);  
    7.   
    8.         // 启动读取套接字中数据并进行处理的线程  
    9.                 new Thread(this).start();// 本类继承了Runnable接口,所以创建线程时将本类的对象传入即可  
    10.     }  
    11.   
    12.     String ip = "192.168.1.1";  
    13.     int port = 9090;  
    14.     android.widget.ImageView image;// 用于显示接收到的图片的ImageView对象  
    15.   
    16.     /** 
    17.      * 由于输入流的read方法会阻塞,为了避免它影响主界面的其他数据处理, 启动一个线程来读取输入流中的数据,并对数据进行相应的处理 
    18.      */  
    19.     public void run() {  
    20.   
    21.         try {  
    22.             // 创建与服务器的连结  
    23.             java.net.Socket sc = new java.net.Socket(ip, port);  
    24.             // 获得界面显示图片的ImageView对象  
    25.             image = (android.widget.ImageView) findViewById(R.id.image);  
    26.             // 获得套接字的输入流并包装成基本数据输入流  
    27.             java.io.DataInputStream din = new java.io.DataInputStream(sc  
    28.                     .getInputStream());  
    29.   
    30.             // 不断监听输入流的数据情况  
    31.             while (true) {  
    32.                 // 当流中有数据时,读取数据并进行处理  
    33.                 if (din.available() > 0) {  
    34.   
    35.                     // 创建data数组并将流中数据读取到数组中  
    36.                     byte[] data = new byte[din.readInt()];// 注此处同样没有处理图片大小超过int的范围的情况  
    37.                     din.read(data);  
    38.   
    39.                     // 根据读到的文件数据创建Bitmap对象bitmap,因为将要在后面的内部类中使用bitmap,所以定义为  
    40.                     // final型  
    41.                     final android.graphics.Bitmap bitmap = android.graphics.BitmapFactory  
    42.                             .decodeByteArray(data, 0, data.length);  
    43.   
    44.                     // 将图片显示到ImageView上  
    45.                     // 此处由于view中的组件都是线程不安全的,使用android提供的这个办法处理(详见下文“附2”)  
    46.                     image.post(new Runnable() {  
    47.   
    48.                         public void run() {  
    49.                             // 将bitmap显示到界面上  
    50.                                image.setImageBitmap(bitmap);  
    51.                         }  
    52.                     });  
    53.                 }  
    54.   
    55.                 // 线程休息1s  
    56.                 Thread.sleep(1000);  
    57.             }  
    58.   
    59.         } catch (Exception e) {  
    60.             e.printStackTrace();  
    61.         }  
    62.     }  
    63.   
    64. }  

    3、main.xml

    Xml代码   
    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <LinearLayout android:orientation="vertical"  
    3.               android:layout_width="fill_parent"   
    4.               android:layout_height="fill_parent"  
    5.               xmlns:android1="http://schemas.android.com/apk/res/android"  
    6.               xmlns:android="http://schemas.android.com/apk/res/android">  
    7.     <ImageView android:layout_width="wrap_content"  
    8.               android:layout_height="wrap_content"   
    9.               android:id="@+id/image"  
    10.               android:gravity="center" />                
    11. </LinearLayout>  

    附1 、android做通信时需要在AndroidMainFest中添加一个permission:

    Java代码   
    1. <uses-permission android:name="android.permission.INTERNET"></uses-permission>  

    附2 、关于android中view的组件线程不安全,已经有很多前辈对此做了详尽的分析,在此我就不再赘述,只给大家提供一个可供参考的地址:http://www.cnblogs.com/playing/archive/2011/03/24/1993583.html

    附3 、发送和接收数据时,有很多种方法可选,此处使用的byte数组方法有几点需要注意:

           a、new byte[]时,传入的数组大小是int型的,所以我们必须考虑到当文件数据超出整型的范围时,需要辅以别的方法来保证数据的完整性。

           b、从文件读取数据,并写入到输出流时,文中使用的代码是:

    Java代码   
    1. byte[] data = new byte[fin.available()];//创建用于存放文件数据数组  
    2.   
    3. fin.read(data);//将文件数据读取到数组中  
    4.   
    5. dou.write(data);// 将数组写入到输出流中  

          可是不乏有偷懒的码友这样写:

    Java代码   
    1. dou.write(fin.read(new byte[fin.available()]));  
    2.   
    3. //只要我们稍微查看一下JDK就会发现:read()如果因为已经到达文件末尾而没有更多的数据,则返回 <code>-1,这样一来写入到输出流中的可就不是我们的文件数据了哦!</code>  

          更有甚者会这样写:

    Java代码  
    1. dou.write(new byte[fin.available()]);//根本就没有将文件数据读入到数组中  

    以上几种错误都是我自己遇到过的,这类很细节的问题要检查出来都会比较费时间,希望各位码友引以为戒!

  • 相关阅读:
    C#验证类(使用正则表达式)
    SQL数据库还原语句
    JS键盘或鼠标事件
    列表针对列宽度自动调整显示内容,超长以...缩写结尾
    SQL按照日、周、月、年统计数据 (转自BLEACH的blog)
    SQL利用Case When Then多条件判断
    调用Web服务:请求因HTTP状态401失败:Unauthorized
    IFrame自动适应宽高,去掉空白
    Asp调用WebService事例
    Timer不执行Elapsed事件的解决办法
  • 原文地址:https://www.cnblogs.com/tc310/p/3658568.html
Copyright © 2011-2022 走看看