Android手機Socket連接配接内網列印機
通常的列印裝置端口都是9100
首先我先把搜尋内網列印裝置的方法告訴大家,其實原理很簡單就是通過socket 循環connect 192.168.1.2-192.168.1.254的所有連接配接裝置的9100端口,連接配接成功的一般情況下都是列印裝置(可能有誤希望大家糾正哦)
首先擷取本機IP位址
//擷取本機IPv4
public String getLocalHostIp() {
try {
Enumeration<NetworkInterface> en = NetworkInterface
.getNetworkInterfaces();
// 周遊所用的網絡接口
while (en.hasMoreElements())
{
NetworkInterface nif = en.nextElement();// 得到每一個網絡接口綁定的所有ip
Enumeration<InetAddress> inet = nif.getInetAddresses();
// 周遊每一個接口綁定的所有ip
while (inet.hasMoreElements())
{
InetAddress ip = inet.nextElement();
if (!ip.isLoopbackAddress()&& InetAddressUtils.isIPv4Address(ip
.getHostAddress()))
{
mIpTv.setText(ip.getHostAddress());
return ip.getHostAddress();
}
}
}
}
catch (SocketException e) {
Log.e(DEBUG_TAG, "擷取本地ip位址失敗");
e.printStackTrace();
}
return null;
}
擷取成功後如果是 192.168.1.XXX
private class RunThread extends Thread{
private int finishSize=;
public RunThread(){
}
@Override
public void run() {
if(pool==null){
pool = Executors.newScheduledThreadPool();
}
for (int i = ; i < ; ++i) {
final int index = i;
pool.execute(new Runnable() {
@Override
public void run() {
try {
String ipaddress = "192.168.1." + index;
NetPrinter printer = new NetPrinter();
printer.Open(ipaddress, NetPrinter.POS_OPEN_NETPORT);
if (printer.IFOpen) {
Log.e(DEBUG_TAG, "connect success" + ipaddress);
} else {
Log.e(DEBUG_TAG, "connect fail" + ipaddress);
}
Thread.sleep();
} catch (Exception e) {
} finally {
synchronized (this) {
finishSize++;
Log.e(DEBUG_TAG, "finishSize:" + finishSize);
}
}
}
});
}
while (true) {
synchronized (this) {
Log.e(DEBUG_TAG, "finishSize:" + finishSize);
if (finishSize == ) {
isFinish=true;
lastFinishTime=System.currentTimeMillis();
Log.e(DEBUG_TAG, "finishSize:" + finishSize);
}
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class NetPrinter {
public Socket socket;
private static final String DEBUG_TAG="NetPrinter";
public static final int POS_OPEN_NETPORT = ;// 0X238c
public boolean IFOpen = false;
public int Net_ReceiveTimeout = ;
//網絡列印機 打開網絡列印機
public boolean Open(String ipaddress, int netport) {
if (socket == null) {
try {
SocketAddress ipe = new InetSocketAddress(Inet4Address.getByName(ipaddress) ,netport);
Log.e(DEBUG_TAG, Inet4Address.getByName(ipaddress)+"|"+netport);
socket = new Socket(); //Socket(ipaddress, netport,true);
socket.connect(ipe, Net_ReceiveTimeout);
IFOpen = true;
} catch(Exception e) {
IFOpen = false;
}
} else {
try {
socket.close();
SocketAddress ipe = new InetSocketAddress(Inet4Address.getByName(ipaddress),netport);
Log.e(DEBUG_TAG, Inet4Address.getByName(ipaddress)+"|"+netport);
socket = new Socket(); //Socket(ipaddress, netport,true);
socket.connect(ipe,Net_ReceiveTimeout);
IFOpen = true;
} catch(Exception e) {
IFOpen = false;
}
}
if(IFOpen){
Close();
}
return IFOpen;
}
//網絡列印機 關閉
public void Close() {
try {
socket.close();
socket = null;
} catch(Exception e) {
e.printStackTrace();
}
}
}
如果 IFOpen=true;那麼就應該是列印裝置了,大家可以用清單緩存起來搜尋到的可用列印裝置了。
然後呢,我們需要嘗試去連接配接上列印裝置和完成我們的列印任務了。
public class EthernetPort {
private static final String DEBUG_TAG = "EthernetService";
public static final int STATE_NONE = ;
public static final int STATE_LISTEN = ;
public static final int STATE_CONNECTING = ;
public static final int STATE_CONNECTED = ;
public static final int STATE_INVALID_PRINTER = ;
public static final int STATE_VALID_PRINTER = ;
private boolean mClosePort;
private int mState;
private int mmBytesAvailable;
private int mPrinterId;
private String mIp;
private int mPortNumber;
private ConnectThread mConnectThread = null;
private ConnectedThread mConnectedThread = null;
private ConnectListener listener=null;
public EthernetPort(int id, String Ip, int Port,ConnectListener l)
{
this.mState = ;
this.mPortNumber = Port;
this.mIp = Ip;
this.mPrinterId = id;
this.listener=l;
}
protected synchronized void setState(int state)
{
Log.d("GpPort", "setState() " + this.mState + " -> " + state);
Log.d("GpPort", "PrinterId() " + this.mPrinterId + " -> " + this.mPrinterId);
this.mState = state;
}
protected int getState()
{
return this.mState;
}
public synchronized void connect()
{
Log.d("EthernetService", "connect to Ip :" + this.mIp + " Port: " + this.mPortNumber);
if (this.mConnectThread != null)
{
this.mConnectThread.cancel();
this.mConnectThread = null;
}
if (this.mConnectedThread != null)
{
this.mConnectedThread.cancel();
this.mConnectedThread = null;
}
this.mConnectThread = new ConnectThread(this.mIp, this.mPortNumber);
this.mConnectThread.start();
setState(STATE_CONNECTING);
}
public synchronized void connected(Socket socket, String ip)
{
Log.d("EthernetService", "connected");
if (this.mConnectThread != null)
{
this.mConnectThread.cancel();
this.mConnectThread = null;
}
if (this.mConnectedThread != null)
{
this.mConnectedThread.cancel();
this.mConnectedThread = null;
}
this.mConnectedThread = new ConnectedThread(socket);
this.mConnectedThread.start();
setState(STATE_CONNECTED);
}
public synchronized void stop()
{
Log.d("EthernetService", "stop");
setState(STATE_NONE);
if (this.mConnectThread != null)
{
this.mConnectThread.cancel();
this.mConnectThread = null;
}
if (this.mConnectedThread != null)
{
this.mConnectedThread.cancel();
this.mConnectedThread = null;
}
}
public GpCom.ERROR_CODE writeDataImmediately(Vector<Byte> data)
{
GpCom.ERROR_CODE retval = GpCom.ERROR_CODE.SUCCESS;
if (this.mState != ) {
return GpCom.ERROR_CODE.PORT_IS_NOT_OPEN;
}
retval = mConnectedThread.writeDataImmediately(data);
return retval;
}
private class ConnectThread
extends Thread
{
private Socket mmSocket;
private String mmIp;
InetAddress mmIpAddress;
SocketAddress mmRemoteAddr;
public ConnectThread(String Ip, int Port)
{
this.mmSocket = new Socket();
try
{
this.mmIpAddress = Inet4Address.getByName(Ip);
this.mmRemoteAddr = new InetSocketAddress(this.mmIpAddress, Port);
this.mmIp = Ip;
}
catch (UnknownHostException e)
{
Log.e("EthernetService",
"IpAddress is invalid",
e);
setState(STATE_NONE);
if(listener!=null)
listener.connectState(mPrinterId,mState);
}
}
public void run()
{
Log.i("EthernetService", "BEGIN mConnectThread");
setName("ConnectThread");
try
{
this.mmSocket.connect(this.mmRemoteAddr, );
}
catch (IOException e)
{
setState(STATE_NONE);
if(listener!=null)
listener.connectState(mPrinterId,mState);
try
{
this.mmSocket.close();
}
catch (IOException e1)
{
Log.e("EthernetService",
"unable to close() socket during connection failure",
e1);
}
EthernetPort.this.stop();
return;
}
synchronized (this)
{
mConnectThread = null;
}
connected(this.mmSocket, this.mmIp);
}
public void cancel()
{
try
{
this.mmSocket.close();
}
catch (IOException e)
{
Log.e("EthernetService", "close() of connect socket failed", e);
setState(STATE_NONE);
}
}
}
private class ConnectedThread
extends Thread
{
private final Socket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(Socket socket)
{
Log.d("EthernetService", "create ConnectedThread");
this.mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try
{
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
}
catch (IOException e)
{
Log.e("EthernetService", "temp sockets not created", e);
if(listener!=null)
listener.connectState(mPrinterId,mState);
}
this.mmInStream = tmpIn;
this.mmOutStream = tmpOut;
}
public void run()
{
Log.i("EthernetService", "BEGIN mConnectedThread");
EthernetPort.this.mClosePort = false;
if(listener!=null)
listener.connectState(mPrinterId,mState);
while (!EthernetPort.this.mClosePort) {
try
{
//如果隻是要列印這部分代碼可以不要,隻需要保證線程alive, 可以加個100mm的sleep CPU 開銷會小很多
EthernetPort.this.mmBytesAvailable = this.mmInStream.available();
if (EthernetPort.this.mmBytesAvailable > )
{
byte[] ReceiveData = new byte[];
int bytes = this.mmInStream.read(ReceiveData);
Log.e("EthernetService", "bytes " + bytes);
if (bytes > )
{
Log.d("printer.id", ""+EthernetPort.this.mPrinterId);
Log.d("device.readcnt", "" + bytes);
Log.d("device.read", "" + ReceiveData);
}
else
{
Log.e("EthernetService", "disconnected");
EthernetPort.this.stop();
}
}
}
catch (IOException e)
{
setState(STATE_NONE);
Log.e("EthernetService", "disconnected", e);
}
}
Log.d("EthernetService", "Closing ethernet work");
}
public void cancel()
{
try
{
EthernetPort.this.mClosePort = true;
this.mmOutStream.flush();
this.mmSocket.close();
}
catch (IOException e)
{
setState(STATE_NONE);
}
}
public int writeDataImmediately(Vector<Byte> data)
{
int retval = ;//SUCCESS
if ((this.mmSocket != null) && (this.mmOutStream != null))
{
if ((data != null) && (data.size() > ))
{
byte[] sendData = new byte[data.size()];
if (data.size() > )
{
for (int i = ; i < data.size(); i++) {
sendData[i] = ((Byte)data.get(i)).byteValue();
}
try
{
this.mmOutStream.write(sendData);
this.mmOutStream.flush();
}
catch (Exception e)
{
Log.d("EthernetService", "Exception occured while sending data immediately: " +
e.getMessage());
retval = -;//FAILED
}
}
}
}
else {
retval = -;//PORT_IS_NOT_OPEN
}
return retval;
}
}
}
這裡我有添加一個列印機連接配接狀态的回調接口,大家可以根據自己的情況來使用。
public interface ConnectListener {
void connectState(int mPrinterId,int status);
}
正式開始連接配接列印裝置了
private void connectPrinter(String printer){
EthernetPort mPort=new EthernetPort(,printer,,this);//第一個參數是如果要同時連接配接多個列印機的話用來區分列印裝置的ID(可以不要,直接用IP來區分裝置也可以的),第二個參數呢就是列印機的IP位址,第三個端口9100咯,第四個就是之前我自己用的一個列印機連接配接狀态的回調接口
mPort.connect();
}
當回調接口狀态為STATE_CONNECTED的時候,表示我們已經連接配接成功了可以開始列印東西了。
int rel;
rel = mPort.writeDataImmediately(datas);
心情不好,有問題大家可以回複,1年多沒寫代碼了。希望各位大神批評教育指點一二!