updated win32 example with latest decode lib
This commit is contained in:
@@ -3,7 +3,6 @@ package net.irext.ircontrol.ui.fragment;
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.hardware.ConsumerIrManager;
|
||||
import android.net.InetAddresses;
|
||||
import android.os.*;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -23,15 +22,13 @@ import net.irext.ircontrol.utils.FileUtils;
|
||||
import net.irext.ircontrol.utils.MessageUtil;
|
||||
import net.irext.ircontrol.utils.ToastUtils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.net.Socket;
|
||||
import java.util.Base64;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Objects;
|
||||
|
||||
import net.irext.ircontrol.utils.IRSocketEmitter;
|
||||
|
||||
/**
|
||||
* Filename: ControlFragment.java
|
||||
* Revised: Date: 2017-04-22
|
||||
@@ -63,24 +60,7 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
private static final int KEY_HOME = 9;
|
||||
private static final int KEY_MENU = 10;
|
||||
|
||||
private static final int EMITTER_PORT = 8000;
|
||||
|
||||
private static final int EMITTER_DISCONNECTED = 0;
|
||||
private static final int EMITTER_CONNECTED = 1;
|
||||
private static final int EMITTER_AVAILABLE = 2;
|
||||
private static final int EMITTER_BIN_RECEIVED = 3;
|
||||
|
||||
private Socket emitterConn = null;
|
||||
private int emitterConnected = EMITTER_DISCONNECTED;
|
||||
|
||||
private static final String A_REQUEST_HELLO = "a_hello";
|
||||
private static final String E_RESPONSE_HELLO = "e_hello";
|
||||
|
||||
private static final String A_REQUEST_BIN = "a_bin";
|
||||
private static final String E_RESPONSE_BIN = "e_bin";
|
||||
|
||||
private static final String A_REQUEST_CTRL = "a_control";
|
||||
private static final String E_RESPONSE_CTRL = "e_control";
|
||||
private IRSocketEmitter mIRSocketEmitter;
|
||||
|
||||
private MsgHandler mHandler;
|
||||
|
||||
@@ -135,19 +115,35 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
mBtnConnect = view.findViewById(R.id.btn_connect_emitter);
|
||||
mVWConnectStatus = view.findViewById(R.id.vw_connect_status);
|
||||
|
||||
// Initialize IRSocketEmitter with callback
|
||||
mIRSocketEmitter = new IRSocketEmitter(new IRSocketEmitter.IRSocketEmitterCallback() {
|
||||
@Override
|
||||
public void onConnected() {
|
||||
onEmitterConnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected() {
|
||||
onEmitterDisconnected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(String response) {
|
||||
onEmitterResponse(response);
|
||||
}
|
||||
});
|
||||
|
||||
mBtnConnect.setOnClickListener(new View.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
vibrate(mParent);
|
||||
String emitterIp = mEtEmitterIp.getText().toString();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
if (!InetAddresses.isNumericAddress(emitterIp)) {
|
||||
ToastUtils.showToast(mParent, mParent.getString(R.string.input_emitter_ip_address), null);
|
||||
return;
|
||||
}
|
||||
if (isIpAddress(emitterIp)) {
|
||||
ToastUtils.showToast(mParent, mParent.getString(R.string.input_emitter_ip_address), null);
|
||||
return;
|
||||
}
|
||||
connectToEmitter(emitterIp, String.valueOf(EMITTER_PORT));
|
||||
mIRSocketEmitter.connectToEmitter(emitterIp, String.valueOf(IRSocketEmitter.EMITTER_PORT));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -165,7 +161,6 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
} else {
|
||||
getRemote();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void getRemote() {
|
||||
@@ -250,46 +245,38 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
/* translate key code for AC according to the mapping above */
|
||||
/* ac status is useless for decoding devices other than AC, it's an optional parameter */
|
||||
/* change wind dir is an optional parameter, set to 0 as default */
|
||||
if (mIRSocketEmitter.getConnectionStatus() == IRSocketEmitter.EMITTER_CONNECTED) {
|
||||
decodeOnBoard(inputKeyCode, acStatus, 0);
|
||||
} else {
|
||||
decodeInApp(inputKeyCode, acStatus, 0);
|
||||
}
|
||||
return mIRDecode.decodeBinary(inputKeyCode, acStatus, 0);
|
||||
}
|
||||
|
||||
private void onEmitterConnected() {
|
||||
Log.d(TAG, "the emitter is connected");
|
||||
emitterConnected = EMITTER_CONNECTED;
|
||||
mParent.runOnUiThread(() -> {
|
||||
mBtnConnect.setImageDrawable(AppCompatResources.getDrawable(mParent, R.mipmap.button_unlink));
|
||||
mVWConnectStatus.setBackgroundColor(Color.parseColor("#3FAFFF"));
|
||||
});
|
||||
}
|
||||
private void onEmitterDisconnected() {
|
||||
if (EMITTER_DISCONNECTED != emitterConnected) {
|
||||
Log.d(TAG, "the emitter is disconnected");
|
||||
} else {
|
||||
Log.d(TAG, "the emitter is disconnected not status is not changed");
|
||||
}
|
||||
|
||||
mParent.runOnUiThread(() -> {
|
||||
if (EMITTER_DISCONNECTED != emitterConnected) {
|
||||
ToastUtils.showToast(mParent, mParent.getString(R.string.connect_failed), Toast.LENGTH_SHORT);
|
||||
} else {
|
||||
ToastUtils.showToast(mParent, mParent.getString(R.string.connect_disconnected), Toast.LENGTH_SHORT);
|
||||
}
|
||||
ToastUtils.showToast(mParent, mParent.getString(R.string.connect_disconnected), Toast.LENGTH_SHORT);
|
||||
mBtnConnect.setImageDrawable(AppCompatResources.getDrawable(mParent, R.mipmap.button_link));
|
||||
mVWConnectStatus.setBackgroundColor(Color.parseColor("#FF7F7F"));
|
||||
});
|
||||
|
||||
emitterConnected = EMITTER_DISCONNECTED;
|
||||
}
|
||||
|
||||
private void processEHello(String response) {
|
||||
sendHelloToEmitter();
|
||||
mIRSocketEmitter.sendHelloToEmitter();
|
||||
}
|
||||
|
||||
private void processEBin(String response) {
|
||||
String binFileName = FileUtils.binDir + FileUtils.FILE_NAME_PREFIX +
|
||||
mCurrentRemoteControl.getRemoteMap() + FileUtils.FILE_NAME_EXT;
|
||||
byte []binContent = FileUtils.getByteArrayFromFile(binFileName);
|
||||
sendBinToEmitter(binContent);
|
||||
mIRSocketEmitter.sendBinToEmitter(binContent, mCurrentRemoteControl.getCategoryId(), mCurrentRemoteControl.getSubCategory());
|
||||
}
|
||||
|
||||
private void processECtrl(String response) {
|
||||
@@ -298,90 +285,17 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
|
||||
private void onEmitterResponse(String response) {
|
||||
Log.d(TAG, "emitter: " + response);
|
||||
if (response.startsWith(E_RESPONSE_HELLO)) {
|
||||
if (response.startsWith(IRSocketEmitter.E_RESPONSE_HELLO)) {
|
||||
processEHello(response);
|
||||
} else if (response.startsWith(E_RESPONSE_BIN)) {
|
||||
} else if (response.startsWith(IRSocketEmitter.E_RESPONSE_BIN)) {
|
||||
processEBin(response);
|
||||
} else if (response.startsWith(E_RESPONSE_CTRL)) {
|
||||
} else if (response.startsWith(IRSocketEmitter.E_RESPONSE_CTRL)) {
|
||||
processECtrl(response);
|
||||
} else {
|
||||
Log.e(TAG, "unexpected response : " + response);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendHelloToEmitter() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Log.d(TAG, "sending a_hello to emitter");
|
||||
PrintWriter out = new PrintWriter(emitterConn.getOutputStream(), true);
|
||||
out.println(A_REQUEST_HELLO);
|
||||
} catch (IOException e) {
|
||||
e.getMessage();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void sendDecodedToEmitter(String value) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
PrintWriter out = new PrintWriter(emitterConn.getOutputStream(), true);
|
||||
out.println(value);
|
||||
} catch (IOException e) {
|
||||
e.getMessage();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void sendBinToEmitter(byte[] binContent) {
|
||||
if (null == binContent) {
|
||||
Log.e(TAG, "binary bytes is null");
|
||||
return;
|
||||
}
|
||||
int categoryId = mCurrentRemoteControl.getCategoryId();
|
||||
int subCate = mCurrentRemoteControl.getSubCategory();
|
||||
String binBase64 = Base64.getEncoder().encodeToString(binContent);
|
||||
String binStr = A_REQUEST_BIN + "," + categoryId + "," + subCate + "," + binBase64.length() + "," + binBase64;
|
||||
Log.d(TAG, "sending bin in base64: " + binStr);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
PrintWriter out = new PrintWriter(emitterConn.getOutputStream(), true);
|
||||
out.println(binStr);
|
||||
} catch (IOException e) {
|
||||
e.getMessage();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void connectToEmitter(String ipAddress, String port) {
|
||||
if (EMITTER_DISCONNECTED == emitterConnected) {
|
||||
if (null == ipAddress || null == port) {
|
||||
return;
|
||||
}
|
||||
new Thread(() -> {
|
||||
try {
|
||||
emitterConn = new Socket(ipAddress, Integer.parseInt(port));
|
||||
emitterConn.setKeepAlive(true);
|
||||
onEmitterConnected();
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(emitterConn.getInputStream()));
|
||||
String response = "";
|
||||
while ((response = in.readLine()) != null) {
|
||||
onEmitterResponse(response);
|
||||
}
|
||||
onEmitterDisconnected();
|
||||
} catch (IOException ioException) {
|
||||
onEmitterDisconnected();
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
try {
|
||||
emitterConnected = EMITTER_DISCONNECTED;
|
||||
emitterConn.close();
|
||||
} catch(IOException e) {
|
||||
e.getMessage();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// control
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@@ -420,9 +334,9 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
decodedValue.append(",");
|
||||
}
|
||||
Log.d(TAG, "decodedValue : " + decodedValue);
|
||||
if (EMITTER_AVAILABLE == emitterConnected) {
|
||||
if (mIRSocketEmitter.isConnected()) {
|
||||
Log.d(TAG, "emitter available, send decoded to emitter");
|
||||
sendDecodedToEmitter(decodedValue.toString());
|
||||
mIRSocketEmitter.sendDecodedToEmitter(decodedValue.toString());
|
||||
}
|
||||
// send decoded integer array to IR emitter
|
||||
ConsumerIrManager irEmitter =
|
||||
@@ -436,6 +350,15 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isIpAddress(String ipAddress) {
|
||||
try {
|
||||
InetAddress inetAddress = InetAddress.getByName(ipAddress);
|
||||
return Objects.equals(inetAddress.getHostAddress(), ipAddress);
|
||||
} catch (UnknownHostException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MsgHandler extends Handler {
|
||||
|
||||
WeakReference<ControlFragment> mMainFragment;
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
package net.irext.ircontrol.utils;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Socket;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* Filename: IRSocketEmitter.java
|
||||
* Description: Handle socket communication with external IR emitter
|
||||
*/
|
||||
public class IRSocketEmitter {
|
||||
private static final String TAG = IRSocketEmitter.class.getSimpleName();
|
||||
|
||||
public static final int EMITTER_DISCONNECTED = 0;
|
||||
public static final int EMITTER_CONNECTED = 1;
|
||||
public static final int EMITTER_AVAILABLE = 2;
|
||||
public static final int EMITTER_BIN_RECEIVED = 3;
|
||||
|
||||
public static final int EMITTER_PORT = 8000;
|
||||
|
||||
public static final String A_REQUEST_HELLO = "a_hello";
|
||||
public static final String E_RESPONSE_HELLO = "e_hello";
|
||||
|
||||
public static final String A_REQUEST_BIN = "a_bin";
|
||||
public static final String E_RESPONSE_BIN = "e_bin";
|
||||
|
||||
public static final String A_REQUEST_CTRL = "a_control";
|
||||
public static final String E_RESPONSE_CTRL = "e_control";
|
||||
|
||||
private Socket emitterConn = null;
|
||||
private int connectionStatus = EMITTER_DISCONNECTED;
|
||||
private IRSocketEmitterCallback callback;
|
||||
|
||||
public interface IRSocketEmitterCallback {
|
||||
void onConnected();
|
||||
void onDisconnected();
|
||||
void onResponse(String response);
|
||||
}
|
||||
|
||||
public IRSocketEmitter(IRSocketEmitterCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public void setCallback(IRSocketEmitterCallback callback) {
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
public int getConnectionStatus() {
|
||||
return connectionStatus;
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return connectionStatus == EMITTER_AVAILABLE;
|
||||
}
|
||||
|
||||
public void connectToEmitter(String ipAddress, String port) {
|
||||
if (connectionStatus == EMITTER_DISCONNECTED) {
|
||||
if (ipAddress == null || port == null) {
|
||||
return;
|
||||
}
|
||||
new Thread(() -> {
|
||||
try {
|
||||
emitterConn = new Socket(ipAddress, Integer.parseInt(port));
|
||||
emitterConn.setKeepAlive(true);
|
||||
connectionStatus = EMITTER_CONNECTED;
|
||||
|
||||
if (callback != null) {
|
||||
callback.onConnected();
|
||||
}
|
||||
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(emitterConn.getInputStream()));
|
||||
String response;
|
||||
while ((response = in.readLine()) != null) {
|
||||
if (callback != null) {
|
||||
callback.onResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
if (callback != null) {
|
||||
callback.onDisconnected();
|
||||
}
|
||||
|
||||
connectionStatus = EMITTER_DISCONNECTED;
|
||||
} catch (IOException ioException) {
|
||||
Log.e(TAG, "Connection error: " + ioException.getMessage());
|
||||
|
||||
if (callback != null) {
|
||||
callback.onDisconnected();
|
||||
}
|
||||
|
||||
connectionStatus = EMITTER_DISCONNECTED;
|
||||
}
|
||||
}).start();
|
||||
} else {
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
try {
|
||||
if (emitterConn != null && !emitterConn.isClosed()) {
|
||||
emitterConn.close();
|
||||
}
|
||||
connectionStatus = EMITTER_DISCONNECTED;
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error closing connection: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void sendHelloToEmitter() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Log.d(TAG, "sending a_hello to emitter");
|
||||
PrintWriter out = new PrintWriter(emitterConn.getOutputStream(), true);
|
||||
out.println(A_REQUEST_HELLO);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error sending hello: " + e.getMessage());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void sendDecodedToEmitter(String value) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
PrintWriter out = new PrintWriter(emitterConn.getOutputStream(), true);
|
||||
out.println(value);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error sending decoded data: " + e.getMessage());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void sendBinToEmitter(byte[] binContent, int categoryId, int subCate) {
|
||||
if (binContent == null) {
|
||||
Log.e(TAG, "binary bytes is null");
|
||||
return;
|
||||
}
|
||||
String binBase64 = Base64.getEncoder().encodeToString(binContent);
|
||||
String binStr = A_REQUEST_BIN + "," + categoryId + "," + subCate + "," + binBase64.length() + "," + binBase64;
|
||||
Log.d(TAG, "sending bin in base64: " + binStr);
|
||||
new Thread(() -> {
|
||||
try {
|
||||
PrintWriter out = new PrintWriter(emitterConn.getOutputStream(), true);
|
||||
out.println(binStr);
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "Error sending binary data: " + e.getMessage());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
public void processEHello(String response) {
|
||||
sendHelloToEmitter();
|
||||
}
|
||||
|
||||
public void processEBin(String response, byte[] binContent, int categoryId, int subCate) {
|
||||
sendBinToEmitter(binContent, categoryId, subCate);
|
||||
}
|
||||
|
||||
public void processECtrl(String response) {
|
||||
// Handle control response if needed
|
||||
}
|
||||
}
|
||||
@@ -33,7 +33,7 @@
|
||||
<string name="ir_not_supported">该设备不支持红外发射, 请连接外部模块进行发射</string>
|
||||
|
||||
<string name="emitter_ip">发射端 IP</string>
|
||||
<string name="default_ip">192.168.2.85</string>
|
||||
<string name="default_ip">192.168.1.40</string>
|
||||
<string name="connect">连接</string>
|
||||
<string name="decode_on_board">在单片机上解码</string>
|
||||
<string name="input_emitter_ip_address">请输入接收器的 IP 地址</string>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<string name="ir_not_supported">IR emitter is not supported in this device, please try with external emitters</string>
|
||||
|
||||
<string name="emitter_ip">Emitter IP</string>
|
||||
<string name="default_ip">192.168.2.85</string>
|
||||
<string name="default_ip">192.168.1.40</string>
|
||||
<string name="connect">connect</string>
|
||||
<string name="decode_on_board">Decode On Board</string>
|
||||
<string name="input_emitter_ip_address">Please input IP address of emitter</string>
|
||||
|
||||
Reference in New Issue
Block a user