[转]Android的网络与通信

本文转自:http://www.cnblogs.com/qingblog/archive/2012/06/15/2550735.html

 

率先部分 Android网络基础
   Android平台浏览器拔取了WeB基特(Kit)引擎,这款名为Chorme
Lite的Web浏览器拥有强大增加特性,
每个开发者都觉着编写自己的插件,使得浏览器的职能越来越周全。
   近期Android平台有3种网络接口。
  第一种 java.net.*(标准java接口)
  
此接口提供与联网有关的类,包括流和数目包套接字、Internet协议、常见HTTP处理。
如:创建URL以及URLConnection/HttpURLConnection对象、
设置连接参数、连接服务器、向服务器写多少、从服务器读取数据等通信。
   下例为常见java.net包的Http例子:
   try{
    URL url = new URL(“http://www.google.com%22)//概念地址
    HttpURLConnection http = (HttpURLConnection)
url.openConnection();//打开连接
    int nRC = http.getResponseCode();//拿到连续情形
    if(nRC == HttpURLConnection.HTTP_OK){
     InputStream is = http.getInputStream();//取得数据
     …..//处理数据
    }
   }catch(Exception e){
    //因是连接网络,不免会现出有的要命,所以必须处理这些至极
   }
  第二种 Apache接口
   Android提供的Apache HttpClient,它是一个开源项目,功效更加周密,
   为客户端的Http编程提供便捷、最新、效率丰盛的工具包。
   Android如今选拔的是HttpClient4.0(org.apache.http.*),
可将Apache看为当前盛行的开源Web服务器,
最首要不外乎成立HttpClient以及Get/Post、HttpRequest等目的,设置连接参数,执行HTTP操作,
   处理服务器重返结果等效用。
   下例为利用android.net.http.*包的例证:
   try{
    HttpClient hc = new
DefaultHttpClient();//创制HttpClient,这里运用DefaultHttpClient表示默认属性
    HttpGet hg = new
HttpGet(“http://www.google.com%22);//HttpGet实例
    HttpResponse rp = hc.execute(hg);//连接
    if(rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
     InputStream is = rp.getEntity().getContent();
     …..//处理数据
    }
   }catch(IOEeception e){
   }
  第三中 Android网络接口
  
android.net.*包实在是经过Apache中HttpClient的包裹来兑现的一个HTTP编程接口,
与此同时还提供了Http请求队列管理以及Http连接池管理,以增强并发请求情状下(如装载网页时)的频率
   还包括
网络状态监视等接口,网络访问的Socket,常用的Uri类以及有关WiFi相关的类等等。
   下例为最简单易行的Socket连接
   try{
    InetAddress ia = InetAddress.getByName(“192.168.1.110”);//IP地址
    Socket sk = new Socket(inetAddress,61203,true);//端口
    InputStream is =sk.getInputStream();//得到数码
    OutputStream os = sk.getOutputStream();
    …..//数据处理
    os.close();
    is.close();
    sk.close();
   }catch(UnknownHostException e){
   }catch(IOException e){
   }
其次部分 Http通信
   Android提供了HttpURLConnection和HttpClient接口来支付Http程序。
   Http(Hyper Text Transfer
Protocol,超文本传输协议)用于传输WWW格局的多少。
  
HTTP通信中客户端发送的每趟请求都急需服务器回送响应,在伸手截至后,会积极释放连接。
从树立连接到关门连接的进程为”五次连续”。
要确保客户端程序在线状态,需要不停地向服务器发送连接请求。
一般说来的做法是就是不需要获得任何数据,客户端也维持没隔一段固定的刻钟向服务器发送三次“保持连续”的乞求,
服务器在吸纳该请求后对客户端举办还原,讲明知道客户端在线。
若长时间不能吸收客户端的呼吁,则觉得客户端下线,若客户端长时间无从收到服务器的复原,则以为网络已经断开。
有的是动静下,需要劳务器端主动向客户端发送数据以维持客户端与服务器数据的实时与一块。
Http通信中,服务器需要等到客户端发送一次呼吁后才能将数据传回给客户端,
从而,客户端定时向劳动器端发送连接请求,不仅能够保持在线,
再者也是在”询问”服务器是否有新数据,假如有就将数据传给客户端。
  
   Http接纳请求/响应的形式。
客户端向服务器发送一个请求,
请求头包含了请求方法,URI,协议版本,以及含有呼吁修饰符,客户音讯和情节,类似于MIME信息结构。
服务器以一个意况行作为响应,响应的情节涵盖信息协议的本子,成功或不当编码,
还蕴藏服务器音讯,实体元音信以及可能的实体内容。
它是一个属于应用层的面向对象的说道,适用于分布式超媒体信息系列。

  
许多HTTP通信是由一个用户代理初步化的,并且包括一个提请在源服务器上资源的请求。
最简便易行的图景或者是在用户代理和服务器之间通过一个单身的接连来完成。
  
在Internet上,Http通信平常发生在TCP/IP连接上,缺省端口是TCP80.任何端口也是可用的。
  第一种 HttpURLConnection接口
   Http通信中行使最多的是Get和Post.
  
Get请求可用拿到静态页面,也足以把参数放在URL字串的前面,传递给服务器。
   Post参数不是身处URL字串里面,而是放在http请求数据中。
   URLConnection与HttpURLConnection都是抽象类,无法直接实例化对象。
其目的紧要透过URL的openConnection方法取得,
但openConnection方法只是开创URLConnection或者HttpURLConnection
的实例,并不是进展真正的连年操作。
就此在连续往日我们可用对一些特性举行安装
   对HttpConnection实例的习性设置:
    connection.setDoOutput(true);//设置输出流
    connection.setDoInput(true);//设置输出流
    connection.setRequestMethod(“POST”);//设置模式为POST
    connection.setUseCaches(false);//Post请求不可能采用缓存
    urlConn.disconnect();//连接形成之后关闭HttpURLConnection连接
   
   首先在服务器上确立一个不需要传递参数的网页http1.jsp文件。代码如下:
   <HTML>
    <HEAD>
     <TITLE>
      Http Test
     </TITLE>
    </HEAD>
    <BODY>
     <% out.println(“<h1>HTTP TEST<br>http
test</h1>”); %>
    </BODY>
   </HTML>
   再创制一个适用Get和Post来传递参数的网页httpget.jsp 代码如下:
   <%@ page language=”java” import = “java.util.*” pageEncoding =
“gb2312” %>
   <HTML>
    <HEAD>
     <TITLE>
      Http Test
     </TITLE>
    </HEAD>
    <BODY>
     <%
      String type = request.getParameter(“par”);
      String result = new
String(type.getBytes(“iso-8859-1″)),”gb2312”);
      out.println(“<h1>parameters:”+result+”</h1>”);
     %>
    </BODY>
   </HTML>
   以下例中经过Android程序分别以不同的情势访问这六个页面。
   main.xm 文件
   <?xml version=”1.0″ encoding=”utf-8″?>
    <LinearLayout
     xmlns:android=”http://schemas.android.com/apk/res/android
     android:orientation=”vertical”
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”>
     <TextView
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”通过上面的按钮举办不同方法的连天”/>
     <Button
      android:id=”@+id/Button_HTTP”
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”直接获取数据”/>
     <Button
      android:id=”@+id/Button_Get”
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”以GET格局传递数据”/>
     <Button
      android:id=”@+id/Button_Post”
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”以POST格局传递数据”/>
    </LinearLayout>

   http.xml文件
   <?xml version=”1.0″ encoding=”utf-8″?>
    <LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android
     android:orientation=”vertical”
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”
     >
     <TextView 
      android:id=”@+id/TextView_HTTP”
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
     />
     <Button
      android:id=”@+id/Button_Back”
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”返回”/>
    </LinearLayout>
   
   public class Activity01 extends
Activity{//进入界面实现3个控件的Activity
    public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
 
     Button button_http = (Button) findViewById(R.id.Button_HTTP);
     /* 监听button的风波消息 */
     button_http.setOnClickListener(new Button.OnClickListener() {
      public void onClick(View v){
       /* 新建一个Intent对象 */
       Intent intent = new Intent();
       /* 指定intent要开动的类 */
       intent.setClass(Activity01.this, Activity02.class);
       /* 启动一个新的Activity */
       startActivity(intent);
       /* 关闭当前的Activity */
       Activity01.this.finish();
      }
     });
     Button button_Get = (Button) findViewById(R.id.Button_Get);
     /* 监听button的风波新闻 */
     button_Get.setOnClickListener(new Button.OnClickListener() {
      public void onClick(View v){
       /* 新建一个Intent对象 */
       Intent intent = new Intent();
       /* 指定intent要开动的类 */
       intent.setClass(Activity01.this, Activity03.class);
       /* 启动一个新的Activity */
       startActivity(intent);
       /* 关闭当前的Activity */
       Activity01.this.finish();
      }
     });
     Button button_Post = (Button) findViewById(R.id.Button_Post);
     /* 监听button的轩然大波音讯 */
     button_Post.setOnClickListener(new Button.OnClickListener() {
      public void onClick(View v){
       /* 新建一个Intent对象 */
       Intent intent = new Intent();
       /* 指定intent要开动的类 */
       intent.setClass(Activity01.this, Activity04.class);
       /* 启动一个新的Activity */
       startActivity(intent);
       /* 关闭当前的Activity */
       Activity01.this.finish();
      }
     });
    }
   }
  
   public class Activity02 extends Activity{//直接获取数据
    private final String DEBUG_TAG = “Activity02”;
     public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.http);
    
     TextView mTextView =
(TextView)this.findViewById(R.id.TextView_HTTP); 
     String httpUrl =
http://192.168.1.110:8080/http1.jsp%22;//http地址
     String resultData = “”;//得到的数量
     URL url = null;
     try{ 
      url = new URL(httpUrl); //构造一个URL对象
     }catch (MalformedURLException e){
      Log.e(DEBUG_TAG, “MalformedURLException”);
     }
     if (url != null){
      try{   
       HttpURLConnection urlConn = (HttpURLConnection)
url.openConnection();//使用HttpURLConnection打开连接   
       InputStreamReader in = new
InputStreamReader(urlConn.getInputStream());//得到读取的情节(流)   
       BufferedReader buffer = new Buffered里德r(in);//
为出口创造BufferedReader
       String inputLine = null;  
       while (((inputLine = buffer.readLine()) !=
null)){//使用循环来读取拿到的数目   
        resultData += inputLine +
“\n”;//我们在每一行前边加上一个”\n”来换行
       }      
       in.close();//关闭InputStreamReader  
       urlConn.disconnect();//关闭http连接   
       if ( resultData != null ){
        mTextView.setText(resultData);//设置呈现取得的情节
       }else {
        mTextView.setText(“读取的内容为NULL”);
       }
      }catch (IOException e){
       Log.e(DEBUG_TAG, “IOException”);
      }
     }else{
      Log.e(DEBUG_TAG, “Url NULL”);
     } 

     Button button_Back = (Button)
findViewById(R.id.Button_Back);//设置按键事件监听
      button_Back.setOnClickListener(new
Button.OnClickListener(){//监听button的风波音信
       public void onClick(View v){   
        Intent intent = new Intent();
        intent.setClass(Activity02.this, Activity01.class);   
        startActivity(intent);
        Activity02.this.finish();
       }
      });
    }
   }

   public class Activity03 extends Activity{//以Get模式上传参数
    private final String DEBUG_TAG = “Activity03”;
    public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.http);
 
     TextView mTextView =
(TextView)this.findViewById(R.id.TextView_HTTP); 
     String httpUrl =
