U盘别名节目

This commit is contained in:
zhy 2026-01-13 21:14:53 +08:00
commit 4211abe679
20 changed files with 485 additions and 194 deletions

View File

@ -11,7 +11,7 @@ android {
minSdk 21 minSdk 21
targetSdk 34 targetSdk 34
versionCode 1 versionCode 1
versionName "2.2.1-N" versionName "2.2.19-config-lora"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
@ -45,17 +45,17 @@ android {
storePassword '123456' storePassword '123456'
} }
D { //A11 D { //A11 --+android.uid.system =
keyAlias 'xixun' keyAlias 'xixun'
keyPassword '123456' keyPassword '123456'
storeFile file('D:/zp/Android/GitConn/xixun-d.keystore') storeFile file('D:/zp/Android/GitConn/xixun-d.keystore')
storePassword '123456' storePassword '123456'
} }
D_3566 { //A11 - D_3576 { //A11 - 3576 3566
keyAlias 'platform' keyAlias 'platform'
keyPassword 'youngfeel' keyPassword 'youngfeel'
storeFile file('D:/XixunSoftware/ZP/conn/yf356x_android11_system.jks') storeFile file('D:/zp/Android/GitConn/yf356x_android11_system.jks')
storePassword 'youngfeel' storePassword 'youngfeel'
} }
@ -96,10 +96,10 @@ android {
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.D_3568 signingConfig signingConfigs.D
} }
debug { debug {
signingConfig signingConfigs.D_3568 signingConfig signingConfigs.D
} }
} }
@ -143,8 +143,3 @@ android.applicationVariants.configureEach { variant ->
outputFileName = fileName outputFileName = fileName
} }
} }
//
//D:\zp\Android\XixunPlayer_zp\XixunPlayer\app\build.gradle
//D:\zp\Android\XixunPlayer_zp\XixunPlayer\gradle\wrapper\gradle-wrapper.properties
//使java17

View File

@ -11,99 +11,10 @@ android {
minSdk 21 minSdk 21
targetSdk 34 targetSdk 34
versionCode 1 versionCode 1
versionName "2.2.1-N" versionName "2.2.19-Y-lora"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
// buildTypes {
// release {
// minifyEnabled false
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// }
// }
signingConfigs {
config { //
keyAlias 'xy'
keyPassword '111111'
storeFile file('D:/zp/Android/GitConn/xy_keystore')
//storeFile file('/home/yzd/work/sign/xy_keystore')
storePassword '111111'
}
M {// //A7
keyAlias 'xixun'
keyPassword '123456'
storeFile file('D:/XixunSoftware/ZP/conn/xixun-m.keystore')
storePassword '123456'
}
Y5a { //A9
keyAlias 'xixun'
keyPassword '123456'
storeFile file('D:/zp/Android/GitConn/xixun-c.keystore')
storePassword '123456'
}
D { //A11
keyAlias 'xixun'
keyPassword '123456'
storeFile file('D:/zp/Android/GitConn/xixun-d.keystore')
storePassword '123456'
}
D_3566 { //A11 -
keyAlias 'platform'
keyPassword 'youngfeel'
storeFile file('D:/XixunSoftware/ZP/conn/yf356x_android11_system.jks')
storePassword 'youngfeel'
}
Y33 { //
keyAlias 'xixun'
keyPassword '123456'
storeFile file('D:/XixunSoftware/ZP/conn/xixun-x.keystore')
storePassword '123456'
}
D_3568 {//3568 //3568
keyAlias 'systemkey'
keyPassword '123456'
storeFile file('D:/zp/Android/GitConn/platform.jks')
storePassword '123456'
}
D_gt {//3568 //
keyAlias 'androiddebugkey'
keyPassword 'android'
storeFile file('D:/zp/Android/GitConn/platform.keystore')
storePassword 'android'
}
a133 {// a133
keyAlias 'platform'
keyPassword 'youngfeel'
storeFile file('D:/zp/Android/GitConn/android11_system.jks')
storePassword 'youngfeel'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.D_3568
}
debug {
signingConfig signingConfigs.D_3568
}
}
buildFeatures { buildFeatures {
aidl true aidl true
} }
@ -112,6 +23,52 @@ android {
sourceCompatibility JavaVersion.VERSION_11 sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11 targetCompatibility JavaVersion.VERSION_11
} }
signingConfigs {
X {//4418
keyAlias 'xixun'
keyPassword '123456'
storeFile file('D:/develop/xixun/signedFile/keystore/xixun-x.keystore')
storePassword '123456'
}
Y {//210
keyAlias 'xixun'
keyPassword '123456'
storeFile file('D:/develop/xixun/signedFile/keystore/xixun-y.keystore')
storePassword '123456'
}
D_3568a {//3568a
keyAlias 'keystore'
keyPassword 'android'
storeFile file('D:/develop/xixun/signedFile/keystore/keystore.jks')
storePassword 'android'
}
D_3568N {//3568
keyAlias 'systemkey'
keyPassword '123456'
storeFile file('D:/_docs/comp/android/keystore/3568D恩泰世 123456.jks')
storePassword '123456'
}
D_YF {//3566 YF
keyAlias 'platform'
keyPassword 'youngfeel'
storeFile file('D:/_docs/comp/android/keystore/yf356x_android11_system.jks')
storePassword 'youngfeel'
}
}
buildTypes {
release {
lintOptions {
checkReleaseBuilds false
abortOnError false
}
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.D_3568N
}
debug {
signingConfig signingConfigs.D_3568N
}
}
} }
dependencies { dependencies {
@ -143,8 +100,3 @@ android.applicationVariants.configureEach { variant ->
outputFileName = fileName outputFileName = fileName
} }
} }
//
//D:\zp\Android\XixunPlayer_zp\XixunPlayer\app\build.gradle
//D:\zp\Android\XixunPlayer_zp\XixunPlayer\gradle\wrapper\gradle-wrapper.properties
//使java17

