Android一个简单的socket通信手机间推送联系人

[size=x-small]

        初学android,没有急于去了解android各种图形类的用法,毕竟每个学Android都有一颗做游戏的心。但是通讯这一块才是一个移动终端最需要去了解的有关socket,由于之前没有怎么接触,这次借着学android的机遇学习了一下,下面就讲我我自己一个简单的socket例子。

        之前是想写一个建议聊天室的,网上有很多人都实现了,但是文章都是抄来抄去,代码也都稀稀散散不完全,给很多初学的人很莫名的感觉,在做点对点聊天之前,先明白socket怎么样通讯才是至关重要的。在做socket之前或许,用httpclient访问下PC服务器这些例子也可以尝试下,起码能熟悉android通讯中流的一些用法。

      我做了一个简单的app,毕竟是给手机之间用,它肯定有一个server端,一个client端。先把界面展示一下。



如果是server端,载入界面后就点击server端按钮,服务器就阻塞直到客户端请求,然后进入本地联系人查询页面,选好本地联系人,将联系人发送给请求端。

服务器端代码:
package com.exmessage;


import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.AlertDialog;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class PServer implements Runnable {
private TextView meesage;//聊天记录
private int zsflag=0;//阻塞flag
private ServerSocket server;
private  Activity context;
private Handler handler;
int count = 1;
private ListView listview;
private Allmessageobj messageobj =new Allmessageobj();//传输信息对象载体
private Map objmap=new HashMap();
private Allmessageobj returnobj=new Allmessageobj();
private OnItemClickListener myonclister;
private Socket client=new Socket();
private OutputStream  outdata ;
public PServer(Activity contextarg) {
try {
	context=contextarg;
	meesage=(TextView)context.findViewById(R.id.textView1);//连接信息框
	//创建属于主线程的handler  
	handler=new Handler();  
	server=new ServerSocket(10010);
         new Thread(this).start();
	context.setContentView(R.layout.conperson);
		
listview=(ListView)context.findViewById(R.id.listView1);
			
myonclister=new OnItemClickListener(){//添加事件
	        	 
public void onItemClick(AdapterView<?> arg0, View arg1,int arg2, long arg3) {
//  OutputStream  outdata = client.getOutputStream();
try {
Object objs=objmap.get(arg2);
returnobj=(Allmessageobj)objs;
zsflag=1;
context.setContentView(R.layout.activity_main);
TextView tsmessag=(TextView)context.findViewById(R.id.textView1);
EditText etx=(EditText)context.findViewById(R.id.search);
etx.setCursorVisible(false);      
etx.setFocusable(false);         
etx.setFocusableInTouchMode(false); 
tsmessag.setText("发送<"+returnobj.getName()+":"+returnobj.getPhonenum()+">成功!目标IP<"+String.valueOf(client.getInetAddress())+">");
java.io.ByteArrayOutputStream bop = new java.io.ByteArrayOutputStream();
				       	java.io.ObjectOutputStream oop;
oop = new java.io.ObjectOutputStream(bop);
oop.writeObject(returnobj);
outdata.write(bop.toByteArray());
outdata.flush();
outdata.close();
} catch (IOException e) {
// TODO Auto-generated catch block
						e.printStackTrace();
			}
					
				}};
		listview.setOnItemClickListener(myonclister);
				
		} catch (IOException e) {
		// TODO Auto-generated catch block
new AlertDialog.Builder(context).setTitle("提示").setMessage(String.valueOf(e)).setPositiveButton("OK", null).show();
		} 
	}

public void run() {
try {
	// handler.post(runnableUi); 
	while(true){ 
		 client=server.accept(); 
		 handler.post(listviewUi);
	 outdata = client.getOutputStream();
				
	
			} 
			
		} catch (Exception e) {
			e.printStackTrace();
			
	System.out.println("服务器 run 异常: " + e.getMessage());
		}
	}
	/* 读取命令 */  
	    public static String readCMDFromSocket(InputStream in)   
	    {  
	        int MAX_BUFFER_BYTES = 2048;  
	        String msg = "";  
	        byte[] tempbuffer = new byte[MAX_BUFFER_BYTES];  
	        try   
	        {  
	           int numReadedBytes = in.read(tempbuffer, 0, tempbuffer.length);  
	            msg = new String(tempbuffer, 0, numReadedBytes, "utf-8");  
	            tempbuffer = null;  
	        } catch (Exception e)   
	        {  
	            e.printStackTrace();  
	        }  
	        return msg;  
	    }  

	    Runnable   runnableUi=new  Runnable(){  
	    	       public void run() {  
	    	           //更新界面  
	    	    	   meesage.setText("信息:"+messageobj.getMessage()+"....");
	    	        	//meesage.setText(meesage.getText()+"\n"+messageobj.getIpaddress()+":"+messageobj.getMessage());  
	    	       }  
	    	         
	    	    };  

	    	    
 Runnable   listviewUi=new  Runnable(){  
		   public void run() {  
	context.setContentView(R.layout.conperson);
    listview=(ListView)context.findViewById(R.id.listView1);
		    				listview.setOnItemClickListener(myonclister);
		    	           //更新界面  
		    	  List list=new ArrayList();
Uri uri = Uri.parse("content://com.android.contacts/contacts");
//String selection = "mimetype='vnd.android.cursor.item/contact_event' and data2='3'";
Cursor cursor = context.getContentResolver().query(uri, new String[]{"_id"}, null, null, null);
		 //Cursor cur = MainActivity.this.getContentResolver().query(ContactsContract.Data.CONTENT_URI, projection, selection, null, null); 
		   	List params=new ArrayList();
		   	List datalist=new ArrayList();
		while (cursor.moveToNext()) { 
		   					messageobj=new Allmessageobj();
		   				            int contractID = cursor.getInt(0); 
		   				            StringBuilder sb = new StringBuilder(); 
		   				           // sb.append(contractID); 
		   				           // Uri uri11 = ContactsContract.Contacts.CONTENT_URI; 
		   				            uri = Uri.parse("content://com.android.contacts/contacts/" + contractID + "/data"); 
		   				           Cursor cursor1 = context.getContentResolver().query(uri, new String[]{"mimetype", "data1", "data2"}, null, null, null); 
		   				           //UserPhoneVO vo=new UserPhoneVO();
		   				           while (cursor1.moveToNext()) { 
		   				                 String data1 = cursor1.getString(cursor1.getColumnIndex("data1")); 
		   				               String mimeType = cursor1.getString(cursor1.getColumnIndex("mimetype")); 
		   				               if ("vnd.android.cursor.item/name".equals(mimeType)) { 
		   				            	messageobj.setName(data1);
		   				                     sb.append(data1+"-"); 
		   				                } else if ("vnd.android.cursor.item/email_v2".equals(mimeType)) {
		   				                    sb.append( data1+"-"); 
		   				                } else if ("vnd.android.cursor.item/phone_v2".equals(mimeType)) {
		   				                   sb.append(data1+"-"); 
		   				                messageobj.setPhonenum(data1);
		   				                }                 
		   				            }  
		   				       
		   				        datalist.add(messageobj);
		   				          
		   				           cursor1.close(); 
		   				        } 
		   				 
		   				   cursor.close();
		   				   for(int i=0;i<datalist.size();i++){
		   					Allmessageobj  messavo=(Allmessageobj)datalist.get(i);
		   					objmap.put(i,messavo);
		   					params.add(messavo.getName()+":"+messavo.getPhonenum());
		   				   }
		    	    	   listview.setAdapter(new ArrayAdapter (context,android.R.layout.simple_list_item_1,params)); 
		    	    	
		    	    	   
		    	   //listview.setAdapter(adapter);
 // meesage.setText("信息:"+messageobj.getMessage()+"....");
//meesage.setText(meesage.getText()+"\n"+messageobj.getIpaddress()+":"+messageobj.getMessage());  
		    	   }  
		    	         
		    	    }; 
}