http://192.168.1.110:8080/httpget.jsp?par=abcdefg%22;//http地方”?par=abcdefg”是大家上传的参数
     String resultData = “”;//获得的数额
     URL url = null;
     try{  
      url = new URL(httpUrl); //构造一个URL对象
     }catch (MalformedURLException e){
      Log.e(DEBUG_TAG, “MalformedURLException”);
     }
     if (url != null){
      try{   
       HttpURLConnection urlConn = (HttpURLConnection)
url.openConnection();// 使用HttpURLConnection打开连接   
       InputStream里德r in = new
InputStream里德r(urlConn.getInputStream());//拿到读取的情节(流)  
       BufferedReader buffer = new BufferedReader(in); //
为出口创立Buffered里德r
       String inputLine = null;   
       while (((inputLine = buffer.readLine()) !=
null)){//使用循环来读取拿到的数目   
        resultData += inputLine +
“\n”;//我们在每一行前边加上一个”\n”来换行
       }       
       in.close();//关闭InputStreamReader   
       urlConn.disconnect();//关闭http连接  
       if ( resultData != null ){
        mTextView.setText(resultData);//设置突显取得的始末
       }else {
        mTextView.setText(“读取的情节为NULL”);
       }
      }catch (IOException e){
       Log.e(DEBUG_TAG, “IOException”);
      }
     }else{
      Log.e(DEBUG_TAG, “Url NULL”);
     }

     Button button_Back = (Button) findViewById(R.id.Button_Back);
      button_Back.setOnClickListener(new Button.OnClickListener() {
       public void onClick(View v){
        Intent intent = new Intent();
        intent.setClass(Activity03.this, Activity01.class);
        startActivity(intent);
        Activity03.this.finish();
       }
      });
    }
   }

   public class Activity04  extends Activity{//以Post形式上传参数
    private final String DEBUG_TAG = “Activity04”;
    public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.http);
 
     TextView mTextView =
(TextView)this.findViewById(R.id.TextView_HTTP);
     String httpUrl =
http://192.168.1.110:8080/httpget.jsp%22;//http地址”?par=abcdefg”是大家上传的参数 
     String resultData = “”;//拿到的数量
     URL url = null;
     try{ 
      url = new URL(httpUrl); //构造一个URL对象
     }catch (MalformedURLException e){
      Log.e(DEBUG_TAG, “MalformedURLException”);
     }
     if (url != null){
      try{  
       HttpURLConnection urlConn = (HttpURLConnection)
url.openConnection();// 使用HttpURLConnection打开连接  
      
urlConn.setDoOutput(true);//因为那个是post请求,设立需要安装为true
       urlConn.setDoInput(true);        
       urlConn.setRequestMethod(“POST”);// 设置以POST方式        
       urlConn.setUseCaches(false);// Post 请求无法利用缓存
       urlConn.setInstanceFollowRedirects(true);        
      
urlConn.setRequestProperty(“Content-Type”,”application/x-www-form-urlencoded”);
//
配置本次连接的Content-type,配置为application/x-www-form-urlencoded的
       //
连接,从postUrl.openConnection()至此的配备必须要在connect以前形成,
       // 要留心的是connection.getOutputStream会隐含的拓展connect。
       urlConn.connect();   
       DataOutputStream out = new
DataOutputStream(urlConn.getOutputStream());//DataOutputStream流         
       String content = “par=” + URLEncoder.encode(“ABCDEFG”,
“gb2312”);//要上传的参数        
       out.writeBytes(content); //将要上传的情节写入流中        
       out.flush();//刷新、关闭
       out.close();          
       Buffered里德r reader = new Buffered里德r(new
InputStreamReader(urlConn.getInputStream()));//获取数据
       String inputLine = null;   
       while(((inputLine = reader.readLine()) !=
null)){//使用循环来读取拿到的数目   
        resultData += inputLine +
“\n”;//我们在每一行前面加上一个”\n”来换行
       }   
       reader.close();
       urlConn.disconnect();//关闭http连接   
       if ( resultData != null ){
        mTextView.setText(resultData);//设置显示取得的始末
       }else{
        mTextView.setText(“读取的情节为NULL”);
       }
      }catch (IOException e){
       Log.e(DEBUG_TAG, “IOException”);
      }
     }else{
      Log.e(DEBUG_TAG, “Url NULL”);
     } 

     Button button_Back = (Button) findViewById(R.id.Button_Back);
      button_Back.setOnClickListener(new Button.OnClickListener(){
       public void onClick(View v){
        Intent intent = new Intent();
        intent.setClass(Activity04.this, Activity01.class);
        startActivity(intent);
        Activity04.this.finish();
       }
      });
    }
   }

  
下面完成的是网络通信自是文件格局的,倘若要显得网络上的一张图纸,连接格局和前面相同,
只需要将连续之后收获数码流转换成Bitmap就足以了。
   下例为展现网络图片的主意
   GetNetBitmap方法
   //取得网络上的图形
   //url:图片地址
   public Bitmap GetNetBitmap(String url){
    URL imageUrl = null;
    Bitmap bitmap = null;
    try{
     imageUrl = new URL(url);
    }catch(MalformedURLException){
     Log.e(DEBUG_TAG,e.getMessage());
    }
    try{
     HttpURLConnection conn =
(HttpURLConnection)imageUrl.openConnection();
     conn.setDoInput(true);
     conn.connect();
     InputStream is =
conn.getInputStream();//将赢得的数目转换成InputStream
     bitmap =
BitmapFactory.decodeStream(is);//将InputStream转换成Bitmap
     id.close();
    }catch(IOException e){
     Log.e(DEBUG_TAG,e.getMessage());
    }
   }

  第二种 HttpClient接口
  
与第一种相相比HttpClient对java.net中的类做了包装和抽象,更符合大家在Android上支付互联网拔取。
   需通晓如下一些类:
   ClinetConnectionManager接口
    此接口是客户端连接管理器接口,有如下抽象方法:
    ClientConnectionManager  关闭所有无效、超时的连年
    closeIdleConnections  关闭空闲的总是
    releaseConnection   释放一个接连
    requestConnection   请求一个新的连续
    shutdown     关闭管理器并释放资源
   DefaultHttpClient
    是默认的一个HTTP客户端,可用它成立一个Http连接 代码如下:
    HttpClinet httpclinet = new HttpClient();
   HttpResponse
   
是一个HTTP连接响应,当执行一个HTTP连接后,就会回去一个HttpResponse,可以透过HttpResponse获得部分响应的信息。
    下例为呼吁一个HTTP连接并取得该请求是否成功的代码:
    HttpResponse httpResponse = httpclient.execute(httpRequest);
    if(httpResponse.getStatusLine(),getStatusCode() ==
HttpStates.SC_OK){//判断是否连接成功
    }
   下例中分头采纳Get和Post形式请求一个网页
   main.xml文件
   <?xml version=”1.0″ encoding=”utf-8″?>
    <LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android
     android:orientation=”vertical”
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”
     >
     <TextView 
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”使用HttpClient来进行GET和POST连接”
     />
     <Button
      android:id=”@+id/Button_Get”
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”以GET形式传递数据”/>
     <Button
      android:id=”@+id/Button_Post”
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”以POST格局传递数据”/>
    </LinearLayout>

   http.xml文件
   <?xml version=”1.0″ encoding=”utf-8″?>
    <LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android
     android:orientation=”vertical”
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”
     >
     <TextView 
      android:id=”@+id/TextView_HTTP”
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
     />
     <Button
      android:id=”@+id/Button_Back”
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”返回”/>
    </LinearLayout>
   
   public class Activity01 extends Activity{
    public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);

     Button button_Get = (Button) findViewById(R.id.Button_Get);
     /* 监听button的风波信息 */
     button_Get.setOnClickListener(new Button.OnClickListener() {
      public void onClick(View v){
       /* 新建一个Intent对象 */
       Intent intent = new Intent();
       /* 指定intent要启动的类 */
       intent.setClass(Activity01.this, Activity02.class);
       /* 启动一个新的Activity */
       startActivity(intent);
       /* 关闭当前的Activity */
       Activity01.this.finish();
      }
     });
     Button button_Post = (Button) findViewById(R.id.Button_Post);
     /* 监听button的轩然大波音信 */
     button_Post.setOnClickListener(new Button.OnClickListener() {
      public void onClick(View v){
       /* 新建一个Intent对象 */
       Intent intent = new Intent();
       /* 指定intent要开动的类 */
       intent.setClass(Activity01.this, Activity03.class);
       /* 启动一个新的Activity */
       startActivity(intent);
       /* 关闭当前的Activity */
       Activity01.this.finish();
      }
     });
    }
   }

   public class Activity02 extends Activity{//Get形式呼吁例子
    public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.http);
     TextView mTextView = (TextView)
this.findViewById(R.id.TextView_HTTP);
 
     String httpUrl =
http://192.168.1.110:8080/httpget.jsp?par=HttpClient_android_Get%22;//
http地址 
     HttpGet httpRequest = new HttpGet(httpUrl);//HttpGet连接对象
     try{ 
      HttpClient httpclient = new
DefaultHttpClient();//取得HttpClient对象
      HttpResponse httpResponse =
httpclient.execute(httpRequest);//请求HttpClient,取得HttpResponse  
      if (httpResponse.getStatusLine().getStatusCode() ==
HttpStatus.SC_OK){//请求成功   
       String strResult =
EntityUtils.toString(httpResponse.getEntity());//取得重回的字符串
       mTextView.setText(strResult);
      }else{
       mTextView.setText(“请求错误!”);
      }
     }catch (ClientProtocolException e){
      mTextView.setText(e.getMessage().toString());
     }catch (IOException e){
      mTextView.setText(e.getMessage().toString());
     }catch (Exception e){
      mTextView.setText(e.getMessage().toString());
     }  
     Button button_Back = (Button)
findViewById(R.id.Button_Back);//设置按键事件监听
      button_Back.setOnClickListener(new Button.OnClickListener() {
       public void onClick(View v){
        Intent intent = new Intent();
        intent.setClass(Activity02.this, Activity01.class);
        startActivity(intent);
        Activity02.this.finish();
       }
      });
    }
   }
 
   public class Activity03 extends Activity{//Post模式请求
    public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.http);
 
     TextView mTextView = (TextView)
this.findViewById(R.id.TextView_HTTP); 
     String httpUrl = “http://192.168.1.110:8080/httpget.jsp%22;//
http地址 
     HttpPost httpRequest = new HttpPost(httpUrl);//HttpPost连接对象
    
     List<NameValuePair> params = new
ArrayList<NameValuePair>();//使用NameValuePair来保存要传送的Post参数 
     params.add(new BasicNameValuePair(“par”,
“HttpClient_android_Post”));//添加要传送的参数
     try{
      HttpEntity httpentity = new UrlEncodedFormEntity(params,
“gb2312”);//设置字符集,Post需要安装所采纳的字符集
      httpRequest.setEntity(httpentity);//请求httpRequest
      HttpClient httpclient = new
DefaultHttpClient();//取得默认的HttpClient
      HttpResponse httpResponse =
httpclient.execute(httpRequest);//取得HttpResponse 
      if (httpResponse.getStatusLine().getStatusCode() ==
HttpStatus.SC_OK){//HttpStatus.SC_OK表示连接成功  
       String strResult =
EntityUtils.toString(httpResponse.getEntity());//取得再次回到的字符串
       mTextView.setText(strResult);
      }else{
       mTextView.setText(“请求错误!”);
      }
     }catch (ClientProtocolException e){
      mTextView.setText(e.getMessage().toString());
     }catch (IOException e){
      mTextView.setText(e.getMessage().toString());
     }catch (Exception e){
      mTextView.setText(e.getMessage().toString());
     }   
     Button button_Back = (Button)
findViewById(R.id.Button_Back);//设置按键事件监听
      button_Back.setOnClickListener(new Button.OnClickListener() {
       public void onClick(View v){
        Intent intent = new Intent();
        intent.setClass(Activity03.this, Activity01.class);
        startActivity(intent);
        Activity03.this.finish();
       }
      });
    }
   }
其三部分 实时更新
   第二有的只是简短地两遍性得到网页数据,
而在实际上支付中更多的是需要我们实时获取最新数据,比如道路流量,实时气象新闻等等。
  
可经过一个线程来决定视图的立异,要实时的从网络获取数据,其实就是把拿到网络数据的代码写到线程中,不停的展开翻新。
  
注意:Android中革新视图不可能一向在线程中开展,所以需要采取Handler来实现革新。
  
下例中大家成立一个网页来显示系统当下的时日,然后每隔5秒系统自动刷新五回视图。
   首先,创设一个出示当前系统时间的jsp网页文件如下:
   date.jsp
   <% page language=”java” import=”java.util.*”
pageEncoding=”gb2312″%>
    <HTML>
     <HEAD>
      <TITLE>
       Date Test
      </TITLE>
     </HEAD>
     <BODY>
      <%java.text.SimpleDateFormat formatter = new
