made progress of android-example

This commit is contained in:
strawmanbobi
2026-01-25 15:38:28 +08:00
parent 94b7851f6f
commit 12fa4d886b
11 changed files with 127 additions and 44 deletions

View File

@@ -45,6 +45,7 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.core:core:1.13.1'
implementation 'com.google.android.material:material:1.13.0'
implementation 'com.google.code.gson:gson:2.13.2'
implementation 'com.android.support:multidex:1.0.3'

View File

@@ -0,0 +1,51 @@
package net.irext.ircontrol.controller;
import com.google.gson.Gson;
import net.irext.decode.sdk.bean.ACStatus;
import net.irext.ircontrol.controller.base.ControlCommand;
import org.jspecify.annotations.NonNull;
import java.util.Base64;
/**
* Filename: ControlCommand.java
* Revised: Date: 2026-01-22
* Revision: Revision: 1.0
* <p>
* Description: Remote command to Arduino remote
* <p>
* Revision log:
* 2026-01-22: created by strawmanbobi
*/
public class ArduinoControlCommand extends ControlCommand {
public ArduinoControlCommand(int keyCode, ACStatus acStatus) {
this.keyCode = keyCode;
this.acStatus = acStatus;
}
public ArduinoControlCommand() {
}
public int getKeyCode() {
return keyCode;
}
public void setKeyCode(int keyCode) {
this.keyCode = keyCode;
}
public ACStatus getAcStatus() {
return acStatus;
}
public void setAcStatus(ACStatus acStatus) {
this.acStatus = acStatus;
}
@Override
public @NonNull String toString() {
String jsonStr = new Gson().toJson(this);
return Base64.getEncoder().encodeToString(jsonStr.getBytes());
}
}

View File