client端载入页面选择好请求方的IP地址点击建立连接,完成一次请求。

客户端代码:
package com.exmessage;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;

import android.app.Activity;
import android.app.AlertDialog;
import android.os.Handler;
import android.widget.EditText;
import android.widget.TextView;

public class Client implements Runnable{
	
	/** 端口号 */
	public static final int PORT = 10010;
	private Activity context;
	private EditText txtvs;
	private TextView dismes;//显示连接信息
	/** ip 地址 */
	public  String IP;
	private Allmessageobj returnobj=new Allmessageobj();
	 private Handler handler=new Handler();  
	public Client(Activity contextarg) {
		context=contextarg;
		txtvs=(EditText)context.findViewById(R.id.search);
		dismes=(TextView)context.findViewById(R.id.textView1);
		IP=String.valueOf(txtvs.getText());
		//handler=new Handler();
		//new AlertDialog.Builder(context).setTitle("提示").setMessage("连接:"+IP+"....").setPositiveButton("OK", null).show();
		run();
	}
	public void run() {
		Socket socket = null;
		try {
				// 创建一个流套接字并将其连接到指定主机上的指定端口号
			//while (true) {
				// 创建一个流套接字并将其连接到指定主机上的指定端口号
				socket = new Socket(IP, PORT);
				
				// 读取服务器端数据
				//System.out.println("是否连接"+socket.isConnected());
//				System.out.println("BufferSize"+socket.getReceiveBufferSize());
//				String inputstr = new BufferedReader(new InputStreamReader(System.in)).readLine();
			//	InputStream inputStream = new ByteArrayInputStream(abc.toString().getBytes());
				//String str = new BufferedReader(new InputStreamReader(inputStream)).readLine();
				//ObjectOutputStream output=new ObjectOutputStream(socket.getOutputStream());
				InputStream indata=socket.getInputStream();
				//DataOutputStream outdata=new DataOutputStream(socket.getOutputStream());
				//Allmessageobj outmessage=new Allmessageobj();
				//outmessage.setMessage("已响应");
				//outdata.writeObject(outmessage);
				//outdata.writeUTF("请求中。。。");
				//indata.read();
				//byte b[] = utfstring.getBytes();
				//String usus=indata.read();
				//byte[] bytess=usus.getBytes();
			    java.io.ByteArrayOutputStream bout = new java.io.ByteArrayOutputStream();
						byte[] bt = new byte[2014];
						//while(indata.read(bt)!= -1)
					   //  {
						    indata.read(bt);
							bout.write(bt,0,bt.length);
						//}
						java.io.ByteArrayInputStream biin = new ByteArrayInputStream(bout.toByteArray());
						java.io.ObjectInputStream isr=new java.io.ObjectInputStream(biin);
				Object obj = isr.readObject();
				returnobj=(Allmessageobj)obj;
				//dismes.setText(returnobj.getName()+"--"+returnobj.getPhonenum());
				 dismes.setText(returnobj.getName()+"--"+returnobj.getPhonenum());
				 new AlertDialog.Builder(context).setTitle("提示").setMessage(returnobj.getName()+"--"+returnobj.getPhonenum()).setPositiveButton("OK", null).show();
				// handler.post(runnableUi);
			//}
		} catch (Exception e) {
			new AlertDialog.Builder(context).setTitle("提示").setMessage(String.valueOf(e)).setPositiveButton("OK", null).show();
		} finally {
			if (socket != null) {
				try {
					socket.close();
				} catch (Exception e) {
					socket = null;
					System.out.println("客户端 finally 异常: " + e.getMessage());
				}
			}
		}
	}
	