java.text.SimpleDateFormat(“yyyy-MM–dd HH:mm:ss”);>
     </BODY>
    </HTML>
  
   main.xml文件
   <?xml version=”1.0″ encoding=”utf-8″?>
    <LinearLayout
     xmlns:android=”http://schemas.android.com/apk/res/android
     android:orientation=”vertical”
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”
     >
     <TextView 
      android:id=”@+id/TextView01″
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”@string/hello”
     />
     <Button
      android:id=”@+id/Button01″
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”刷新” />
    </LinearLayout>

   public class Activity01 extends Activity{
    private final String DEBUG_TAG = “Activity02”;
     private TextView mTextView;
     private Button mButton;
     public void onCreate(Bundle savedInstanceState){
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
     
      mTextView = (TextView)this.findViewById(R.id.TextView01);
      mButton = (Button)this.findViewById(R.id.Button01);
      mButton.setOnClickListener(new Button.OnClickListener(){
       public void onClick(View arg0){
        refresh();//刷新
       }
      }); 
      new Thread(mRunnable).start();//开启线程
     }
     private void refresh(){//刷新网页显示
      String httpUrl = “http://192.168.1.110:8080/date.jsp“;
      String resultData = “”;
      URL url = null;
      try{  
       url = new URL(httpUrl);// 构造一个URL对象
      }catch (MalformedURLException e){
       Log.e(DEBUG_TAG, “MalformedURLException”);
      }
      if (url != null){
       try{   
        HttpURLConnection urlConn = (HttpURLConnection)
url.openConnection();// 使用HttpURLConnection打开连接   
        InputStream里德r in = new
InputStream里德(Reade)r(urlConn.getInputStream());// 拿到读取的内容(流)   
        BufferedReader buffer = new Buffered里德r(in);//
为出口成立BufferedReader
        String inputLine = null;   
        while (((inputLine = buffer.readLine()) != null)){//
使用循环来读取拿到的数据    
         resultData += inputLine + “\n”;//
我们在每一行前面加上一个”\n”来换行
        }   
        in.close();// 关闭InputStreamReader  
        urlConn.disconnect();// 关闭http连接  
        if (resultData != null){
         mTextView.setText(resultData);// 设置凸显取得的情节
        }else{
         mTextView.setText(“读取的内容为NULL”);
        }
       }catch (IOException e){
        Log.e(DEBUG_TAG, “IOException”);
       }
      }else{
       Log.e(DEBUG_TAG, “Url NULL”);
      }
     }
     private Runnable mRunnable = new Runnable(){
      public void run(){
       while (true){
        try{
         Thread.sleep(5 * 1000);          
         mHandler.sendMessage(mHandler.obtainMessage());//发送消息
        }catch (InterruptedException e){
         Log.e(DEBUG_TAG, e.toString());
        }
       }
      }
     };
     Handler mHandler = new Handler(){
      public void handleMessage(Message msg){
       super.handleMessage(msg);//接受信息      
       refresh();//刷新
      }
     };
   }

第四片段 Socket通信
  
假设要开发一款五个人联网的玩乐,Http已经不可以很好的满意要求了。那时就需要Socket通信了。
   Socket经常称为”套接字”,用于描述IP地址和端口,是一个通信链的句柄。
应用程序通常经过“套接字”向网络发出请求或者应答网络请求。
它是通信的木本,是支撑TCP/IP协议的网络
  
通信的基本操作单元。它是网络通信过程中端点的悬空意味,包含举办网络通信必需的5种消息:
   
连接使用的协议、本地主机的IP地址、本地进程的合计端口、远地主机的IP地址、远地经过的商事端口。
  1、Socket传输形式
   Socket有两种重要操作方法:面向连接的 和 无连接的
    面向连接的Socket操作就像一部电话,必须要等对方接上之后才能打电话。
负有的多寡到达的相继与它出发时的逐一是一模一样的。
面向连接的操作使用TCP协议,即此情势下必须先连续上目的地的Socket,
老是上后Socket就能够利用一个流接口举办打开、读、写、关闭等操作。
所有所发消息都会在另一端以同等的各类被接受。安全性高,但效用低。
   
无连接的就像是一个邮件投递,没有保险,多少个邮件到达时的顺序可能与出发时的相继不一致。
无连接的操作使用数据报协议,一个数据报是一个独立的单元,它富含了这次投递的具有音信。
可将其想象成一个信封,这一个形式下的Socket不需要连续一个指标Socket,它只是简单的投出数据报。
无连接的操作时急迅和飞跃的,可是多少安全性不高。
   
到底用哪一类由应用程序的内需控制。如:文件服务器需要多少的科学和有序性,因选面向连接的。
  2、Socket编程原理
   Socket构造
   
java.net包中提供六个类Socket和ServerSocket,分别用来代表双向连接的客户端和服务器端.
    两类中其构造方法如下:
    Socket(InetAddress address,int port);
    Socket(InetAddress address,int port,boolean stream);
    Socket(String host,int port);
    Socket(String host,int port,boolean stream);
    Socket(SocketImpl impl);
    Socket(String host,int port,InetAddress localAddr,int localPort);
    Socket(InetAddress address,int port,InetAddress localAddr,int
localPort);
    ServerSocket(int port);
    ServerSocket(int port,int backlog);
    ServerSocket(int port,int backlog,InetAddress bindAddr);
    其中参数意义:
     address      双向连接中另一方的IP地址
     host   双向连接中另一方的主机名
     port   双向连接中另一方的端口号
     stream   指明Socket是流Socket仍然数码报Socket
     localPort  本地主机的端口号
     localAddr和bindAddr是地面机械的地址(ServerSocket的主机地址)
     impl  
是Socket的父类,即能够用来创立ServerSocket,又有何不可用来创立Socket
    例:
    //count代表服务端所扶助的最哈拉雷接数
    Socket client = new Socket(“192.168.1.110”,54321);
    ServerSocket server = new ServerSocket(54321);
   
注意:在选用端口时每一个端口对应一个服务,唯有付出正确的端口,才能取得相应的劳务。0~1023的端口号为系统所保存,例如http服务的端口号为80,telent服务的端口号
    为21,ftp服务的端口号为23,所以采取端口号时最好选用一个抢先1023的数
如上的54321,制止暴发争持。在成立Socket时假设爆发错误,将时有暴发IOException,所以在开立Socket
    和ServerSocket时必须捕获或抛出相当。
   Socket 客户端
   
要想采纳Socket来与一个服务器通信,就必须先在客户端创造一个Socket,并提议需要连续的服务器端的IP地址和端口,代码如下:
     try{
      Socket socket = new
Socket(“192.168.1.110”,33221);//”192.168.1.110″是IP地址,33221是端口号
     }catch(IOException e){
     }
   ServerSocket 服务器端
    创造一个劳动器端的代码:
     ServerSocket server = null;
     try{
      server = new
ServerSocket(33221);//服务器端在33221端口号监听客户请求,在此处服务器端只好收到一个伸手,接收后服务器端就淡出了。实际的使用中连续让她不
              
停地循环往复接收,一旦有客户请求,服务器端总是会创设一个服务器线程来服务新来的客户,而团结则连续监听。
     }catch(IOException e){    
     }
     try{
      Socket socket = new
server.accpet();//accpet()为一个绿灯函数,即该格局被调用后将等待客户的呼吁,直到有一个客户启动并请求连接到同一的端口,然后accept
              
重临一个应和于客户端的Socket.这时,客户方和劳动方都建立了用于通信的Socket,接下去就由各种Socket分别打开各自的输入
               输出流。
     }catch(IOExcetion e){
     }
   输入、输出流
    Socket
提供了getInputStream()和getOutPutStream()来拿到相应的输入(输出)流以开展读(写)操作,这两个办法分别重返InputStream和OutputStream类对象。
   
为了便利读(写)数据,可以在回来输入、输出流对象上树立过滤流。如:DataInputStream、DataOutPutStream、或PrintStream类对象。对于文本形式流对象,可以使用
    InputStream里德(Reade)r和OutputStreamWriter、PrintWirter处理 代码如下:
     PrintStream os = new PrintStream(new
BufferedOutputStream(Socket.getOutputStream()));
     DataInputStream is = new
DataInputStream(socket.getInputStream());
     PrintWriter out = new PrintWriter(socket.getOutStream(),true);
     BufferedReader in = new ButfferedReader(new
InputStreamReader(Socket.getInputStream()));
   关闭Socket和流
    在Socket使用完毕后需要将其倒闭,以自由资源。
   
注意:在关门Socket以前,应将与Socket相关的有所的输入、输出流先关闭,以自由资源。要留心关闭的顺序。
     os.close();//输出流先关闭
     is.close();//输入流其次
     socket.close();//最后关闭Socket
   下例中
实现一个服务器和客户端通信。客户端发送数据并收受服务器发回的数码。
    public class Server implements Runnable{//服务器实现
注意:该程序需要独自编译,并在命令行格局下启动
     public void run(){
      try{  
       ServerSocket serverSocket = new
ServerSocket(54321);//创造ServerSocket 设置端口号为54321
       while (true){  
        Socket client =
serverSocket.accept();//通过accept监听接受客户端请求
        System.out.println(“accept”);
        try{   
         Buffered里德r in = new BufferedReader(new
InputStream里德r(client.getInputStream()));//通过BufferedReader对象吸收客户端音信
         String str = in.readLine();
         System.out.println(“read:” + str);    
         PrintWriter out = new PrintWriter( new BufferedWriter( new
OutputStreamWriter(client.getOutputStream())),true); 
//通过PrintWriter向服务器发送音信,但
                                     需要通过Socket对象来取得其出口流
         out.println(“server message”);     
         out.close();//关闭流
         in.close();
        }catch (Exception e){
         System.out.println(e.getMessage());
         e.printStackTrace();
        }finally{    
         client.close();//关闭
         System.out.println(“close”);
        }
       }
      }catch (Exception e){
       System.out.println(e.getMessage());
      }
     }
     public static void main(String a[]){//main函数用来拉开服务器
      Thread desktopServerThread = new Thread(new Server());
      desktopServerThread.start();//开启线程
     }
    }
    public class Activity01 extends Activity{//客户端
     private final String  DEBUG_TAG = “Activity01”;
     private TextView mTextView=null;
     private EditText mEditText=null;
     private Button  mButton=null;
     public void onCreate(Bundle savedInstanceState){
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
 
      mButton = (Button)findViewById(R.id.Button01);
      mTextView=(TextView)findViewById(R.id.TextView01);
      mEditText=(EditText)findViewById(R.id.EditText01);
   
      mButton.setOnClickListener(new OnClickListener(){//登陆
       public void onClick(View v){
        Socket socket = null;
        String message = mEditText.getText().toString() + “\r\n”;
        try {     
         socket = new Socket(“192.168.1.110”,54321);//创立Socket
连接服务器   
         PrintWriter out = new PrintWriter( new BufferedWriter( new
OutputStreamWriter(socket.getOutputStream())),true);
//向服务器发送音信    
         out.println(message);
         Buffered里德r br = new BufferedReader(new
InputStreamReader(socket.getInputStream())); //接收来自服务器的音信
         String msg = br.readLine(); //读取   
         if ( msg != null ){
          mTextView.setText(msg);//接受音信后更新展现到TextView中
         }else{
          mTextView.setText(“数据失实!”);
         }    
          out.close();//关闭流
          br.close();    
          socket.close(); //关闭Socket
        }catch (Exception e) {
         Log.e(DEBUG_TAG, e.toString());
        }
       }
      });
     }
    }
    通过上例总计了眨眼间间:
    使用Socket实现客户端的手续;
     1、通过IP地址和端口实例化Socket,请求连接服务器
     2、获取Socket上的流以开展读写
     3、把流包装进Buffer里德r/PrintWriter的实例
     4、对Socket举行读写
     5、关闭打开的流
    创建服务器的步调:
     1、指定端口实例化一个ServerSocket
     2、调用ServerSocket的accept()以在等候连接期间造成堵塞
     3、获取位于该层Socket的流以开展读写操作
     4、将数据封装成流
     5、对Socket举办读写
     6、关闭打开的流

第五局部 Socket应用—简易聊天室
  
第四部分事例中贯彻了一个客户端和一个服务器的单独通信,并且不得不四遍通信,
在实际中,往往需要在服务器上运行一个永远的顺序,它可以吸纳来自另外六个客户端的乞请,并提供相应服务。
这就需要多线程来促成多客户机制。
服务器总是在指定的端口上监听是否有客户请求,一旦监听到客户请求,
服务器就会启动一个特意的劳动线程来响应该客户的请求,
而服务器本身在开行完线程后及时又进来监听状态,等待下一个客户。
  
   下例中采取Socket通信实现了一个概括的聊天室程序。
   
下例我们需要启动四个客户端来还要连接服务器,一个客户端是Android程序,另一个是Java程序.
第一启动服务器—启动Android客户端—启动另一个PC客户端—-Android客户端
   
