Avoid JDK APIs newer than Android's minSdk 33 in core

Files.readString/writeString (API 36.1), Path.of, ByteBuffer.slice(int, int)
and Matcher.appendReplacement(StringBuilder) (API 34) threw NoSuchMethodError
on Android; connecting crashed in ChatLogStore. Each replacement keeps the
original desktop code in a comment above it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 14:05:39 +00:00
parent 5d67b0c1e3
commit c5a49fc7b3
6 changed files with 23 additions and 7 deletions

View File

@@ -174,7 +174,10 @@ public final class ChatLogStore {
Files.createDirectories(files.txt.getParent());
Files.createDirectories(files.html.getParent());
if (!Files.exists(files.html)) {
Files.writeString(files.html, HTML_HEADER + System.lineSeparator(), StandardCharsets.UTF_8,
// Android < API 36.1 lacks Files.writeString; original:
// Files.writeString(files.html, HTML_HEADER + System.lineSeparator(), StandardCharsets.UTF_8,
// StandardOpenOption.CREATE, StandardOpenOption.APPEND);
Files.write(files.html, (HTML_HEADER + System.lineSeparator()).getBytes(StandardCharsets.UTF_8),
StandardOpenOption.CREATE, StandardOpenOption.APPEND);
}
if (!Files.exists(files.txt)) Files.createFile(files.txt);

View File

@@ -2,6 +2,7 @@ package com.ts3client.config;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* Where the client keeps its own state. On the desktop that is {@code ~/.ts3jclient}, with chat
@@ -50,7 +51,9 @@ public final class AppDirs {
public static Path chatLogs() {
Path dir = chatLogs;
if (dir == null) {
dir = Path.of(System.getProperty("user.home", "."), ".ts3client", "chats");
// Android < API 34 lacks Path.of; original:
// dir = Path.of(System.getProperty("user.home", "."), ".ts3client", "chats");
dir = Paths.get(System.getProperty("user.home", "."), ".ts3client", "chats");
chatLogs = dir;
}
return dir;

View File

@@ -70,7 +70,9 @@ public final class ContactStore {
void readFile() {
String text;
try {
text = Files.readString(file.toPath(), StandardCharsets.UTF_8);
// Android < API 36.1 lacks Files.readString; original:
// text = Files.readString(file.toPath(), StandardCharsets.UTF_8);
text = new String(Files.readAllBytes(file.toPath()), StandardCharsets.UTF_8);
} catch (IOException e) {
return;
}

View File

@@ -34,7 +34,7 @@ import com.ts3client.text.TsLink;
import java.io.File;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -1399,7 +1399,9 @@ public final class TeamspeakConnection implements TS3Listener {
return;
}
String dir = settings.chatLogDir == null ? "" : settings.chatLogDir.trim();
ChatLogStore logs = new ChatLogStore(dir.isEmpty() ? ChatLogStore.defaultRoot() : Path.of(dir), uniqueId);
// Android < API 34 lacks Path.of; original:
// ChatLogStore logs = new ChatLogStore(dir.isEmpty() ? ChatLogStore.defaultRoot() : Path.of(dir), uniqueId);
ChatLogStore logs = new ChatLogStore(dir.isEmpty() ? ChatLogStore.defaultRoot() : Paths.get(dir), uniqueId);
chatLogs = logs;
logs.begin();
List<String> serverHistory = logs.serverHtmlHistory();

View File

@@ -35,7 +35,11 @@ final class WaveFile {
int id = in.getInt();
int size = in.getInt();
if (size < 0 || size > in.remaining()) size = in.remaining(); // truncated files still play
ByteBuffer chunk = in.slice(in.position(), size).order(ByteOrder.LITTLE_ENDIAN);
// Android < API 34 lacks ByteBuffer.slice(int, int); original:
// ByteBuffer chunk = in.slice(in.position(), size).order(ByteOrder.LITTLE_ENDIAN);
ByteBuffer chunk = in.duplicate();
chunk.limit(chunk.position() + size);
chunk = chunk.slice().order(ByteOrder.LITTLE_ENDIAN);
if (id == fourCc("fmt ") && size >= 16) {
format = chunk.getShort() & 0xFFFF;
channels = chunk.getShort() & 0xFFFF;

View File

@@ -21,7 +21,9 @@ public final class HtmlText {
private static String unescape(String s) {
Matcher m = ENTITY.matcher(s);
StringBuilder out = new StringBuilder(s.length());
// Android < API 34 lacks Matcher.appendReplacement/appendTail(StringBuilder); original:
// StringBuilder out = new StringBuilder(s.length());
StringBuffer out = new StringBuffer(s.length());
while (m.find()) {
String decoded = decode(m.group(1));
m.appendReplacement(out, Matcher.quoteReplacement(decoded == null ? m.group() : decoded));