    Runnable   runnableUi=new  Runnable(){  
	       public void run() {  
	           //更新界面  
	    	   new AlertDialog.Builder(context).setTitle("提示").setMessage(returnobj.getName()+"--"+returnobj.getPhonenum()).setPositiveButton("OK", null).show();
	        	//meesage.setText(meesage.getText()+"\n"+messageobj.getIpaddress()+":"+messageobj.getMessage());  
	       }  
	         
	    }; 

}



MainActivity.java
package com.exmessage;

import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

	private EditText etx;//IP地址
	private TextView txtvs;//显示连接信息
	private Button btsend;//建立连接
	private String IPAddress;
	private Button btserver;//server按钮
	
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		btsend=(Button)findViewById(R.id.button1);
		etx=(EditText)findViewById(R.id.search);
		txtvs=(TextView)findViewById(R.id.textView1);
		IPAddress=getlocalip();
		txtvs.setText("本地WIFI-IP地址:"+IPAddress);//初始显示本地IP
		btserver=(Button)findViewById(R.id.button2);
		
		/**
		 * SERVER端事件
		 */
		btserver.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				/**
				 * IP输入只读
				 */
				etx.setCursorVisible(false);      
				etx.setFocusable(false);         
				etx.setFocusableInTouchMode(false); 
				//开启server端线程
				new AlertDialog.Builder(MainActivity.this).setTitle("提示").setMessage("启动server端监听").setPositiveButton("OK", null).show();
				new PServer(MainActivity.this);
			}
			
		});
		/**
		 * client端事件
		 */
		
		btsend.setOnClickListener(new OnClickListener(){

			@Override
			public void onClick(View arg0) {
				/**
				 * IP输入只读
				 */
				etx.setCursorVisible(false);      
				etx.setFocusable(false);         
				etx.setFocusableInTouchMode(false); 
				//开启server端线程
				//new AlertDialog.Builder(MainActivity.this).setTitle("提示").setMessage("启动请求......").setPositiveButton("OK", null).show();
				new Client(MainActivity.this);
			}
			
		});
		
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	/**
	 * 通过wifi连接获取IP地址
	 * @return
	 */
	private String getlocalip(){  
		       WifiManager wifiManager = (WifiManager)getSystemService(Context.WIFI_SERVICE);    
		        WifiInfo wifiInfo = wifiManager.getConnectionInfo();    
		        int ipAddress = wifiInfo.getIpAddress();   
		      //  Log.d(Tag, "int ip "+ipAddress);  
		        if(ipAddress==0)return null;  
		        return ((ipAddress & 0xff)+"."+(ipAddress>>8 & 0xff)+"."  
		               +(ipAddress>>16 & 0xff)+"."+(ipAddress>>24 & 0xff));  
		    } 

	

}