发送音讯—-pc客户端发送音讯—Android客户端发送音信—-pc客户端发送信息….
(当一个客户端发送音信(或连续服务器))后,服务器将向具有客户端发送一个音信,
这就需要服务器和客户端间接处于监听状态。
    main.xml文件
    <?xml version=”1.0″ encoding=”utf-8″?>
     <AbsoluteLayout
      xmlns:android=”http://schemas.android.com/apk/res/android
      android:orientation=”vertical”
      android:layout_width=”fill_parent”
      android:layout_height=”fill_parent”
      >
      <EditText
       android:id=”@+id/EditText01″
       android:text=”聊天记录:\n”
       android:layout_width=”fill_parent”
       android:layout_height=”200px”>
      </EditText>
      <EditText
       android:id=”@+id/EditText02″
       android:text=”输入要发送的情节”
       android:layout_width=”fill_parent”
       android:layout_height=”wrap_content”
       android:layout_y=”200px”>
      </EditText>
      <Button
       android:id=”@+id/Button_In”
       android:layout_width=”80px”
       android:layout_height=”wrap_content”
       android:text=”登陆”
       android:layout_x=”30px”
       android:layout_y=”260px”
       /> 
      <Button
       android:id=”@+id/Button_Send”
       android:layout_width=”80px”
       android:layout_height=”wrap_content”
       android:text=”发送”
       android:layout_x=”210px”
       android:layout_y=”260px”
       />
     </AbsoluteLayout>

    public class Server{//服务器端
需要单独编译并在命令行情势下启动测试
     private static final int SERVERPORT = 54321; //服务器端口 
     private static List<Socket> mClientList = new
ArrayList<Socket>(); //客户端连接
通过List来囤积所有连接进来的客户端的Socket对象(也可用CopyOnWriteArrayList来存储)
     private Executor瑟维斯(Service) mExecutor瑟维斯(Service);  //线程池
需要为每个客户端都张开一个线程   
     private ServerSocket mServerSocket;  //ServerSocket对象 
     public static void main(String[] args){ //main方法 开启服务器
      new Server();
     }
     public Server(){
      try{  
       mServerSocket = new ServerSocket(SERVERPORT);//设置服务器端口  
       mExecutorService =
Executors.newCachedThreadPool();//创设一个线程池
       System.out.println(“start…”);  
       Socket client = null;//用来临时保存客户端连接的Socket对象
       while (true){   
        client = mServerSocket.accept(); //接收客户连接并添加到list中
        mClientList.add(client);   
        mExecutor瑟维斯(Service).execute(new
ThreadServer(client));//开启一个客户端线程
       }
      }catch (IOException e){
       e.printStackTrace();
      }
     }   
     static class ThreadServer implements
Runnable{//每个客户端单独开启一个线程
      private Socket   mSocket;
      private BufferedReader mBufferedReader;
      private PrintWriter  mPrintWriter;
      private String   mStrMSG;

      public ThreadServer(Socket socket) throws IOException{
       this.mSocket = socket;
       mBufferedReader = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
       mStrMSG = “user:”+this.mSocket.getInetAddress()+” come total:” +
mClientList.size();
       sendMessage();
      }
      public void run(){
       try{
        while ((mStrMSG = mBufferedReader.readLine()) != null){
         if (mStrMSG.trim().equals(“exit”)){
          //当一个客户端退出时
          mClientList.remove(mSocket);
          mBufferedReader.close();
          mPrintWriter.close();
          mStrMSG = “user:”+this.mSocket.getInetAddress()+” exit total:”

  • mClientList.size();
              mSocket.close();
              sendMessage();
              break;
             }else{
              mStrMSG = mSocket.getInetAddress() + “:” + mStrMSG;
              sendMessage();
             }
            }
           }catch (IOException e){
            e.printStackTrace();
           }
          } 
          private void sendMessage() throws
    IOException{//发送音信给拥有客户端
           System.out.println(mStrMSG);
           for (Socket client : mClientList){
            mPrintWriter = new PrintWriter(client.getOutputStream(),
    true);
            mPrintWriter.println(mStrMSG);
           }
          }
         }
        }
       
        public class Client2{//需要单独编译并在命令行情势下启动测试
         private static final int  PORT = 54321;
         private static ExecutorService exec =
    Executors.newCachedThreadPool();

     public static void main(String[] args) throws Exception{
      new Client2();
     }
     public Client2(){
      try{
       Socket socket = new Socket(“192.168.1.110”, PORT);
       exec.execute(new Sender(socket));
       BufferedReader br = new BufferedReader(new
InputStreamReader(socket.getInputStream()));
       String msg;
       while ((msg = br.readLine()) != null){
        System.out.println(msg);
       }
      }catch (Exception e){
      }
     }    
     static class Sender implements
Runnable{//客户端线程获取控制台输入信息
      private Socket socket;
      public Sender(Socket socket){
       this.socket = socket;
      }
      public void run(){
       try{
        BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(socket.getOutputStream(),
true);
        String msg;
        while (true){
         msg = br.readLine();
         pw.println(msg);
         if (msg.trim().equals(“exit”)){
          pw.close();
          br.close();
          exec.shutdownNow();
          break;
         }
        }
       }catch (Exception e){
        e.printStackTrace();
       }
      }
     } 
    }
   
    public class Activity01 extends Activity{//客户端,
客户端需要与服务器始终维持通信状态
在意:因Android是线程安全的,所以不可以一向在线程中更新视图,需使用Handler来更新视图
           当点击”登陆“按钮时,连接服务器,并拿走需要操作的流,
点击”发送”按钮时取出输入框中的情节发送向服务器,由服务器发送给每个客户端

     private final String  DEBUG_TAG = “Activity01”;     
     private static final String SERVERIP =
“192.168.1.110”;//服务器IP、端口
     private static final int SERVERPORT = 54321;
     private Thread mThread = null;
     private Socket    mSocket  = null;
     private Button    mButton_In = null;
     private Button    mButton_Send= null;
     private EditText   mEditText01  = null;
     private EditText   mEditText02  = null;
     private BufferedReader  mBufferedReader = null;
     private PrintWriter mPrintWriter = null;
     private  String mStrMSG = “”;

     public void onCreate(Bundle savedInstanceState){
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
 
      mButton_In = (Button)findViewById(R.id.Button_In);
      mButton_Send = (Button)findViewById(R.id.Button_Send);
      mEditText01=(EditText)findViewById(R.id.EditText01);
      mEditText02=(EditText)findViewById(R.id.EditText02);
 
      mButton_In.setOnClickListener(new OnClickListener(){//登陆按钮
       public void onClick(View v){
        try {    
         mSocket = new Socket(SERVERIP, SERVERPORT); //连接服务器    
         mBuffered里德r = new BufferedReader(new
InputStream里德(Reade)r(mSocket.getInputStream()));//取得输入、输出流
         mPrintWriter=new PrintWriter(mSocket.getOutputStream(),
true);  
        }catch (Exception e) {
         Log.e(DEBUG_TAG, e.toString());
        }
       }
      });
      mButton_Send.setOnClickListener(new
OnClickListener(){//发送音讯按钮
       public void onClick(View v){
        try {
         String str = mEditText02.getText().toString() +
“\n”;//取得编辑框中我们输入的始末
         mPrintWriter.print(str);//发送给服务器
         mPrintWriter.flush();
        }catch (Exception e) {
         Log.e(DEBUG_TAG, e.toString());
        }
       }
      });
      mThread = new Thread(mRunnable);
      mThread.start();
     }
     private Runnable mRunnable = new Runnable() {
//线程:监听服务器发来的音讯
      public void run(){
       while (true){
        try{
         if ( (mStrMSG = mBufferedReader.readLine()) != null ){     
          mStrMSG+=”\n”;//音讯换行
          mHandler.sendMessage(mHandler.obtainMessage());// 发送音讯
         }    
        }catch (Exception e){
         Log.e(DEBUG_TAG, e.toString());
        }
       }
      }
     };
     Handler mHandler = new Handler() {         
      public void handleMessage(Message msg){          
       super.handleMessage(msg);//接受音信 刷新
       try{     
        mEditText01.append(mStrMSG); //将聊天记录添加进去  
       }catch (Exception e){                    
        Log.e(DEBUG_TAG, e.toString());         
       }         
      }        
     };
    }

第六有的 网络通信的华语乱码问题
  要想缓解Java粤语乱码问题,需理解如下内容:
   字符:是文字与符号的总称,包括文字、图形符号、数学符号等。
   字符集:就是一组抽象字符的聚集。
字符集通常和一种具体的语言文字对应起来,该文字中所有字符或者大部分字符就构成了该字符集。
诸如英文字符集、繁体汉字字符集、日文字符集等。
  
字符编码:统计机要拍卖各个字符,就需要将字符和二进制内码对应起来,这种对应关系就是字符编码。
要规定编码首先要确定字符集,并将字符集内的字符排序,然后和二进制数字对应起来。
依据字符集内字符的略微,确定用多少个字节来编码。
     ASCII编码是当下用得最广的字符集及编码。
    
Unicode编码是电脑上使用的字符编码。UTF-8就是Unicode编码的贯彻格局。
     GB2312字集是简体字集
     BIG5字集安徽繁体字集
     GBK字集是简繁字集
    
GB18030是国家制定的一个强制性大字集标准,它的生产使汉字有了统一的标准。
     Linux系统默认使用的是ISO-8859-1编码
     Win32系统默认使用的是GB2312编码
   网络通信中,发生乱码的缘故根本是通信过程中应用了不同的编码形式:
如:服务器中的编码格局、传输过程中的编码模式、传输到达顶峰设备的编码形式。
据此在传输过程中足足需要两回编码转换。
率先从服务器编码转换为网络编码,再从网络编码转换为巅峰设备编码。
在转换过程中爆发任何动静都可能滋生编码混乱,
  
   可以因此二种形式来避免编码混乱:
    第一种:由于多数终极设备都匡助Unicode字符集,
为此在连年网页时,我们盼望网页数据在网络传输时使用UTF-8情势传输,
如此这般就足以将UTF-8转换成Unicode字符集了。
     
下边为我们将通信过程中取得的流先转换为字节,然后再将字节按GB2312的章程展开转移得到字符串。
      InputStream is = conn.getInputStream();
      BufferedInputStream bis =new.BufferedInputStream(is);
      byte bytearray[] = new byte[1024];
      int current = -1;
      int i = 0;
      while((current = bis.read()) != -1){
       bytearray[i] = (byte) current;
       i++;
      }
      resultData = new
String(bytearray,”GB2312″);//resultData字符串便可兆示普通话效果
    第二种:在数额传输过程中应用ISO-8859-1字符集,
诸如此类就是直接行使ASCII编码情势,当然在传递到终极设备时,需要将其数量反转才能正常展现。
      下面将一个字符串按ISO-8859-1字符集举办更换。
      public static String FormatStr(String str){
       if(str = null||str.length() ==0){
        return “”;
       }
       try{
        return new
String(str.getBytes(“ISO-8859-1″),”bgk”);//使用getBytes(“编码形式”)
对汉字举办重编码,
得到它的字节数组。再使用new String(Bytes[],”解码形式”)
                      来对字节数组举行对应的解码。
实质上只要了解了哪些时候理应编码,什么日期应该解码,怎么编码、解码就不怕中文乱码问题了。
       }catch(UnsupportedEncodingException ex){
        return str;
       }
      }
     
第七部分 Web基特(Kit)应用 
   Android 浏览器的基础是Webkit引擎,Web基特的前身是KDE小组的KHTML.
   WebKit
    是一个开源浏览器网页排版引擎。与之相应的发动机有Gecko和Trident等。
    Web基特 由3个模块组合:
    Web基特(Kit)       整个项目标称呼
    JavaScriptCore JavaScrip解释器
    WebCore  
整个项目的中央,用来贯彻Render引擎,解析Web页面,生成一个DOM树和一个Render树。
    Web基特的剖析过程:
     1、CURL拿到网站的stream。
     2、解析划分字符串。
     3、通过DOM Builer按法定的HTML规范生成DOM树。
     4、假诺有Javascript,JSEngine就透过ECMA-262规范周到DOM树。
    
5、把DOM传给LayoutEngine举办布局,假如有CSS样式,就透过CSSParser解析。
     6、最后Rendering渲染出来。
   WebView
    WebView控件是Web基特(Kit)类中特地用来浏览网页的控件。
    其应用需要在XML文件中如下设计:
    <WebView
     android:id=”@+id/WebView01″
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent” 
     android:layout_weight=”1″
     />
    然后需要在程序代码中转载那些控件