View File

@ -5,6 +5,7 @@
<!-- android:sharedUserId="android.uid.system"--> <!-- android:sharedUserId="android.uid.system"-->
<!-- android:sharedUserMaxSdkVersion="32">--> <!-- android:sharedUserMaxSdkVersion="32">-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission <uses-permission

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@ -106,7 +106,8 @@
<img src="images/web3.png" class="imgSize1" style="object-fit: contain;"> <img src="images/web3.png" class="imgSize1" style="object-fit: contain;">
</div> </div>
</div> </div>
<div style="width: 100%;min-height: 25%;"> <div style="display: flex;align-items: flex-start;justify-content: space-between;width: 100%;min-height: 25%;">
<div>
<div class="fontBold Hcenter"> <div class="fontBold Hcenter">
<span class="step-icon">📌</span> <span class="step-icon">📌</span>
<span class="i18n-text" data-i18n="notes">注意事项</span> <span class="i18n-text" data-i18n="notes">注意事项</span>
@ -115,6 +116,12 @@
设备需切换至联网模式并关联云平台账号云服务器地址https://www.ledokcloud.com 设备需切换至联网模式并关联云平台账号云服务器地址https://www.ledokcloud.com
</div> </div>
</div> </div>
<div style="width: 1rem;"></div>
<div>
<img id="videoCommentaryQrcode" src="images/code_cn.png" class="imgSize3" style="object-fit: contain;">
<div class="qrcode-text i18n-text" data-i18n="videoCommentary">视频详解</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -166,7 +173,7 @@
<div> <div>
<img src="images/code.png" class="imgSize3" <img src="images/code.png" class="imgSize3"
style="object-fit: contain;"> style="object-fit: contain;">
<!-- <div class="qrcode-text i18n-text" data-i18n="scanDownload">扫码下载APP</div> --> <div class="qrcode-text i18n-text" data-i18n="scanDownload">扫码下载APP</div>
</div> </div>
</div> </div>
</div> </div>
@ -244,14 +251,15 @@
appStep2: "2.创建并编辑节目", appStep2: "2.创建并编辑节目",
appStep3: "3.发送节目到设备", appStep3: "3.发送节目到设备",
appNote: "设备需切换至热点模式,手机需连接该设备热点", appNote: "设备需切换至热点模式,手机需连接该设备热点",
scanDownload: "扫码下载APP", scanDownload: "下载APP",
usbStep1: "1.节目文件存入U盘", usbStep1: "1.节目文件存入U盘",
usbStep2: "2.U盘接入设备", usbStep2: "2.U盘接入设备",
usbStep3: "3.系统自动播放", usbStep3: "3.系统自动播放",
usbNote: "无设备模式限制U盘即插即播", usbNote: "无设备模式限制U盘即插即播",
loading: "正在接收Android宽高...", loading: "正在接收Android宽高...",
loadFail: "接收宽高失败", loadFail: "接收宽高失败",
unknownNetwork: "未知网络" unknownNetwork: "未知网络",
videoCommentary: "视频详解"
}, },
// 英文 // 英文
en: { en: {
@ -272,14 +280,15 @@
appStep2: "2.Create and edit programs", appStep2: "2.Create and edit programs",
appStep3: "3.Send programs to device", appStep3: "3.Send programs to device",
appNote: "The device must be switched to hotspot mode, and the mobile phone must connect to the device's hotspot", appNote: "The device must be switched to hotspot mode, and the mobile phone must connect to the device's hotspot",
scanDownload: "Scan to download APP", scanDownload: "Download APP",
usbStep1: "1.Save program files to USB", usbStep1: "1.Save program files to USB",
usbStep2: "2.Connect USB to device", usbStep2: "2.Connect USB to device",
usbStep3: "3.System plays automatically", usbStep3: "3.System plays automatically",
usbNote: "No device mode restrictions, plug and play with USB", usbNote: "No device mode restrictions, plug and play with USB",
loading: "Receiving Android width and height...", loading: "Receiving Android width and height...",
loadFail: "Failed to receive width and height", loadFail: "Failed to receive width and height",
unknownNetwork: "Unknown Network" unknownNetwork: "Unknown Network",
videoCommentary: "Video commentary"
} }
}; };
@ -375,7 +384,8 @@
const cardId = document.getElementById("cardId"); const cardId = document.getElementById("cardId");
const cardVideos = document.querySelectorAll(".card-bg-video"); // 所有卡片视频 const cardVideos = document.querySelectorAll(".card-bg-video"); // 所有卡片视频
const infoBarVideo = document.querySelector(".info-bar-bg-video"); // 顶部信息栏视频 const infoBarVideo = document.querySelector(".info-bar-bg-video"); // 顶部信息栏视频
const qrcodeImg = document.getElementById("videoCommentaryQrcode");
qrcodeImg.src = currentLang === "zh" ? "images/code_cn.png" : "images/code_en.png";
try { try {
// ---------------------- 1. 获取并更新宽高 ---------------------- // ---------------------- 1. 获取并更新宽高 ----------------------
const sizeJson = AndroidBridge.getSizeFromAndroid(); const sizeJson = AndroidBridge.getSizeFromAndroid();

View File

@ -110,7 +110,7 @@ public class AIDLService extends Service {
@SuppressLint("ResourceType") @SuppressLint("ResourceType")
@Override @Override
public String executeJosnCommand(String jsonstr) throws RemoteException { public String executeJosnCommand(String jsonstr) throws RemoteException {
Util.println("AIDL executeJsonCommand ..."+jsonstr);//{"_type":"DeleteTask","id":"652522a0e81d1e000009201a","sendTo":"yzd-player"} Util.println("AIDL executeJson "+jsonstr);//{"_type":"DeleteTask","id":"652522a0e81d1e000009201a","sendTo":"yzd-player"}
String commandId = null; String commandId = null;
try { try {
var jsonBytes = jsonstr.getBytes(StandardCharsets.UTF_8); var jsonBytes = jsonstr.getBytes(StandardCharsets.UTF_8);

View File

@ -0,0 +1,175 @@
package com.xixun.xixunplayer;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.IBinder;
import android.util.Log;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class AidlUtil {
// static final String ACTION_CONN ="xixun.intent.action.CONNECTION_INFO";
static final String ACTION_PLAYER ="com.xixun.action.PlayerInfo";
static final String ACTION_CARD_SYSTEM ="com.xixun.joey.aidlset.SettingsService";
static final String ACTION_LIVE ="xixun.intent.action.Live";
static final String ACTION_UPDATE ="xixun.intent.action.UPDATE_APK";
static final String ACTION_JIESHUN ="com.xixun.xy.conn.JieShun";
static final String ACTION_TaxiAppServer ="com.xixun.xy.conn.aidl.TaxiAppServer";
static final String ACTION_CustomServer ="com.xixun.xy.conn.aidl.CustomService";
static final String ACTION_ConnServer ="com.xixun.xy.conn.aidl.ConnService";
static final String ACTION_AiServer ="com.sysolution.ai.AiAvatarService";
public static final String PACKAGE_PLAYER="com.xixun.xixunplayer";
public static final String PACKAGE_CARD_SYSTEM="com.xixun.joey.cardsystem";
public static final String PACKAGE_LIVE="com.xixun.xy.live";
public static final String PACKAGE_UPDATE="com.xixun.xy.update";
public static final String PACKAGE_TAXIAPP = "net.sysolution.taxiapp";
public static final String PACKAGE_CUSTOMAPP = "com.xixun.xixunledplayer";
public static final String PACKAGE_BASICAPP = "net.sysolution.basicapp";
public static final String PACKAGE_STARTER = "net.sysolution.starter";
public static final String PACKAGE_DISPLAY = "com.xixun.display";
public static final String PACKAGE_ORDER_VIDEO = "add.xixun.com.ordervideo";
public static final String PACKAGE_JIESHUN = "com.xixun.stopguide";
public static final String PACKAGE_TAXIAPP88 = "cn.trans88.taxiappkotlin";
public static final String PACKAGE_AI = "com.sysolution.ai";
public static final String PACKAGE_CONN = "com.xixun.xy.conn";
public static Intent newConnIntent(){
Intent intent = new Intent(ACTION_ConnServer);
intent.setPackage(PACKAGE_CONN);
return intent;
}
public static Intent newAiIntent(){
Intent intent = new Intent(ACTION_AiServer);
intent.setPackage(PACKAGE_AI);
return intent;
}
public static Intent newCustomIntent(){
Intent intent = new Intent(ACTION_CustomServer);
intent.setPackage(PACKAGE_CUSTOMAPP);
return intent;
}
public static Intent newTaxiAppIntent(){
Intent intent = new Intent(ACTION_TaxiAppServer);
intent.setPackage(PACKAGE_TAXIAPP);
return intent;
}
public static Intent newPlayerIntent(){
Intent intent = new Intent(ACTION_PLAYER);
intent.setPackage(PACKAGE_PLAYER);
return intent;
}
public static Intent newCardSystemIntent(){
Intent intent = new Intent(ACTION_CARD_SYSTEM);
intent.setPackage(PACKAGE_CARD_SYSTEM);
return intent;
}
public static Intent newLiveIntent(){
Intent intent = new Intent(ACTION_LIVE);
intent.setPackage(PACKAGE_LIVE);
return intent;
}
public static Intent newUpdateIntent(){
Intent intent = new Intent(ACTION_UPDATE);
intent.setPackage(PACKAGE_UPDATE);
return intent;
}
public static Intent newJieShunIntent(){
Intent intent = new Intent(ACTION_JIESHUN);
intent.setPackage(PACKAGE_JIESHUN);
return intent;
}
CountDownLatch latch = new CountDownLatch(1);
IBinder binder = null;
private Intent intent;
private Context ctx;
private int timeout;
private IBinder[] container = new IBinder[1];
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder =service;
ctx.unbindService(this);
latch.countDown();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("yzd", "aidl disconnected");
}
};
public AidlUtil(Context context, Intent intent, int timeout) {
ctx = context;
this.intent =intent;
this.timeout = timeout;
}
public AidlUtil(Context context, Intent intent) {
this(context, intent, 3000);
}
static int rate =200;
public IBinder getIBinder() {
ctx.bindService(intent, conn,
Context.BIND_AUTO_CREATE);
try {
latch.await(timeout, TimeUnit.MILLISECONDS);
}catch(Exception e){
e.printStackTrace();
}
if(binder==null) {
System.out.println("AIDL通讯建立失败");
}
return binder;
}
/***
* Android L (lollipop, API 21) introduced a new problem when trying to invoke implicit intent,
* "java.lang.IllegalArgumentException: Service Intent must be explicit"
*
* If you are using an implicit intent, and know only 1 target would answer this intent,
* This method will help you turn the implicit intent into the explicit form.
*
* Inspired from SO answer: http://stackoverflow.com/a/26318757/1446466
* @param context
* @param implicitIntent - The original implicit intent
* @return Explicit Intent created from the implicit original intent
*/
public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
// Retrieve all services that can match the given intent
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);
// Make sure only one match was found
if (resolveInfo == null || resolveInfo.size() != 1) {
return null;
}
// Get component info and create ComponentName
ResolveInfo serviceInfo = resolveInfo.get(0);
String packageName = serviceInfo.serviceInfo.packageName;
String className = serviceInfo.serviceInfo.name;
ComponentName component = new ComponentName(packageName, className);
// Create a new intent. Use the old one for extras and such reuse
Intent explicitIntent = new Intent(implicitIntent);
// Set the component to be explicit
explicitIntent.setComponent(component);
return explicitIntent;
}
}

View File

@ -30,6 +30,8 @@ import androidx.core.content.ContextCompat;
import com.xixun.joey.aidlset.CardService; import com.xixun.joey.aidlset.CardService;
import com.xixun.xy.conn.aidl.ConnService; import com.xixun.xy.conn.aidl.ConnService;
import org.json.JSONObject;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
@ -182,7 +184,6 @@ public class MainActivity extends Activity implements Choreographer.FrameCallbac
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
Util.println(" ==>> MainActivity onResume >> "+hashCode()); Util.println(" ==>> MainActivity onResume >> "+hashCode());
if(progView==null && insView==null) runOnUiThread(this::initProg);
} }
@Override @Override
@ -190,10 +191,9 @@ public class MainActivity extends Activity implements Choreographer.FrameCallbac
super.onPause(); super.onPause();
Util.println(" ==<< MainActivity onPause << "+hashCode()); Util.println(" ==<< MainActivity onPause << "+hashCode());
state = 8; state = 8;
stopProg();
} }
CardService serviCard; static CardService serviCard;
ConnService serviXy; ConnService serviXy;
Intent intenCard; Intent intenCard;
ServiceConnection connCard; ServiceConnection connCard;
@ -246,31 +246,22 @@ public class MainActivity extends Activity implements Choreographer.FrameCallbac
return "{\"width\":\"" + Util.screenWidth + "px\",\"height\":\"" + Util.screenHeight + "px\"}"; return "{\"width\":\"" + Util.screenWidth + "px\",\"height\":\"" + Util.screenHeight + "px\"}";
} }
@JavascriptInterface @JavascriptInterface
public String getNetwork() { public String getNetwork() {// 获取当前网络类型
// 获取当前网络类型
NetworkTypeUtil.NetworkType networkType = NetworkTypeUtil.getCurrentNetworkType(MainActivity.this); NetworkTypeUtil.NetworkType networkType = NetworkTypeUtil.getCurrentNetworkType(MainActivity.this);
String value = ""; String value = "";
switch (networkType) { switch (networkType) {
case WIFI: case WIFI:
value = NetworkTypeUtil.getWifiSsid(MainActivity.this); value = NetworkTypeUtil.getWifiSsid(MainActivity.this);// 处理未获取到SSID的情况
// 处理未获取到SSID的情况 if(O.isEmpty(value)) value = "未知WiFi名称";
if (O.isEmpty(value)) value = "未知WiFi名称";
System.out.println("当前是 WiFi 网络:" + value);
break; break;
case ETHERNET: case ETHERNET:
System.out.println("当前是有线网络");
break; break;
case CELLULAR: case CELLULAR:// 细分蜂窝网络类型2G/3G/4G
// 细分蜂窝网络类型2G/3G/4G value = NetworkTypeUtil.getCellularSubType(MainActivity.this);;
String cellularSubType = NetworkTypeUtil.getCellularSubType(MainActivity.this);
value = cellularSubType;
System.out.println("当前是蜂窝网络:" + cellularSubType);
break; break;
case NONE: case NONE:
System.out.println("无网络连接");
break; break;
case UNKNOWN: case UNKNOWN:
System.out.println("未知网络类型如蓝牙、VPN");
break; break;
} }
var IP = NetworkTypeUtil.getActiveNetworkIp(MainActivity.this); var IP = NetworkTypeUtil.getActiveNetworkIp(MainActivity.this);
@ -327,6 +318,7 @@ public class MainActivity extends Activity implements Choreographer.FrameCallbac
Util.isScreenOn = serviCard.isScreenOpen(); Util.isScreenOn = serviCard.isScreenOpen();
Util.screenWidth = serviCard.getScreenWidth(); Util.screenWidth = serviCard.getScreenWidth();
Util.screenHeight = serviCard.getScreenHeight(); Util.screenHeight = serviCard.getScreenHeight();
Util.println(" IsScreenOn: "+Util.isScreenOn+" screen: "+Util.screenWidth+" x "+Util.screenHeight); Util.println(" IsScreenOn: "+Util.isScreenOn+" screen: "+Util.screenWidth+" x "+Util.screenHeight);
backView.invalidate(); backView.invalidate();
if(Util.isScreenOn) initProg(); if(Util.isScreenOn) initProg();
@ -346,6 +338,7 @@ public class MainActivity extends Activity implements Choreographer.FrameCallbac
bindService(intenCard, connCard, Context.BIND_AUTO_CREATE); bindService(intenCard, connCard, Context.BIND_AUTO_CREATE);
services.add(connCard); services.add(connCard);
var connXy = new ServiceConnection() { var connXy = new ServiceConnection() {
public void onServiceDisconnected(ComponentName name) { public void onServiceDisconnected(ComponentName name) {
serviXy = null; serviXy = null;
@ -570,11 +563,17 @@ public class MainActivity extends Activity implements Choreographer.FrameCallbac
AudioManager audioManager; AudioManager audioManager;
AudioFocusRequest audioFocusRequest; AudioFocusRequest audioFocusRequest;
public void stopProg() { public void stopProg() {
Util.println("---- Stop Prog\n");
avas.clear(); avas.clear();
showHides.clear(); showHides.clear();
showeds.clear(); showeds.clear();
curAva = 0; curAva = 0;
curTimes = 1; curTimes = 1;
if(backViewL==null) setContentView(backView);
else {
setContentView(backViewL);
backViewL.loadUrl("file:///android_asset/local_page.html");
}
if(insView!=null) { if(insView!=null) {
insView.release(); insView.release();
insView = null; insView = null;
@ -583,11 +582,6 @@ public class MainActivity extends Activity implements Choreographer.FrameCallbac
progView.release(); progView.release();
progView = null; progView = null;
} }
if(backViewL==null) setContentView(backView);
else {
setContentView(backViewL);
backViewL.loadUrl("file:///android_asset/local_page.html");
}
System.gc(); System.gc();
} }
public boolean delProgFile() { public boolean delProgFile() {
@ -609,9 +603,11 @@ public class MainActivity extends Activity implements Choreographer.FrameCallbac
return ok; return ok;
} }
public void initProg() { public void initProg() {
Util.println("\n---- Init Prog");
if(progView!=null || insView!=null) return;
state = 1; state = 1;
try { try {
Util.println("\nParse Insert Prog Json"); Util.println(" Parse Insert Json");
var root = JSMap.fromClose(new BufferedInputStream(new FileInputStream(Util.programDir + "/insert"))); var root = JSMap.fromClose(new BufferedInputStream(new FileInputStream(Util.programDir + "/insert")));
var task = root.jsmap("task"); var task = root.jsmap("task");
if(task==null && root.containsKey("layers")) task = new JSMap("items", new JSList<>(new JSMap("_program", root))); if(task==null && root.containsKey("layers")) task = new JSMap("items", new JSList<>(new JSMap("_program", root)));
@ -626,7 +622,7 @@ public class MainActivity extends Activity implements Choreographer.FrameCallbac
} }
var demand = 0; var demand = 0;
try { try {
Util.println("\nParse Prog Json"); Util.println(" Parse Json");
var root = JSMap.fromClose(new BufferedInputStream(new FileInputStream(Util.programDir + "/program"))); var root = JSMap.fromClose(new BufferedInputStream(new FileInputStream(Util.programDir + "/program")));
var task = root.jsmap("task"); var task = root.jsmap("task");
demand = root.intg("Demand"); demand = root.intg("Demand");
@ -646,10 +642,12 @@ public class MainActivity extends Activity implements Choreographer.FrameCallbac
} }
if(insView!=null || progView!=null) { if(insView!=null || progView!=null) {
state = 5; state = 5;
Util.println("Init Sync");
var ms = System.currentTimeMillis(); var ms = System.currentTimeMillis();
if(demand==0 || progView==null) syncProg(ms, 0); if(demand==0 || progView==null) {
else { Util.println(" Init Sync");
syncProg(ms, 0);
} else {
Util.println(" demand "+demand);
avas.clear(); avas.clear();
var page = progView.pages.get(demand-1); var page = progView.pages.get(demand-1);
avas.add(page); avas.add(page);
@ -669,8 +667,8 @@ public class MainActivity extends Activity implements Choreographer.FrameCallbac
} else if(state != 7) state = 3; } else if(state != 7) state = 3;
} }
public void initProg(byte[] json) { public void initProg(byte[] json) {
Util.println("\n---- Init Prog with json");
try { try {
Util.println("\nParse Prog Json");
var root = JSMap.from(json); var root = JSMap.from(json);
var task = root.jsmap("task"); var task = root.jsmap("task");
if(task==null) { if(task==null) {

View File

@ -7,14 +7,27 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.os.IBinder; import android.os.IBinder;
import com.xixun.xy.conn.aidl.ConnService;
import net.lingala.zip4j.ZipFile; import net.lingala.zip4j.ZipFile;
import org.json.JSONObject;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Comparator;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
import gnph.util.IOs; import gnph.util.IOs;
import gnph.util.JSList;
import gnph.util.JSMap;
public class MainService extends Service { public class MainService extends Service {
@ -50,27 +63,132 @@ public class MainService extends Service {
Util.makeText(MainService.this, "MEDIA_MOUNTED path: "+path+"\nImporting 正在导入 ...").show(); Util.makeText(MainService.this, "MEDIA_MOUNTED path: "+path+"\nImporting 正在导入 ...").show();
new Thread(()->{ new Thread(()->{
try { try {
var zip = new ZipFile(path+"/program.zip"); if(Util.custom == Util.Custom.LoRa) {
System.out.println("周鹏测试");
JSONObject jo = new JSONObject();
jo.put("_id","123456");
jo.put("_type","GetCardAlias");
String alias = MainActivity.serviCard.executeJsonCommand(jo.toString());
JSONObject js = new JSONObject(alias);
// 1. JSONObject 中获取待解码的原始字符串替换为你的 js.getString("alias")
String rawBase64Str = js.getString("alias");
// 2. 关键Base64 字符串预处理解决大部分格式非法问题
String processedBase64Str = preprocessBase64(rawBase64Str);
// 3. 后续正常解码使用预处理后的字符串
byte[] decodeBytes = Base64.getDecoder().decode(processedBase64Str);
String originalStr = new String(decodeBytes, StandardCharsets.UTF_8);
System.out.println("周鹏获取别名"+originalStr);
Util.downId = 0;
var ok = new AtomicBoolean(false);
if(MainActivity.ins!=null) {
var latch = new CountDownLatch(1);
MainActivity.ins.runOnUiThread(() -> {
ok.set(MainActivity.ins.delProgFile());
latch.countDown();
});
try {
latch.await();
} catch (InterruptedException ignored) {}
}
// var id = Util.getCardId();
var id = originalStr;
var dir = new File(path+"/"+id);
if(! dir.isDirectory()) {
Util.println("MEDIA_MOUNTED can't find "+id);
if(acti!=null) acti.runOnUiThread(() -> Util.makeText(acti, "MEDIA_MOUNTED can't find "+id).show());
return;
}
long size = 0;
var files = dir.listFiles();
Arrays.sort(files, (f1, f2) -> f1.getName().compareTo(f2.getName()));
for(var file : files) if(! file.getName().endsWith("json")) {
size += file.length();
}
if(size==0) {
Util.println("files' size is 0");
if(acti!=null) acti.runOnUiThread(() -> Util.makeText(acti, "files' size is 0").show());
return;
}
var items = new JSList<JSMap>();
var root = new JSMap(
"_type", "PlayXixunTask",
"Demand", 1,
"task", new JSMap(
"name", id,
"width", Util.screenWidth,
"height", Util.screenHeight,
"items", items
)
);
Util.deleteFiles(size, null);
for(var file : files) if(! file.getName().endsWith("json")) {
var name = file.getName();
Util.println(" name: " + name);
var fOut = new FileOutputStream(Util.programDir + "/" + name);
IOs.writeCloseIn(fOut, new FileInputStream(file));
fOut.flush();
fOut.getFD().sync();
fOut.close();
items.add(new JSMap(
"_program", new JSMap(
"name", name,
"layers", new JSList<>(new JSMap(
"sources", new JSList<>(new JSMap(
"_type", "Video",
"id", name,
"md5", name,
"name", name,
"timeSpan", 43200,
"left", 0,
"top", 0,
"width", Util.screenWidth,
"height", Util.screenHeight,
"playTime", 0
))
))
)
));
}
var fOut = new FileOutputStream(Util.programDir + "/program");
root.write(fOut);
var spaces = " ".getBytes();
for(int i=0;i<1000; i++) fOut.write(spaces);
fOut.flush();
fOut.getFD().sync();
fOut.close();
Util.println("Import Succeed");
if(acti!=null) acti.runOnUiThread(() -> {
Util.makeText(acti, "Import Succeed 导入成功").show();
acti.initProg();
});
} else {
var zip = new ZipFile(path + "/program.zip");
if(zip.isEncrypted()) zip.setPassword(pass); if(zip.isEncrypted()) zip.setPassword(pass);
long size = 0; long size = 0;
ByteArrayOutputStream jsonOut = null; ByteArrayOutputStream jsonOut = null;
var headers = zip.getFileHeaders(); var headers = zip.getFileHeaders();
for(var header : headers) { for(var header : headers) {
size += header.getUncompressedSize(); size += header.getUncompressedSize();
if("program".equals(header.getFileName())) IOs.writeClose(jsonOut = new ByteArrayOutputStream(), zip.getInputStream(header)); if ("program".equals(header.getFileName()))
IOs.writeClose(jsonOut = new ByteArrayOutputStream(), zip.getInputStream(header));
} }
if(jsonOut==null) { if(jsonOut == null) {
Util.println("No program File"); Util.println("No program File");
if(acti!=null) acti.runOnUiThread(() -> Util.makeText(acti, "No program File").show()); if (acti != null)
acti.runOnUiThread(() -> Util.makeText(acti, "No program File").show());
return; return;
} }
if(size==0) { if(size == 0) {
Util.println("zip size is 0"); Util.println("zip size is 0");
if(acti!=null) acti.runOnUiThread(() -> Util.makeText(acti, "zip size is 0").show()); if (acti != null)
acti.runOnUiThread(() -> Util.makeText(acti, "zip size is 0").show());
return; return;
} }
Util.deleteFiles(size, null); Util.deleteFiles(size, null);
for(var header : headers) if(! "program".equals(header.getFileName())) { for(var header : headers)
if (!"program".equals(header.getFileName())) {
Util.println(" name: " + header.getFileName()); Util.println(" name: " + header.getFileName());
var fOut = new FileOutputStream(Util.programDir + "/" + header.getFileName()); var fOut = new FileOutputStream(Util.programDir + "/" + header.getFileName());
IOs.writeCloseIn(fOut, zip.getInputStream(header)); IOs.writeCloseIn(fOut, zip.getInputStream(header));
@ -80,7 +198,7 @@ public class MainService extends Service {
} }
var json = jsonOut.toByteArray(); var json = jsonOut.toByteArray();
Util.println("Import Succeed"); Util.println("Import Succeed");
if(acti!=null) acti.runOnUiThread(() -> { if(acti != null) acti.runOnUiThread(() -> {
Util.makeText(acti, "Import Succeed 导入成功").show(); Util.makeText(acti, "Import Succeed 导入成功").show();
acti.initProg(json); acti.initProg(json);
}); });
@ -88,7 +206,7 @@ public class MainService extends Service {
var fOut = new FileOutputStream(Util.programDir + "/program"); var fOut = new FileOutputStream(Util.programDir + "/program");
fOut.write(json); fOut.write(json);
var spaces = " ".getBytes(); var spaces = " ".getBytes();
for(int i=0;i<1000; i++) fOut.write(spaces); for (int i = 0; i < 1000; i++) fOut.write(spaces);
fOut.flush(); fOut.flush();
fOut.getFD().sync(); fOut.getFD().sync();
fOut.close(); fOut.close();
@ -99,6 +217,7 @@ public class MainService extends Service {
var inten = new Intent("com.xixun.AccessibilityService"); var inten = new Intent("com.xixun.AccessibilityService");
inten.putExtra("newProgram", "USB"); inten.putExtra("newProgram", "USB");
sendBroadcast(inten); sendBroadcast(inten);
}
} catch (Exception e) { } catch (Exception e) {
Util.printStackTrace(e); Util.printStackTrace(e);
if(acti!=null) acti.runOnUiThread(() -> Util.makeText(acti, Util.toStr(e)).show()); if(acti!=null) acti.runOnUiThread(() -> Util.makeText(acti, Util.toStr(e)).show());
@ -127,4 +246,34 @@ public class MainService extends Service {
public IBinder onBind(Intent intent) { public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented"); throw new UnsupportedOperationException("Not yet implemented");
} }
/**
* Base64 字符串预处理清洗非法内容补全合法格式
* @param rawStr 原始待解码的 Base64 字符串
* @return 符合标准 Base64 格式的预处理字符串
*/
private static String preprocessBase64(String rawStr) {
if (rawStr == null || rawStr.trim().isEmpty()) {
throw new IllegalArgumentException("待解码的 Base64 字符串不能为空");
}
// 步骤1剔除所有不可见字符空格换行制表符等
String cleanStr = rawStr.replaceAll("\\s+", "");
// 步骤2剔除 Base64 标准字符之外的非法字符仅保留 A-Za-z0-9+/=
cleanStr = cleanStr.replaceAll("[^A-Za-z0-9+/=]", "");
// 步骤3补全格式使字符串长度为 4 的整数倍不足补 =最多补 3 实际只会补 0/1/2
int remainder = cleanStr.length() % 4;
if (remainder != 0) {
int padLength = 4 - remainder;
StringBuilder sb = new StringBuilder(cleanStr);
for (int i = 0; i < padLength; i++) {
sb.append('=');
}
cleanStr = sb.toString();
}
return cleanStr;
}
} }

View File

@ -490,9 +490,20 @@ public class Prog extends AbsLayout {
void release() { void release() {
try { try {
setVisibility(GONE); setVisibility(GONE);
View view; for(var page : pages) for(var layer : page.layers) for(var src : layer.srcs) {
for(int cc=0; cc<getChildCount(); cc++) if((view = getChildAt(cc)) instanceof SrcVideo) ((SrcVideo) view).release(); if(src.tts!=null) src.tts.shutdown();
for(var page : pages) for(var layer : page.layers) for(var src : layer.srcs) if(src.tts!=null) src.tts.shutdown(); if(src.view instanceof SrcVideo) {
((SrcVideo) src.view).release();
src.view = null;
Util.println(" SrcVideo released");
} else if(src.view instanceof WebView) {
var web = (WebView) src.view;
web.removeAllViews();
web.destroy();
src.view = null;
Util.println(" WebView destroyed");
}
}
} catch (Throwable e) { } catch (Throwable e) {
Util.printStackTrace(e); Util.printStackTrace(e);
} }

View File

@ -35,8 +35,8 @@ import wseemann.media.FFmpegMediaMetadataRetriever;
public class Util { public class Util {
enum Custom{Normal, Yishi}; enum Custom{Normal, Yishi, LoRa};
public static final Custom custom = Custom.Normal; public static final Custom custom = Custom.LoRa;
public static JSMap cfg; public static JSMap cfg;
public static SQLiteOpenHelper openHelper; public static SQLiteOpenHelper openHelper;
public static String serverURL; public static String serverURL;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.