[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;//阻塞flagprivate 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 blocke.printStackTrace();}}};listview.setOnItemClickListener(myonclister);} catch (IOException e) {// TODO Auto-generated catch blocknew 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按钮@Overrideprotected 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);//初始显示本地IPbtserver=(Button)findViewById(R.id.button2);/** * SERVER端事件 */btserver.setOnClickListener(new OnClickListener(){@Overridepublic 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(){@Overridepublic 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);}});}@Overridepublic 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]

更多相关文章

  1. Android自动连接指定的WiFi热点
  2. Android编程实现连接Wifi(运用Wifi 相关 API)
  3. AirPods怎么连接Android设备 AirPods与安卓设备连接方法
  4. Android(安卓)无线调试
  5. Android(安卓)客户端与服务器交互方式
  6. android客户端与服务器数据交换原则
  7. 【Android】蓝牙开发——BLE(低功耗蓝牙)(附完整Demo)
  8. 【Android开发】Android(安卓)Host详解(翻译自官方文档)
  9. 网络编程之——他山之石OkHttp

随机推荐

  1. Android Handler:子线程发消息到UI主线程
  2. android 3d 问题汇总1
  3. Android绘图API自定义View(三)
  4. Android修改状态栏颜色
  5. Android IntentService用法和源码分析
  6. Android常用三方库混淆规则整理(小结)
  7. Android ScrollView里嵌套ListView
  8. android保存数据到xml以及pull解析模板
  9. Android ButterKnife注解式开发
  10. How to enable logging for apache commo