,并设置其颜色、字体、要访问的网址(也可在XML文件中装置)。
    通过loadUrl方法设置当前WebView需要拜访的网址代码如下:
    mWebView= (WebView)findViewById(R.id.WebView01);
    mWebView.loadUrl(“http://www.google.com/“);
   WebSettings
   
在Android中可以透过WebSettings来设置Web基特的局部性能、状态等。在开立WebView时,系统有一个默认的安装,可以经过WebView.getSettings来获取如下:
    WebSettings webSettings =
mWebView.getSetting();//得到mWebView的WebSettings对象
    WebSettings和WebView
都在相同生命周期中存在,当WebView被销毁后,假若再利用WebSettings则会抛出IllegalStateException很是。
   
下为时设置有些常用属性、状态的形式。将下边的set改为get即可拿到WebView的一对属性和情形。
     setAllowFileAccess   启动或禁止WebView访问文件数量
     setBlockNetworkImage  是否出示图像
     setBuiltInZoomControls  设置是否帮助缩放
     setCacheMode    设置缓冲情势
     setDefaultFontSize   设置默认的字体大小
     setDefaultTextEncodingName 设置在解码时接纳的默认编码
     setFixedFontFamily   设置固定使用的书体
     setJavaScriptEnabled  设置是否协助JavaScript
     setLayoutAlgorithm   设置布局模式
     setLightTouchEnabled  设置用鼠标激活被挑选
     setSupportZoom    设置是否补助定焦
   WebViewClient
    在先后中得以用WebViewClient来自定义网页浏览程序。
   
此类专门襄助WebView处理各样公告,请求等事件的类。可以通过WebView的setWebViewClient方法来创立一个WebViewClient对象。
    WebViewClient常用艺术:
     doUpdateVisitedHistory   更新历史记录
     onFormResubmission    应用程序重新请求网页数据
     onLoadResource     加载指定地点提供的资源
     onPageFinished     网页加载完毕
     onPageStarted     网页初阶加载
     onReceivedError     报告错误音讯
     onScaleChanged     WebView发生改变
     shouldOverrideUrlLoading  控制新的连年在现阶段WebView中打开
   
我们得以覆盖这么些办法来赞助WebView浏览网页.如下:我们设置覆盖shouldOverrideUrlLoading方法。
     public boolean shouldOverrideUrlLoading(WebView view ,String
url){
      view.loadUrl(url);//设置访问的网址
      ruturn true;
     }
   WebChromeClient
   
在Android中经过WebChromeClient专门来支援WebView处理Javascript的对话框、网站图标、网站Title、加载进度等。
    WebChromeClient中常用艺术
     onCloseWindow  关闭WebView
     onCreateWindow  创建WebView
     onJsAlert   处理Javascript中的Alert对话框
     onJsConfirm   处理Javascript中的Confirm对话框
     onJsPrompt   处理Javascript中的Prompt对话框
     onProgressChanged 加载进度条改变
     onReceivedIcon  网页图标改动
     onReceivedTitle  网页Title更改
     onRequestFocus  WebView展现主旨
    上边来贯彻onReceiveTitle方法,用于转移应用程序的Title 代码如下:
     public void onReceivedTitle(WebView view,String title){
      Activity01.this.setTitle(title);
      super.onReceivedTitle(view,title);
     }
   下例为对地点知识的汇总采纳。
   prom_dialog.xml文件
   <?xml version=”1.0″ encoding=”utf-8″?>
   <LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android
    android:gravity=”center_horizontal”
    android:orientation=”vertical”
    android:layout_width=”fill_parent”
    android:layout_height=”wrap_content”
    >
    <TextView
     android:id=”@+id/TextView_PROM”
     android:layout_width=”fill_parent”
     android:layout_height=”wrap_content”/>
    <EditText
     android:id=”@+id/EditText_PROM”
     android:layout_width=”fill_parent”
     android:layout_height=”wrap_content”
     android:selectAllOnFocus=”true”
     android:scrollHorizontally=”true”/>
   </LinearLayout>
   main.xml文件
   <?xml version=”1.0″ encoding=”utf-8″?>
   <LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android
    android:orientation=”vertical”
    android:layout_width=”fill_parent”
    android:layout_height=”fill_parent”
    >
    <LinearLayout
     android:orientation=”horizontal”
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”
     android:animationCache=”true”
     android:layout_weight=”9″>
     <EditText
      android:id=”@+id/EditText01″
      android:layout_width=”wrap_content”
      android:layout_weight=”9″
      android:layout_height=”wrap_content”
      android:text=”请输入网址”/>
     <Button
      android:id=”@+id/Button01″
      android:layout_width=”wrap_content”
      android:layout_weight=”1″
      android:layout_height=”wrap_content”
      android:text=”连接” />
    </LinearLayout>
    <WebView
     android:id=”@+id/WebView01″
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent” 
     android:layout_weight=”1″
     />
   </LinearLayout>
  
   public class Activity01 extends Activity{
    private final String DEBUG_TAG = “Activity01”;
    private Button 
mButton;//界面中使用EditText来输入网址,用Button来认同连接,用WebView来显示网页内容。
    private EditText mEditText;
    private WebView  mWebView;

    public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
     mButton = (Button) findViewById(R.id.Button01);
     mEditText = (EditText) findViewById(R.id.EditText01);
     mWebView = (WebView) findViewById(R.id.WebView01);
 
     WebSettings webSettings =
mWebView.getSettings();//设置帮助JavaScript脚本 
     webSettings.setJavaScriptEnabled(true); 
     webSettings.setAllowFileAccess(true);//设置可以访问文件 
     webSettings.setBuiltInZoomControls(true);//设置襄助缩放
 
     mWebView.setWebViewClient(new WebViewClient(){ //设置WebViewClient
来扶持WebView处理局部轩然大波
      public boolean shouldOverrideUrlLoading(WebView view, String url)
{  
       view.loadUrl(url);  
       return true;  
      } 
      public void onPageFinished(WebView view, String url) {
       super.onPageFinished(view, url);
      }
      public void onPageStarted(WebView view, String url, Bitmap
favicon) {
       super.onPageStarted(view, url, favicon);
      }
     }); 
     mWebView.setWebChromeClient(new
WebChromeClient(){//设置WebChromeClient
来辅助WebView处理JavaScripte对话框 
      public boolean onJsAlert(WebView view, String url, String
message,final JsResult result) {//处理javascript中的alert
       //构建一个Builder来显示网页中的对话框
       Builder builder = new Builder(Activity01.this);
       builder.setTitle(“提醒对话框”);
       builder.setMessage(message);
       builder.setPositiveButton(android.R.string.ok,
        new AlertDialog.OnClickListener() {
         public void onClick(DialogInterface dialog, int which)
{       
         
esult.confirm();//点击确定按钮之后,继续执行网页中的操作。通过confirm和cancel方法将大家的操作传递给Javascript处理
         }
        });
       builder.setCancelable(false);
       builder.create();
       builder.show();
       return true;
      }; 
      public boolean onJsConfirm(WebView view, String url, String
message,final JsResult result) {//处理javascript中的confirm
       Builder builder = new Builder(Activity01.this);
       builder.setTitle(“带选用的对话框”);
       builder.setMessage(message);
       builder.setPositiveButton(android.R.string.ok,
        new AlertDialog.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
         
result.confirm();//通过confirm和cancel方法将我们的操作传递给Javascript处理
         }
        });
       builder.setNegativeButton(android.R.string.cancel,
        new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
         
result.cancel();//通过confirm和cancel方法将大家的操作传递给Javascript处理
         }
        });
       builder.setCancelable(false);
       builder.create();
       builder.show();
       return true;
      };
      public boolean onJsPrompt(WebView view, String url, String
message,
       String defaultValue, final JsPromptResult result)
{//处理javascript中的prompt,message为网页中对话框的指示内容,defaultValue在并未输入时,默认展现的内容   
       final LayoutInflater factory =
LayoutInflater.from(Activity01.this);//自定义一个带输入的对话框由TextView和EditText构成
       final View dialogview = factory.inflate(R.layout.prom_dialog,
null);   
       ((TextView)
dialogview.findViewById(R.id.TextView_PROM)).setText(message);//设置TextView对应网页中的指示信息  
       ((EditText)
dialogview.findViewById(R.id.EditText_PROM)).setText(defaultValue);//设置EditText对应网页中的输入框
   
       Builder builder = new Builder(Activity01.this);
       builder.setTitle(“带输入的对话框”);
       builder.setView(dialogview);
       builder.setPositiveButton(android.R.string.ok,
        new AlertDialog.OnClickListener() {
         public void onClick(DialogInterface dialog, int which)
{      
          String value = ((EditText)
dialogview.findViewById(R.id.EditText_PROM)).getText().toString();//点击确定之后,取得输入的值,传给网页处理
         
result.confirm(value);//通过confirm和cancel方法将大家的操作传递给Javascript处理
         }
        });
       builder.setNegativeButton(android.R.string.cancel,
        new DialogInterface.OnClickListener() {
         public void onClick(DialogInterface dialog, int which) {
         
result.cancel();//通过confirm和cancel方法将我们的操作传递给Javascript处理
         }
        });
       builder.setOnCancelListener(new
DialogInterface.OnCancelListener() {
        public void onCancel(DialogInterface dialog) {
        
result.cancel();//通过confirm和cancel方法将大家的操作传递给Javascript处理
        }
       });
       builder.show();
       return true;
      };  
      public void onProgressChanged(WebView view, int newProgress)
{//设置网页加载的进度条
      
Activity01.this.getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
newProgress * 100);
       super.onProgressChanged(view, newProgress);
      }  
      public void onReceivedTitle(WebView view, String title)
{//设置应用程序的标题title
       Activity01.this.setTitle(title);
       super.onReceivedTitle(view, title);
      }
     }); 
     mButton.setOnClickListener(new
OnClickListener(){//连接按钮事件监听
      public void onClick(View v){
       try {    
        String url =
mEditText.getText().toString();//取得编辑框中大家输入的始末       
        if ( URLUtil.isNetworkUrl(url) ){
//判断输入的始末是不是网址        
         mWebView.loadUrl(url);//装载网址
        }else{
         mEditText.setText(“输入网址错误,请重新输入”);
        }
       }catch (Exception e){
        Log.e(DEBUG_TAG, e.toString());
       }
      }
     });
    }
    public boolean onKeyDown(int keyCode, KeyEvent event){
     if ((keyCode == KeyEvent.KEYCODE_BACK) &&
mWebView.canGoBack()){//当大家按再次来到键时
可以通过goBack和goForward方法来安装其进步和退化,但在应用在此之前大家透过
                    
canGoBack和canGoForward方法来检测是否能够后退和提升。
      mWebView.goBack();//重临前一个页面
       return true;
     }
     return super.onKeyDown(keyCode, event);
    } 
   }
  
   WebView和Javascript相互调用
   
下例为兑现了WebView和Javascript怎么样相互调用,该例实现了从Android应用中调出个人资料,然后经过Javascript呈现出来。
   main.xml
   <?xml version=”1.0″ encoding=”utf-8″?>
    <LinearLayout
xmlns:android=”http://schemas.android.com/apk/res/android
     android:orientation=”vertical”
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”
     >
     <WebView
      android:id=”@+id/WebView01″
      android:layout_width=”fill_parent”
      android:layout_height=”fill_parent”/>
    </LinearLayout>

   public class Activity01 extends Activity{
    private WebView mWebView;
    private PersonalData mPersonalData;
    public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
     mPersonalData = new PersonalData();
     mWebView = (WebView)this.findViewById(R.id.WebView01);
 
    
mWebView.getSettings().setJavaScriptEnabled(true);//设置襄助JavaScript
     mWebView.addJavascriptInterface(this,
“PersonalData”);//把本类的一个实例添加到js的全局对象window中,那样就可以运用window.PersonalData来调用它的办法 
    
mWebView.loadUrl(“http://www.cnblogs.com/freeliver54/admin/file:///android_asset/PersonalData.html%22);//加载网页。
                   
在Java代码中经过WebView.loadUrl(“javascript:方法名”);能够直接调用Javascript方法
                    为了让WebViwe从Apk文件中加载assets,Android
SDK提供了一个Schema,前缀
                   
为”http://www.cnblogs.com/freeliver54/admin/file:///android_asset/“。当WebView遭遇Schema,就去当前包中的Assets目录中找内容
    }
    public PersonalData
getPersonalData(){//在js脚本中调用得到PersonalData对象
     return mPersonalData;
    } 
    class
PersonalData{//js脚本中调用突显的资料。定义一个PersonalData类,用来保存个人资料,并且定义得到这多少个数据的积极分子函数,供Javascript调用
     String  mID;
     String  mName;
     String  mAge;
     String  mBlog;
     public PersonalData(){
      this.mID=”123456789″;
      this.mName=”Android”;
      this.mAge=”100″;
      this.mBlog=”http://yarin.javaeye.com/“;
     }
     public String getID(){
      return mID;
     }
     public String getName(){
      return mName;
     }
     public String getAge(){
      return mAge;
     }
     public String getBlog(){
      return mBlog;
     }
    }
   }
  