Object流对象:
package com.exmessage;

import java.io.Serializable;

public class Allmessageobj implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1579114883234266292L;
	public String ipaddress;
	public String message;
	public String flagcode;
	public String name;
	public String phonenum;
	public String getIpaddress() {
		return ipaddress;
	}
	public void setIpaddress(String ipaddress) {
		this.ipaddress = ipaddress;
	}
	public String getMessage() {
		return message;
	}
	public void setMessage(String message) {
		this.message = message;
	}
	public String getFlagcode() {
		return flagcode;
	}
	public void setFlagcode(String flagcode) {
		this.flagcode = flagcode;
	}
	
	public String toString(){
		return name+"----"+phonenum;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPhonenum() {
		return phonenum;
	}
	public void setPhonenum(String phonenum) {
		this.phonenum = phonenum;
	}
	
	

}




界面布局:

activity_main.xml:
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TableRow
        android:id="@+id/tableRow1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <EditText
            android:id="@+id/search"
            android:layout_width="140dip"
            android:layout_height="wrap_content"
            android:hint="@string/search_hint"
            android:imeOptions="actionSend"
            android:inputType="text"
            android:singleLine="true" >

            <requestFocus />
        </EditText>


        <Button
            android:id="@+id/button1"
            style="?android:attr/buttonStyleSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/connbegain" />
        
        <Button
            android:id="@+id/button2"
            style="?android:attr/buttonStyleSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/asserver" />
    </TableRow>

    <TableRow
        android:id="@+id/tableRow2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.01" >

        <TextView
            android:id="@+id/textView1"
            android:layout_width="wrap_content"
           android:layout_height="wrap_content"
            />
    </TableRow>

</LinearLayout>




       
       
   

联系人选择布局:

conperson.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

    </LinearLayout>




AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.exmessage"
    android:versionCode="1"
    android:versionName="1.0" >

<uses-permission android:name="android.permission.READ_CONTACTS" /> 
<uses-permission android:name="android.permission.WRITE_CONTACTS" /> 
<uses-permission android:name="android.permission.INTERNET"/>  
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<!--  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>  -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>  
    <!--  <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="8" />
-->

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.exmessage.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>




备注:有些权限没有用到,可适当更改,有预留给其他功能开发用。[/size]

猜你喜欢

转载自model2012.iteye.com/blog/1996585