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

[size=x-small]

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

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

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

[img]http://dl2.iteye.com/upload/attachment/0092/6005/ab4079d2-1c70-3109-bec6-77d10e1cd040.png[/img]

如果是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]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值