通过地方的起先化WebView后,在Javascript中就可以用window.PersonalData.getPersonalData()来收获Java对象。
   上面是在Javascript访问Android应用的代码。
   assets.test.js文件
    window.onload = function(){
     var personaldate =
window.PersonalData.getPersonalData();//取得java对象
     if(personaldate){
      var Personaldate = document.getElementById(“Personaldate”);
      pnode = document.createElement(“P”);
      tnode =
document.createTextNode(“ID:”+personaldate.getID());//通过Java对象访问数据
      pnode = appendChild(tnode);
      Personaldata.appendChild(pnode);
     
      pnode = document.createElement(“P”);
      tnode =
document.createTextNode(“Name:”+personaldate.getName());//通过Java对象访问数据
      pnode = appendChild(tnode);
      Personaldata.appendChild(pnode);
     
      pnode = document.createElement(“P”);
      tnode =
document.createTextNode(“Age:”+personaldate.getAge());//通过Java对象访问数据
      pnode = appendChild(tnode);
      Personaldata.appendChild(pnode);
     
      pnode = document.createElement(“P”);
      tnode =
document.createTextNode(“Blog:”+personaldate.getBlog());//通过Java对象访问数据
      pnode = appendChild(tnode);
      Personaldata.appendChild(pnode);
     }
    }
第八片段 WiFi—Wireless Fidelity
   WiFi又称802.11b标准,最大亮点传输速度高。
   WiFi操作的一些常见类和接口
    ScanResult
    
重要用来讲述已经检测出的接入点,包括接入点的地方、名称、身份注脚、频率、信号强度等音讯。
    WifiConfiguration
     WiFi网络的安排,包括平安布局等
    WifiInfo
    
WiFi无线连接的叙述,包括接入点、网络连接状态、隐藏的接入点、IP地址、连接速度、MAC地址、网络ID、信号强度等音信。
    WifiManager
     包括了保管WiFi连接的大部分API,如下内容:
     
已经安排好的网络清单。这些清单可以查阅和修改,而且可以修改个别记录的习性。
     
当连接中有活动的Wi-Fi网络时,可以建立或关闭这多少个连续,并且可以查询有关网络状态的动态音信。
      对接入点的扫视结果包含丰裕的音信来决定需要与什么接入点建立连接。
      还定义了重重常量来表示Wi-Fi状态的转移。
    WifiManager.WifiLock
    
用户一段时间没有其他操作时,WiFi就会自行关闭,大家可以经过WifiLock来锁定WiFi网络,使其一向保持连续,直到锁定被放走。
    
当有多少个应用程序时或者会有五个WifiLock,在收音机设备中必须保证其他一个选用中都从未接纳WifiLock时,才可以关闭它。
    
在利用WiFi锁在此之前,必须确定应用需要WiFi的联网,或者能够在活动网络下工作。
     WiFi锁无法跨越客户端的Wi-Fi Enabled设置,也绝非飞行格局。
     如下代码可获取WifiManager对象,可拔取这么些目的来操作WiFi连接
      WifiManager wifiManager =
(WifiManager)getSystemService(Context.WIFI_SERVICE);
      如下为WifiManager的常用方法:
       addNetwork    添加一个部署好的网络连接
       calculateSignalLevel 总括信号强度
       compareSignalLevel  相比较三个信号的强度
       createWifiLock   成立一个Wifi锁
       disableNetwork   废除一个布局好的网络,固然其不可用
       disconnect    从接入点断开
       enableNetwork   允许指定的网络连接
       getConfiguredNetworks 拿到客户端具备曾经安排好的网络列表
       getConnectionInfo  拿到正在使用的连年的动态信息
       getDhcpInfo    拿到最终五遍成功的DHCP请求的DHCP地址
       getScanResults   拿到被围观到的接入点
       getWifiState   拿到可用WiFi的景观
       isWifiEnabled   得到WiFi是否可用
       pingSupplicant   检查客户端对请求的反响
       reassociate    从脚下接入点重新连接
       removeNetwork   从已经部署好的网络列表中删去指定ID的网络
       saveConfiguration  保存当前布局好的网络列表
       setWifiEnabled   设置WiFi是否可用
       startScan    扫描存在的接入点
       updateNetwork   更新已经部署好的网络
  
例:下例中的WifiAdmin需要打开(关闭)WIFI、锁定(释放)WifiLock、成立WifiLock、取得配置好的网络、扫描、连接、断开、获取网络连接的音信。
   因WiFi与装备有关所以需在真机上才能看到功效。
   public class Activity01 extends Activity{
    private WifiManager wifiManager;
    public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
    }
   }
   public class WifiAdmin{
    private WifiManager mWifiManager;//定义WifiManager对象
    private WifiInfo mWifiInfo;//定义WifiInfo对象
    private List<ScanResult> mWifiList;//扫描出的网络连接列表
    private List<WifiConfiguration>
mWifiConfiguration;//网络连接列表
    WifiLock mWifiLock;//定义一个WifiLock
    public  WifiAdmin(Context context){//构造器 
     mWifiManager = (WifiManager)
context.getSystemService(Context.WIFI_SERVICE);//取得WifiManager对象
     mWifiInfo = mWifiManager.getConnectionInfo();//取得WifiInfo对象
    }
    public void OpenWifi(){//打开WIFI
     if (!mWifiManager.isWifiEnabled()){
      mWifiManager.setWifiEnabled(true);  
     }
    }
    public void CloseWifi(){//关闭WIFI
     if (!mWifiManager.isWifiEnabled()){
      mWifiManager.setWifiEnabled(false);
     }
    }
    public void AcquireWifiLock(){//锁定WifiLock
     mWifiLock.acquire();
    }
    public void ReleaseWifiLock(){//解锁WifiLock 
     if (mWifiLock.isHeld()){//判断时候锁定
      mWifiLock.acquire();
     }
    }
    public void CreatWifiLock(){ //创制一个WifiLock
     mWifiLock = mWifiManager.createWifiLock(“Test”);
    }
    public List<WifiConfiguration>
GetConfiguration(){//得到部署好的网络
     return mWifiConfiguration;
    }
    public void ConnectConfiguration(int
index){//指定安排好的网络展开连接
     if(index >
mWifiConfiguration.size()){//索引大于配置好的网络索引重回
      return;
     } 
     mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId,
true);//连接配置好的指定ID的网络
    }
    public void StartScan(){
     mWifiManager.startScan();
     mWifiList = mWifiManager.getScanResults();//得到扫描结果 
     mWifiConfiguration =
mWifiManager.getConfiguredNetworks();//得到部署好的网络连接
    }
    public List<ScanResult> GetWifiList(){//拿到网络列表
     return mWifiList;
    }
    public StringBuilder LookUpScan(){//查看扫描结果
     StringBuilder stringBuilder = new StringBuilder();
      for (int i = 0; i < mWifiList.size(); i++){
       stringBuilder.append(“Index_”+new Integer(i + 1).toString() +
“:”);
      
//将ScanResult音讯转换成一个字符串包,其中把包括:BSSID、SSID、capabilities、frequency、level
       stringBuilder.append((mWifiList.get(i)).toString());
       stringBuilder.append(“\n”);
      }
      return stringBuilder;
    }
    public String GetMacAddress(){//得到MAC地址
     return (mWifiInfo == null) ? “NULL” : mWifiInfo.getMacAddress();
    }
    public String GetBSSID(){//得到接入点的BSSID
     return (mWifiInfo == null) ? “NULL” : mWifiInfo.getBSSID();
    }
    public int GetIPAddress(){//得到IP地址
     return (mWifiInfo == null) ? 0 : mWifiInfo.getIpAddress();
    }
    public int GetNetworkId(){//拿到连续的ID
     return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId();
    }
    public String GetWifiInfo(){//得到WifiInfo的装有音信包
     return (mWifiInfo == null) ? “NULL” : mWifiInfo.toString();
    }
    public void AddNetwork(WifiConfiguration wcg){//添加一个网络并一连
     int wcgID = mWifiManager.addNetwork(wcg);
     mWifiManager.enableNetwork(wcgID, true);
    }
    public void DisconnectWifi(int netId){//断开指定ID的网络
     mWifiManager.disableNetwork(netId);
     mWifiManager.disconnect();
    }
   }
   AndroidManifest.xml文件 最后索要在此文件中对权力举行宣示
    <uses-permission
android:name=”android.permission.ACCESS_WIFI_STATE”></uses-permission>
    <uses-permission
android:name=”android.permission.ACCESS_CHECKIN_PROPERTIES”></uses-permission>
    <uses-permission
android:name=”android.permission.WAKE_LOCK”></uses-permission>
    <uses-permission
android:name=”android.permission.INTERNET”></uses-permission>
    <uses-permission
android:name=”android.permission.CHANGE_WIFI_STATE”></uses-permission>
    <uses-permission
android:name=”android.permission.MODIFY_PHONE_STATE”></uses-permission>
   
第九片段 蓝牙
  
蓝牙是一种短距离的无线连接技术标准的代称,蓝牙的真面目内容就是起家通用无线电空中接口及其控制软件的当众规范。
  
蓝牙采纳分散式网络布局以及快调频和短包技术,补助点对点以及多对点通信,
工作在大地通用的2.4GHz
ISM(即工业、科学、教育学)频段,其数量速率为1Mbps,采纳时分双工传输方案。
  
蓝牙协议分4层:即主旨协议层、电缆替代协议层、电话控制协议层、采取其他的协议层。
   Android 2.0 即API Level等级为5或上述版本才含有蓝牙功效
   蓝牙的类和接口位于android.bluetooth包中,有如下效能:
    Bluetooth艾达pter   蓝牙适配器(代表当地蓝牙适配器)
    BluetoothClass    蓝牙类(首要不外乎劳动和装置)
    BluetoothClass.Device  蓝牙设备类
    BluetoothClass.Device.Major 蓝牙设备管理
    BluetoothClass.Service  有关蓝牙服务的类
    BluetoothDevice    蓝牙设备(首要指远程蓝牙设备)
    BluetoothServerSocket  监听蓝牙连接的类
    BluetoothSocket    蓝牙连接类
   要使用蓝牙API必须要在AndroidManifest.xml中扬言权限代码如下:
    <uses-sdk android:minSdkVersion=”5″ />//API等级为5
    <uses-permission android:name=”android.permission.BLUETOOTH”
/>//蓝牙权限
    <uses-permission
android:name=”android.permission.BLUETOOTH_ADMIN”
/>//蓝牙管理、操作
    <uses-permission
android:name=”android.permission.READ_CONTACTS”/>//读取联系人
   要使用蓝牙必须先得到蓝牙适配器 代码如下:
    BluetoothAdapter  _bluetooth =
Bluetooth艾达(Ada)pter.getDefault艾达(Ada)pter();//通过getDefaultAdapter()方法取得当地蓝牙适配器,要博得远程的用BluetoothDevice类。
  
如何开辟、关闭本地蓝牙和怎样才能使其它设施可以寻找到温馨的设施?如下:
    首先定义三个常量,分别表示呼吁打开和乞请可以被搜寻代码如下:
     private static final int REQUEST_ENABLE;//请求打开蓝牙
     private static final int REQUEST_DISCOVERABLE;//请求可以被寻找
    1、请求开启蓝牙
     Intent enabler = new
Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);//请求系统允许用户打开蓝牙
     startActivityForResult(enabler, REQUEST_ENABLE);
    2、请求可以被搜寻
     Intent enabler = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//请求系统允许蓝牙设备被搜寻
     startActivityForResult(enabler, REQUEST_DISCOVERABLE);
      Bluetooth艾达pter类中此外动作常量
       ACTION_DISCOVERY_FINISHED  已经完成搜索
       ACTION_DISCOVERY_STARTED  已经上马寻找蓝牙设备
       ACTION_LOCAL_NAME_CHANGED  更改蓝牙名字
       ACTION_REQUEST_DISCOVERABLE  请求可以被搜寻
       ACTION_REQUEST_ENABLE   请求开启蓝牙
       ACTION_SCAN_MODE_CHANGED  描述情势已转移
       ACTION_STATE_CHANGED   状态已改成
    3、打开蓝牙
     _bluetooth.enable();//使用BluetoothAdapter类中的enable方法
    4、关闭蓝牙
     _bluetooth.disable();//使用BluetoothAdapter类中的diable方法
      BluetoothAdapter中的常用方法
       cancelDiscovery   撤销当前设备搜索过程
       checkBlutoothAddress
