[转]Android的大网以及通信

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

 

率先片 Android网络基础
   Android平台浏览器采用了WeBKit引擎,这款号称也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 BufferedReader(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打开连接   
       InputStreamReader in = new
InputStreamReader(urlConn.getInputStream());//得到读取的情(流)  
       BufferedReader buffer = new BufferedReader(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() {
       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();          
       BufferedReader reader = new BufferedReader(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打开连接   
        InputStreamReader in = new
InputStreamReader(urlConn.getInputStream());// 得到读取的始末(流)   
        BufferedReader buffer = new BufferedReader(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类对象。对于文本方式流对象,可以行使
    InputStreamReader和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{   
         BufferedReader in = new BufferedReader(new
InputStreamReader(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);
         BufferedReader 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、把流包装进BufferReader/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 ExecutorService mExecutorService;  //线程池
用为每个客户端都打开一个线程   
     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);   
        mExecutorService.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); //连接服务器    
         mBufferedReader = new BufferedReader(new
InputStreamReader(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;
       }
      }
     
第七有的 WebKit应用 
   Android 浏览器的基础是Webkit引擎,WebKit的前身是KDE小组的KHTML.
   WebKit
    是一个开源浏览器网页排版引擎。与之对应之发动机来Gecko和Trident等。
    WebKit 由3单模块组合:
    WebKit       整个项目的称呼
    JavaScriptCore JavaScrip解释器
    WebCore  
整个项目的基本,用来落实Render引擎,解析Web页面,生成一个DOM树和一个Render树。
    WebKit的分析过程:
     1、CURL获得网站的stream。
     2、解析划分字符串。
     3、通过DOM Builer按法定的HTML规范生成DOM树。
     4、如果有Javascript,JSEngine就通过ECMA-262标准到DOM树。
    
5、把DOM传给LayoutEngine进行布局,如果发生CSS样式,就经过CSSParser解析。
     6、最后Rendering渲染出来。
   WebView
    WebView控件是WebKit类中特意就此来浏览网页的控件。
    其行使得以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来设置WebKit的有些性质、状态等。在开创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包中,有如下功能:
    BluetoothAdapter   蓝牙适配器(代表当地蓝牙适配器)
    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 =
BluetoothAdapter.getDefaultAdapter();//通过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);
      BluetoothAdapter类中其他动作常量
       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类实际是一个蓝牙硬件地址薄,该类对象是不行变更之。
那操作都是长途蓝牙硬件地址下BluetoothAdapter来创建一个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
BroadcastReceiver(){// 接收器 当搜索蓝牙设备好时调用
     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 =
BluetoothAdapter.getDefaultAdapter();//获取默认的蓝牙适配器
    
//其中listenUsingRfcommWithServiceRecord可以回去一个蓝牙服务器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 =
BluetoothAdapter.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>

 

 

相关文章