@@ -2,7 +2,10 @@ package net.irext.ircontrol.controller;
import android.content.Context;
import android.util.Log;
import net.irext.ircontrol.controller.implementable.IRemote;
import net.irext.decode.sdk.bean.ACStatus;
import net.irext.ircontrol.controller.base.IRemote;
import static net.irext.ircontrol.controller.ArduinoSocket.*;
/**
* Filename: ArduinoRemote.java
@@ -16,7 +19,7 @@ import net.irext.ircontrol.controller.implementable.IRemote;
*/
public class ArduinoRemote implements IRemote {
private static final String TAG = PhoneRemote.class.getSimpleName();
private static final String TAG = ArduinoRemote.class.getSimpleName();
Context mContext;
ArduinoSocket mArduinoSocket;
@@ -28,7 +31,17 @@ public class ArduinoRemote implements IRemote {
@Override
public int irControl(int category, int subCategory, int keyCode) {
Log.d(TAG, "irControl, category = " + category + ", subCategory = " + subCategory + ", keyCode = " + keyCode);
ACStatus acStatus = new ACStatus();
int inputKeyCode = ControlHelper.translateKeyCode(category, keyCode, acStatus);
ArduinoControlCommand command = new ArduinoControlCommand(inputKeyCode, acStatus);
String controlCommand = command.toString();
mArduinoSocket.sendControlToEmitter(controlCommand);
return 0;
}
}

View File

@@ -25,8 +25,7 @@ public class ArduinoSocket {
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_WORKING = 2;
public static final int EMITTER_PORT = 8000;
@@ -61,10 +60,6 @@ public class ArduinoSocket {
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) {
@@ -81,9 +76,7 @@ public class ArduinoSocket {
BufferedReader in = new BufferedReader(new InputStreamReader(emitterConn.getInputStream()));
String response;
while ((response = in.readLine()) != null) {
if (callback != null) {
callback.onResponse(response);
}
onResponse(response);
}
if (callback != null) {
@@ -129,22 +122,12 @@ public class ArduinoSocket {
}).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);
@@ -152,23 +135,36 @@ public class ArduinoSocket {
try {
PrintWriter out = new PrintWriter(emitterConn.getOutputStream(), true);
out.println(binStr);
} catch (IOException e) {
} catch (Exception e) {
Log.e(TAG, "Error sending binary data: " + e.getMessage());
}
}).start();
}
public void processEHello(String response) {
sendHelloToEmitter();
public void sendControlToEmitter(String command) {
String commandStr = A_REQUEST_CTRL + "," + command.length() + "," + command;
Log.d(TAG, "sending command in base64: " + commandStr);
new Thread(() -> {
try {
PrintWriter out = new PrintWriter(emitterConn.getOutputStream(), true);
out.println(commandStr);
} catch (IOException e) {
Log.e(TAG, "Error sending control data: " + e.getMessage());
}
});
}
public void processEBin(String response, byte[] binContent, int categoryId, int subCate) {
sendBinToEmitter(binContent, categoryId, subCate);
public void sendDecodedToEmitter(String binContent) {
new Thread(() -> {
try {
PrintWriter out = new PrintWriter(emitterConn.getOutputStream(), true);
out.println(binContent);
} catch (IOException e) {
Log.e(TAG, "Error sending decoded data: " + e.getMessage());
}
}).start();
}
public void processECtrl(String response) {
// Handle control response if needed
}
private void onConnected() {
if (callback != null) {
@@ -178,15 +174,15 @@ public class ArduinoSocket {
}
private void onResponse(String response) {
Log.d(TAG, "emitter: " + response);
if (response.startsWith(ArduinoSocket.E_RESPONSE_HELLO)) {
processEHello(response);
;
} else if (response.startsWith(ArduinoSocket.E_RESPONSE_BIN)) {
;
} else if (response.startsWith(ArduinoSocket.E_RESPONSE_CTRL)) {
processECtrl(response);
connectionStatus = EMITTER_WORKING;
} else {
Log.e(TAG, "unexpected response : " + response);
}
callback.onResponse(response);
}
}

View File

@@ -9,7 +9,7 @@ import net.irext.ircontrol.utils.ToastUtils;
import java.util.Objects;
import static net.irext.ircontrol.controller.implementable.IRemote.*;
import static net.irext.ircontrol.controller.base.IRemote.*;
/**
* Filename: ControlHelper.java

View File

@@ -4,7 +4,7 @@ import android.content.Context;
import android.util.Log;
import net.irext.decode.sdk.IRDecode;
import net.irext.decode.sdk.bean.ACStatus;
import net.irext.ircontrol.controller.implementable.IRemote;
import net.irext.ircontrol.controller.base.IRemote;
/**
* Filename: PhoneRemote.java

View File

@@ -0,0 +1,22 @@
package net.irext.ircontrol.controller.base;
import net.irext.decode.sdk.bean.ACStatus;
/**
* Filename: ControlCommand.java
* Revised: Date: 2026-01-22
* Revision: Revision: 1.0
* <p>
* Description: ControlCommand base class
* <p>
* Revision log:
* 2026-01-22: created by strawmanbobi
*/
public abstract class ControlCommand {
protected int keyCode;
protected ACStatus acStatus;
public abstract String toString();
}

View File

@@ -1,4 +1,4 @@
package net.irext.ircontrol.controller.implementable;
package net.irext.ircontrol.controller.base;
/**
* Filename: IRemote.java

View File

@@ -17,10 +17,11 @@ import net.irext.ircontrol.bean.RemoteControl;
import net.irext.ircontrol.controller.ArduinoRemote;
import net.irext.ircontrol.controller.ArduinoSocket;
import net.irext.ircontrol.controller.PhoneRemote;
import net.irext.ircontrol.controller.implementable.IRemote;
import net.irext.ircontrol.controller.base.IRemote;
import net.irext.ircontrol.ui.activity.ControlActivity;
import net.irext.ircontrol.utils.FileUtils;
import net.irext.ircontrol.utils.MessageUtils;
import net.irext.ircontrol.utils.MiscUtils;
import net.irext.ircontrol.utils.ToastUtils;
import java.lang.ref.WeakReference;
@@ -123,7 +124,7 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
public void onClick(View v) {
vibrate(mParent);
String emitterIp = mEtEmitterIp.getText().toString();
if (!ArduinoSocket.isValidIPv4(emitterIp)) {
if (!MiscUtils.isValidIPv4(emitterIp)) {
Log.e(TAG, "IP address is invalid: " + emitterIp);
ToastUtils.showToast(mParent, mParent.getString(R.string.input_emitter_ip_address), null);
return;
@@ -217,11 +218,10 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
}
private void processECtrl(String response) {
;
}
private void onEmitterResponse(String response) {
Log.d(TAG, "emitter: " + response);
if (response.startsWith(ArduinoSocket.E_RESPONSE_HELLO)) {
processEHello(response);
} else if (response.startsWith(ArduinoSocket.E_RESPONSE_BIN)) {
@@ -264,7 +264,7 @@ public class ControlFragment extends Fragment implements View.OnClickListener {
keyCode = IRemote.KEY_MENU;
}
if (mArduinoSocket.isConnected() && mArduinoSocket.getConnectionStatus() == ArduinoSocket.EMITTER_BIN_RECEIVED) {
if (mArduinoSocket.getConnectionStatus() == ArduinoSocket.EMITTER_WORKING) {
remote = new ArduinoRemote(mParent, mArduinoSocket);
} else {
remote = new PhoneRemote(mParent);

View File

@@ -33,7 +33,7 @@
<!-- Emitter panel -->
<string name="emitter_ip">发射端 IP</string>
<string name="default_ip">192.168.1.40</string>
<string name="default_ip">192.168.1.43</string>
<string name="connect">连接</string>
<string name="decode_on_board">在单片机上解码</string>

View File

@@ -33,7 +33,7 @@
<!-- Emitter panel -->
<string name="emitter_ip">Emitter IP</string>
<string name="default_ip">192.168.1.40</string>
<string name="default_ip">192.168.1.43</string>
<string name="connect">Connect</string>
<string name="decode_on_board">Decode On Board</string>