检测蓝牙地址是否科学。如”00:43:A8:23:10:F0″字母必须是大写
       disable     关闭蓝牙适配器
       enable     打开蓝牙适配器
       getAddress    取得地点蓝牙的硬件适配器地址
       getDefaultAdapter  得到默认的蓝牙适配器
       getName     拿到蓝牙的名字
       getRemoteDevice   取得指定蓝牙硬件地址的BluetoothDevice对象
       getScanMode    获得扫描格局
       getState    得到气象
       isDiscovering   是否允许被寻找
       isEnabled    是否打开
       setName     设置名字
       startDiscovery   开头物色
    5、搜索蓝牙设备
     搜索远程蓝牙设备亟需使用BluetoothDevice类
    
首先利用BluetoothAdapter类的getRemoteDevice方法来收获一个指定地点的BluetoothDevice
     BluetoothDevice类实际是一个蓝牙硬件地址薄,该类对象是不可改变的。
其操作都是长距离蓝牙硬件地址使用Bluetooth艾达(Ada)pter来创造一个BluetoothDevice对象。

   public class DiscoveryActivity  extends
ListActivity{//此类为寻找蓝牙的类
    private Handler _handler = new Handler();
    private BluetoothAdapter _bluetooth =
BluetoothAdapter.getDefaultAdapter();//取得默认的蓝牙适配器
    private List<BluetoothDevice> _devices = new
ArrayList<BluetoothDevice>();// 用List来囤积搜索到的蓝牙设备
    private volatile boolean  _discoveryFinished;//是否成功搜索
    private Runnable _discoveryWorkder = new Runnable() {
     public void run() {
      _bluetooth.startDiscovery();//开端搜寻
      for (;;) {
       if (_discoveryFinished) {
        break;
       }
       try {
        Thread.sleep(100);
       } catch (InterruptedException e){}
      }
     }
    };
    private BroadcastReceiver _foundReceiver = new
布罗德castReceiver(){// 接收器 当搜索蓝牙设备完成时调用
     public void onReceive(Context context, Intent intent) {
      BluetoothDevice device =
intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);//从intent中取得搜索结果数据
      _devices.add(device);//将结果添加到列表中
      showDevices();//呈现列表
     }
    };
    private BroadcastReceiver _discoveryReceiver = new
BroadcastReceiver() {
     public void onReceive(Context context, Intent intent) {
      /* 卸载注册的采纳器 */
      unregisterReceiver(_foundReceiver);
      unregisterReceiver(this);
      _discoveryFinished = true;
     }
    };
    protected void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     
getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,
WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
      setContentView(R.layout.discovery);
      if (!_bluetooth.isEnabled()){//假设蓝牙适配器没有打开,则结果
       finish();
       return;
      }
      /* 注册接收器 */
      IntentFilter discoveryFilter = new
IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//1搜索以形成 
程序时通过线程来支配蓝牙设备的搜寻的(startDiscovery)
                            
当搜索过程中触发1、2两个接收器就径直传送给接收器进性保存
                             注意:搜索蓝牙设备流水线为:
                            
取得蓝牙适配器(getDefaultAdapter)—最先探寻—
                            
搜索完成(ACTION_DISCOVERY_FINISHED)卸载BroadcastReceiver
                            
—发现设备(ACTION_FOUND)—取得设备(EXTRA_DEVICE)
      registerReceiver(_discoveryReceiver, discoveryFilter);
      IntentFilter foundFilter = new
IntentFilter(BluetoothDevice.ACTION_FOUND);//2发现设备
      registerReceiver(_foundReceiver, foundFilter);
      SamplesUtils.indeterminate(DiscoveryActivity.this, _handler,
“Scanning…”, _discoveryWorkder, new OnDismissListener(){//展现一个对话框,正在搜寻蓝牙设备
       public void onDismiss(DialogInterface dialog){
        for (; _bluetooth.isDiscovering();){
         _bluetooth.cancelDiscovery();
        }
        _discoveryFinished = true;
       }
      }, true);
    }
    protected void showDevices(){//展现列表
最终将保留在List中的BluetoothDevice呈现在一个ListView中
     List<String> list = new ArrayList<String>();
      for (int i = 0, size = _devices.size(); i < size; ++i){
       StringBuilder b = new StringBuilder();
       BluetoothDevice d = _devices.get(i);
       b.append(d.getAddress());
       b.append(‘\n’);
       b.append(d.getName());
       String s = b.toString();
       list.add(s);
      }
     final ArrayAdapter<String> adapter = new
ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
list);
     _handler.post(new Runnable() {
      public void run(){
       setListAdapter(adapter);
      }
     });
    }
    protected void onListItemClick(ListView l, View v, int position,
long id){
     Intent result = new Intent();
     result.putExtra(BluetoothDevice.EXTRA_DEVICE,
_devices.get(position));
     setResult(RESULT_OK, result);
     finish();
    }
   }
   蓝牙Socket服务器与客户端
   
蓝牙服务器端就是通过注册一个享著名称和唯一识另外UUID号的BluetoothServerSocket,然后间接监听客户端(BluetoothSocket)的乞求,并作出相应处理。
    怎么样注册蓝牙服务器代码:
     private BluetoothAdapter  _bluetooth =
Bluetooth艾达(Ada)pter.getDefaultAdapter();//获取默认的蓝牙适配器
    
//其中listenUsingRfcommWith瑟维斯(Service)(Service)Record可以回到一个蓝牙服务器BluetoothServerSocker对象,其中参数PROTOCOL_SCHEME_RFCOMM是一个String类型常量,代表蓝牙服务器名称
    
//UUID.fromString(“a60f35f0-b93a-11de-8a39-08002009c666”)是该蓝牙服务器唯一标示UUID。在客户端连接这么些服务器时需要拔取该UUID.
     private BluetoothServerSocker _serverSocket =
_bluetooth.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,UUID.fromString(“a60f35f0-b93a-11de-8a39-08002009c666”));
   
   
连接之后可以透过BluetoothServerSocket的accept方法来收纳客户端请求,并作出相应处理代码如下:
     BluetoothSocket socket =
_serverSocket.accept();//接收客户端的连天请求,accept方法重返一个BluetoothSocket对象表示客户端
     if(socket != null){//处理请求内容
     }
     …
     _serverSocket.close;//通过BluetoothServerSocker的close方法
关闭蓝牙服务器

   public class ServerSocketActivity extends
ListActivity{//蓝牙Socket服务器
    /* 一些常量,代表服务器的名称 */
    public static final String PROTOCOL_SCHEME_L2CAP = “btl2cap”;
    public static final String PROTOCOL_SCHEME_RFCOMM = “btspp”;
    public static final String PROTOCOL_SCHEME_BT_OBEX = “btgoep”;
    public static final String PROTOCOL_SCHEME_TCP_OBEX =
“tcpobex”;
    private static final String TAG =
ServerSocketActivity.class.getSimpleName();
    private Handler _handler = new Handler();
    private BluetoothAdapter _bluetooth =
Bluetooth艾达pter.getDefaultAdapter();// 取得默认的蓝牙适配器
    private BluetoothServerSocket _serverSocket;//蓝牙服务器
    private Thread _serverWorker = new Thread() {//
线程-监听客户端的链接
     public void run() {
      listen();
     };
    };
    protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
    
getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
     setContentView(R.layout.server_socket);
     if (!_bluetooth.isEnabled()) {
      finish();
      return;
     }
     _serverWorker.start();//开头监听 开启线程
    }
    protected void onDestroy() {
     super.onDestroy();
     shutdownServer();
    }
    protected void finalize() throws Throwable {
     super.finalize();
     shutdownServer();
    }
    private void shutdownServer() {//截止服务器
     new Thread() {
      public void run() {
       _serverWorker.interrupt();
       if (_serverSocket != null) {
        try {
         _serverSocket.close();//关闭服务器
        } catch (IOException e) {
         Log.e(TAG, “”, e);
        }
        _serverSocket = null;
       }
      };
     }.start();
    }
    public void onButtonClicked(View view) {
     shutdownServer();
    }
    protected void listen() {
     try {
      // 创立一个蓝牙服务器 参数分别:服务器名称、UUID
      _serverSocket =
_bluetooth.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,
                   
UUID.fromString(“a60f35f0-b93a-11de-8a39-08002009c666”));
      final List<String> lines = new
ArrayList<String>();//客户端连线列表
将接连进的具备客户端都放进一个List中
      _handler.post(new Runnable() {
       public void run() {
        lines.add(“Rfcomm server started…”);
        ArrayAdapter<String> adapter = new
ArrayAdapter<String>(ServerSocketActivity.this,android.R.layout.simple_list_item_1,
lines);
        setListAdapter(adapter);
       }
      });
      BluetoothSocket socket =
_serverSocket.accept();//接受客户端的连续请求
      if (socket != null) {//处理请求内容
       InputStream inputStream = socket.getInputStream();
       int read = -1;
       final byte[] bytes = new byte[2048];
       for (; (read = inputStream.read(bytes)) > -1;) {
        final int count = read;
        _handler.post(new Runnable(){
         public void run() {
          StringBuilder b = new StringBuilder();
           for (int i = 0; i < count; ++i) {
            if (i > 0) {
             b.append(‘ ‘);
            }
            String s = Integer.toHexString(bytes[i] & 0xFF);
            if (s.length() < 2) {
             b.append(‘0’);
            }
            b.append(s);
           }
          String s = b.toString();
          lines.add(s);
          ArrayAdapter<String> adapter = new
ArrayAdapter<String>(ServerSocketActivity.this,android.R.layout.simple_list_item_1,
lines);
          setListAdapter(adapter);
         }
        });
       }
      }
     } catch (IOException e) {
      Log.e(TAG, “”, e);
     } finally {
     }
    }
   }
   蓝牙客户端连接

   public class ClientSocketActivity  extends Activity{//蓝牙客户端
    private static final String TAG =
ClientSocketActivity.class.getSimpleName();
    private static final int REQUEST_DISCOVERY = 0x1;;
    private Handler _handler = new Handler();
    private BluetoothAdapter _bluetooth =
BluetoothAdapter.getDefaultAdapter();
    protected void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
    
getWindow().setFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND,WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
     setContentView(R.layout.client_socket);
     if (!_bluetooth.isEnabled()) {
      finish();
      return;
     }
     Intent intent = new Intent(this, DiscoveryActivity.class);
     Toast.makeText(this, “select device to connect”,
Toast.LENGTH_SHORT).show();//提醒采纳一个要连接的服务器(即搜索处理的蓝牙设备)
     startActivityForResult(intent, REQUEST_DISCOVERY);//
跳转到搜索的蓝牙设备列表区,举办精选
    }
    protected void onActivityResult(int requestCode, int resultCode,
Intent data) {//采取了服务器之后展开连续
     if (requestCode != REQUEST_DISCOVERY) {
      return;
     }
     if (resultCode != RESULT_OK) {
      return;
     }
     final BluetoothDevice device =
data.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);//因首先判断当地蓝牙是否启动,在连接时首先要确保本地连接已经启动
                   然后透过BluetoothDevice device =
Intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);代码
                   取得要连续的蓝牙设备。
     new Thread() {
      public void run() {
       connect(device);//连接
      };
     }.start();
    }
    protected void connect(BluetoothDevice device) {
     BluetoothSocket socket = null;
     try {
      //创立一个Socket连接:只需要服务器在登记时的UUID号
      // socket =
device.createRfcommSocketToServiceRecord(BluetoothProtocols.OBEX_OBJECT_PUSH_PROTOCOL_UUID);
      socket =
device.createRfcommSocketToServiceRecord(UUID.fromString(“a60f35f0-b93a-11de-8a39-08002009c666”));  
      socket.connect();//与服务器举办连接
     } catch (IOException e) {
      Log.e(TAG, “”, e);
     } finally {
      if (socket != null) {
       try {
        socket.close();
       } catch (IOException e) {
        Log.e(TAG, “”, e);
       }
      }
     }
    }
   }
   其他多少个类以供参考
   public class Activity01 extends Activity{
    /* 取得默认的蓝牙适配器 */
    private BluetoothAdapter _bluetooth    =
BluetoothAdapter.getDefaultAdapter();
    /* 请求打开蓝牙 */
    private static final int REQUEST_ENABLE   = 0x1;
    /* 请求可以被搜索 */
    private static final int REQUEST_DISCOVERABLE = 0x2;
    public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
    }
    /* 开启蓝牙 */
    public void onEnableButtonClicked(View view){
     // 用户请求打开蓝牙
     //Intent enabler = new
Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
     //startActivityForResult(enabler, REQUEST_ENABLE);
     //打开蓝牙
     _bluetooth.enable();
    }
    /* 关闭蓝牙 */
    public void onDisableButtonClicked(View view){
     _bluetooth.disable();
    }
    /* 使设备可以被搜索 */
    public void onMakeDiscoverableButtonClicked(View view){
     Intent enabler = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
     startActivityForResult(enabler, REQUEST_DISCOVERABLE);
    }
    /* 初阶搜索 */
    public void onStartDiscoveryButtonClicked(View view){
     Intent enabler = new Intent(this, DiscoveryActivity.class);
     startActivity(enabler);
    }
    /* 客户端 */
    public void onOpenClientSocketButtonClicked(View view){
     Intent enabler = new Intent(this, ClientSocketActivity.class);
     startActivity(enabler);
    }
    /* 服务端 */
    public void onOpenServerSocketButtonClicked(View view){
     Intent enabler = new Intent(this, ServerSocketActivity.class);
     startActivity(enabler);
    }
    /* OBEX服务器 */
    public void onOpenOBEXServerSocketButtonClicked(View view){
     Intent enabler = new Intent(this, OBEXActivity.class);
     startActivity(enabler);
    }
   }

   public class OBEXActivity extends Activity{
    private static final String  TAG      = “@MainActivity”;
    private Handler     _handler    = new Handler();
    private BluetoothServerSocket _server;
    private BluetoothSocket   _socket;
    private static final int  OBEX_CONNECT   = 0x80;
    private static final int  OBEX_DISCONNECT   = 0x81;
    private static final int  OBEX_PUT    = 0x02;
    private static final int  OBEX_PUT_END   = 0x82;
    private static final int  OBEX_RESPONSE_OK  = 0xa0;
    private static final int  OBEX_RESPONSE_CONTINUE = 0x90;
    private static final int  BIT_MASK    = 0x000000ff;
    Thread t = new Thread() {
     public void run(){
      try{             
       _server =
BluetoothAdapter.getDefaultAdapter().listenUsingRfcommWithServiceRecord(“OBEX”,
null);             
       new Thread() {             
        public void run(){                  
         Log.d(“@Rfcom”, “begin close”);            
         try{           
          _socket.close();            
         }catch (IOException e){             
          Log.e(TAG, “”, e);            
         }          
         Log.d(“@Rfcom”, “end close”);            
        };           
       }.start();             
       _socket = _server.accept();             
       reader.start();              
       Log.d(TAG, “shutdown thread”);             
      }catch (IOException e){             
       e.printStackTrace();            
      }            
     };          
    };
    Thread reader = new Thread() {                         
     public void run(){             
      try{
       Log.d(TAG, “getting inputstream”);             
       InputStream inputStream =
_socket.getInputStream();             
       OutputStream outputStream =
_socket.getOutputStream();             
       Log.d(TAG, “got inputstream”);             
       int read = -1;           
       byte[] bytes = new byte[2048];
       ByteArrayOutputStream baos = new
ByteArrayOutputStream(bytes.length);
       while ((read = inputStream.read(bytes)) != -1){
        baos.write(bytes, 0, read);
        byte[] req = baos.toByteArray();
        int op = req[0] & BIT_MASK;
        Log.d(TAG, “read:” + Arrays.toString(req));
        Log.d(TAG, “op:” + Integer.toHexString(op));
        switch (op){
         case OBEX_CONNECT:
          outputStream.write(new byte[] { (byte) OBEX_RESPONSE_OK,
0, 7, 16, 0, 4, 0 });
          break;
         case OBEX_DISCONNECT:
          outputStream.write(new byte[] { (byte) OBEX_RESPONSE_OK,
0, 3, 0 });
          break;
         case OBEX_PUT:
          outputStream.write(new byte[] { (byte)
OBEX_RESPONSE_CONTINUE, 0, 3, 0 });
          break;
         case OBEX_PUT_END:
          outputStream.write(new byte[] { (byte) OBEX_RESPONSE_OK,
0, 3, 0 });
          break;
         default:
          outputStream.write(new byte[] { (byte) OBEX_RESPONSE_OK,
0, 3, 0 });
        }
        Log.d(TAG, new String(baos.toByteArray(), “utf-8”));
        baos = new ByteArrayOutputStream(bytes.length);
       }
       Log.d(TAG, new String(baos.toByteArray(), “utf-8”));
      }catch (IOException e){
       e.printStackTrace();
      }
     };
    };
    private Thread put = new Thread() {
     public void run(){            
     };           
    };
    public void onCreate(Bundle savedInstanceState){
     super.onCreate(savedInstanceState);
     setContentView(R.layout.obex_server_socket);
     t.start();
    }
    protected void onActivityResult(int requestCode, int resultCode,
Intent data){
     Log.d(TAG, data.getData().toString());
     switch (requestCode){
      case (1):
       if (resultCode == Activity.RESULT_OK){
        Uri contactData = data.getData();
        Cursor c = managedQuery(contactData, null, null, null, null);
        for (; c.moveToNext();){
         Log.d(TAG, “c1—————————————“);
         dump(c);
         Uri uri = Uri.withAppendedPath(data.getData(),
ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
         Cursor c2 = managedQuery(uri, null, null, null, null);
         for (; c2.moveToNext();){
          Log.d(TAG, “c2—————————————“);
          dump(c2);
         }
        }
       }
       break;
     }
    }
    private void dump(Cursor c){
     for (int i = 0, size = c.getColumnCount(); i < size; ++i){
      String col = c.getColumnName(i);
      String s = c.getString(i);
      Log.d(TAG, col + “=” + s);
     }
    }
   }

   abstract class SamplesUtils{
    public static void indeterminate(Context context, Handler handler,
String message, final Runnable runnable, OnDismissListener
dismissListener){
     try{
      indeterminateInternal(context, handler, message, runnable,
dismissListener, true);
     }catch (Exception e){
      ; // nop.
     }
    }
    public static void indeterminate(Context context, Handler handler,
String message, final Runnable runnable, OnDismissListener
dismissListener,boolean cancelable){
     try{
      indeterminateInternal(context, handler, message, runnable,
dismissListener, cancelable);
     }catch (Exception e){
      ; // nop.
     }
    }
    private static ProgressDialog createProgressDialog(Context context,
String message){
     ProgressDialog dialog = new ProgressDialog(context);
     dialog.setIndeterminate(false);
     dialog.setMessage(message);
     return dialog;
    }
    private static void indeterminateInternal(Context context, final
Handler handler, String message, final Runnable runnable,
     OnDismissListener dismissListener, boolean cancelable){
      final ProgressDialog dialog = createProgressDialog(context,
message);
      dialog.setCancelable(cancelable);
      if (dismissListener != null){
       dialog.setOnDismissListener(dismissListener);
      }
      dialog.show();
      new Thread(){
       @Override
       public void run(){
        runnable.run();
        handler.post(new Runnable() {
         public void run(){
          try{
           dialog.dismiss();
          }catch (Exception e){
           ; // nop.
          }
         }
        });
       };
      }.start();
     }
   }

   discovery.xml
   <?xml version=”1.0″ encoding=”utf-8″?>
    <LinearLayout
     xmlns:android=”http://schemas.android.com/apk/res/android
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”>
     <ListView
      android:id=”@+id/android:list”
      android:layout_width=”fill_parent”
      android:layout_height=”fill_parent” />
       <!–
       <TextView
        android:id=”@+id/android:empty”
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:text=”no device found” />
       –>
    </LinearLayout>

   main.xml
   <?xml version=”1.0″ encoding=”utf-8″?>
    <LinearLayout
     xmlns:android=”http://schemas.android.com/apk/res/android
     android:orientation=”vertical”
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”
     android:padding=”10dip”>
     <Button
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”打开蓝牙”
      android:onClick=”onEnableButtonClicked” />
     <Button
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”关闭蓝牙”
      android:onClick=”onDisableButtonClicked” />
     <Button
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”允许搜索”
      android:onClick=”onMakeDiscoverableButtonClicked” />
     <Button
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”开头搜索”
      android:onClick=”onStartDiscoveryButtonClicked” />
     <Button
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”客户端”
      android:onClick=”onOpenClientSocketButtonClicked” />
     <Button
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”服务器端”
      android:onClick=”onOpenServerSocketButtonClicked” />
     <Button
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”OBEX服务器”
      android:onClick=”onOpenOBEXServerSocketButtonClicked” />
    </LinearLayout>

   server_socket.xml
   <?xml version=”1.0″ encoding=”utf-8″?>
    <LinearLayout
     xmlns:android=”http://schemas.android.com/apk/res/android
     android:orientation=”vertical”
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”
     android:padding=”10dip”>
     <Button
      android:layout_width=”fill_parent”
      android:layout_height=”wrap_content”
      android:text=”Stop server”
      android:onClick=”onButtonClicked” />
     <ListView
      android:id=”@+id/android:list”
      android:layout_width=”fill_parent”
      android:layout_height=”fill_parent” />
    </LinearLayout>

   obex_server_socket.xml
   <?xml version=”1.0″ encoding=”utf-8″?>
    <LinearLayout
     xmlns:android=”http://schemas.android.com/apk/res/android
     android:orientation=”vertical”
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”
     android:padding=”10dip”>
    </LinearLayout>

   client_socket.xml
   <?xml version=”1.0″ encoding=”utf-8″?>
    <LinearLayout
     xmlns:android=”http://schemas.android.com/apk/res/android
     android:orientation=”vertical”
     android:layout_width=”fill_parent”
     android:layout_height=”fill_parent”
     android:padding=”10dip”>
    </LinearLayout>

   AndroidManifest.xml
   <?xml version=”1.0″ encoding=”utf-8″?>
    <manifest
     xmlns:android=”http://schemas.android.com/apk/res/android
     package=”com.yarin.android.Examples_08_09″
     android:versionCode=”1″
     android:versionName=”1.0″>
    <application android:icon=”@drawable/icon”
android:label=”@string/app_name”>
    <activity
android:name=”.Activity01″android:label=”@string/app_name”>
     <intent-filter>
      <action android:name=”android.intent.action.MAIN” />
      <category android:name=”android.intent.category.LAUNCHER”
/>
     </intent-filter>
    </activity>
    <activity
android:name=”.DiscoveryActivity”android:theme=”@style/Theme.Transparent”>
     <intent-filter>
      <action android:name=”android.intent.action.MAIN” />
      <category android:name=”android.intent.category.DEFAULT”
/>
     </intent-filter>
    </activity>
    <activity
android:name=”.ClientSocketActivity”android:theme=”@style/Theme.Transparent”>
     <intent-filter>
      <action android:name=”android.intent.action.MAIN” />
      <category android:name=”android.intent.category.DEFAULT”
/>
     </intent-filter>
    </activity>
    <activity
android:name=”.ServerSocketActivity”android:theme=”@style/Theme.Transparent”>
     <intent-filter>
      <action android:name=”android.intent.action.MAIN” />
      <category android:name=”android.intent.category.DEFAULT”
/>
     </intent-filter>
    </activity>
    <activity
android:name=”.OBEXActivity”android:theme=”@style/Theme.Transparent”>
     <intent-filter>
      <action android:name=”android.intent.action.MAIN” />
      <category android:name=”android.intent.category.DEFAULT”
/>
     </intent-filter>
    </activity>
   </application>
    <uses-sdk android:minSdkVersion=”5″ />
    <uses-permission android:name=”android.permission.BLUETOOTH”
/>
    <uses-permission
android:name=”android.permission.BLUETOOTH_ADMIN” />
    <uses-permission
android:name=”android.permission.READ_CONTACTS”/>
   </manifest>

 

 

相关文章