diff --git a/XixunPlayer/app/build.gradle b/XixunPlayer/app/build.gradle index 695f214..6bc8d03 100644 --- a/XixunPlayer/app/build.gradle +++ b/XixunPlayer/app/build.gradle @@ -11,7 +11,7 @@ android { minSdk 21 targetSdk 34 versionCode 1 - versionName "1.1" + versionName "2.0.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -45,6 +45,7 @@ dependencies { implementation files('libs/ijkplayer-java-0.8.8.aar') implementation files('libs/ijkplayer-armv7a-0.8.8.aar') implementation files('libs/ijkplayer-arm64-0.8.8.aar') + implementation files('libs\\connService2.jar') } def getAppName() { diff --git a/XixunPlayer/app/libs/connService2.jar b/XixunPlayer/app/libs/connService2.jar new file mode 100644 index 0000000..9bb1491 Binary files /dev/null and b/XixunPlayer/app/libs/connService2.jar differ diff --git a/XixunPlayer/app/src/main/AndroidManifest.xml b/XixunPlayer/app/src/main/AndroidManifest.xml index 38625b6..6a47772 100644 --- a/XixunPlayer/app/src/main/AndroidManifest.xml +++ b/XixunPlayer/app/src/main/AndroidManifest.xml @@ -14,8 +14,6 @@ android:allowBackup="true" android:usesCleartextTraffic="true" android:launchMode="singleTop" - android:dataExtractionRules="@xml/data_extraction_rules" - android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" diff --git a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/MainActivity.java b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/MainActivity.java index e244e1f..86553f3 100644 --- a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/MainActivity.java +++ b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/MainActivity.java @@ -16,7 +16,6 @@ import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.IBinder; -import android.os.RemoteException; import android.os.StatFs; import android.os.StrictMode; import android.view.Choreographer; @@ -32,6 +31,7 @@ import androidx.core.content.ContextCompat; import androidx.media3.common.util.UnstableApi; import com.xixun.joey.aidlset.CardService; +import com.xixun.xy.conn.aidl.ConnService; import net.lingala.zip4j.ZipFile; @@ -100,6 +100,9 @@ public class MainActivity extends ComponentActivity implements Choreographer.Fra if(requestCode==999 && grantResults.length > 0 && grantResults[0]==PackageManager.PERMISSION_GRANTED && backView==null) init(); } + int receCnt; + ConnService connService; + @SuppressLint("UnspecifiedRegisterReceiverFlag") public void init() { var dir = Build.VERSION.SDK_INT < Build.VERSION_CODES.R ? Environment.getExternalStorageDirectory().getAbsolutePath() + "/XixunPlayer" : getExternalFilesDir(null).getAbsolutePath(); @@ -113,33 +116,146 @@ public class MainActivity extends ComponentActivity implements Choreographer.Fra msg = "---- mkdir: "+program.mkdirs(); Util.println(msg); - var conn = new ServiceConnection() { + var cardConn = new ServiceConnection() { public void onServiceDisconnected(ComponentName name) { Util.println("Disconnected cardsystem aidl service"); } public void onServiceConnected(ComponentName name, IBinder iBinder) { + unbindService(this); Util.println("Bind cardsystem aidl service success"); var service = CardService.Stub.asInterface(iBinder); try { Util.isScreenOn = service.isScreenOpen(); - Util.println("isScreenOn: "+Util.isScreenOn); - backView = new BackView(MainActivity.this, service.getScreenWidth(), service.getScreenHeight()); - state = 5; - if(Util.isScreenOn) initProg(); - else state = 8; - if(progView==null) setContentView(backView); - } catch (RemoteException e) { + Util.screenWidth = service.getScreenWidth(); + Util.screenHeight = service.getScreenHeight(); + Util.println(" IsScreenOn: "+Util.isScreenOn+" screen: "+Util.screenWidth+" x "+Util.screenHeight); + if(receCnt++>=1) { + backView = new BackView(MainActivity.this, Util.screenWidth, Util.screenHeight); + state = 5; + if(Util.isScreenOn) initProg(); + else state = 8; + if(progView==null) setContentView(backView); + } + } catch (Exception e) { Util.makeText(MainActivity.this, Util.toStr(e)).show(); Util.printStackTrace(e); - } finally { - unbindService(this); } } }; var intent = new Intent("com.xixun.joey.aidlset.SettingsService"); intent.setPackage("com.xixun.joey.cardsystem"); - bindService(intent, conn, Context.BIND_AUTO_CREATE); + bindService(intent, cardConn, Context.BIND_AUTO_CREATE); + + var connConn = new ServiceConnection() { + public void onServiceDisconnected(ComponentName name) { + Util.println("Disconnected xy.conn aidl service"); + connService = null; + } + public void onServiceConnected(ComponentName name, IBinder iBinder) { + unbindService(this); + Util.println("Bind xy.conn aidl service success"); + connService = ConnService.Stub.asInterface(iBinder); + try { + Util.serverURL = connService.getServerURL(); + Util.println(" ServerURL: "+Util.serverURL); + if(Util.serverURL==null || Util.serverURL.isEmpty()) Util.serverURL = "https://m2mled.net/"; + else { + if(! Util.serverURL.startsWith("http")) Util.serverURL = "http://"+Util.serverURL; + if(! Util.serverURL.endsWith("/")) Util.serverURL += "/"; + } + if(receCnt++>=1) { + backView = new BackView(MainActivity.this, Util.screenWidth, Util.screenHeight); + state = 5; + if(Util.isScreenOn) initProg(); + else state = 8; + if(progView==null) setContentView(backView); + } + } catch (Exception e) { + Util.makeText(MainActivity.this, Util.toStr(e)).show(); + Util.printStackTrace(e); + } + } + }; + intent = new Intent("xixun.intent.action.CONNECTION_INFO"); + intent.setPackage("com.xixun.xy.conn"); + bindService(intent, connConn, Context.BIND_AUTO_CREATE); + + registerReceiver(new BroadcastReceiver(){ + @Override + public void onReceive(Context context, Intent intent) { + Util.println("Receive PAUSE_PLAYER"); + Util.isScreenOn = ! intent.getBooleanExtra("pause", false); + Util.println(" IsScreenOn: "+Util.isScreenOn); + if(! Util.isScreenOn) { + state = 8; + if(progView!=null) { + progView.release(); + progView = null; + setContentView(backView); + } + } else if(progView==null) initProg(); + } + }, new IntentFilter("com.xixun.action.PAUSE_PLAYER")); + + registerReceiver(new BroadcastReceiver(){ + @Override + public void onReceive(Context context, Intent intent) { + Util.println("Receive CHANGE_COMPANYID"); + if(connService!=null) { + try { + Util.serverURL = connService.getServerURL(); + Util.println(" ServerURL: "+Util.serverURL); + } catch (Exception e) { + Util.makeText(MainActivity.this, Util.toStr(e)).show(); + Util.printStackTrace(e); + } + } + } + }, new IntentFilter("com.xixun.joey.CHANGE_COMPANYID")); + + registerReceiver(new BroadcastReceiver(){ + @Override + public void onReceive(Context context, Intent intent) { + MainActivity.this.environIntent = intent; + for(var environ : environs) { + environ.onReceive(intent); + ((View)environ).invalidate(); + } + } + }, new IntentFilter("xixun.intent.action.TEMPERATURE_HUMIDITY")); + + registerReceiver(new BroadcastReceiver(){ + @Override + public void onReceive(Context context, Intent intent) { + try { + var code = intent.getIntExtra("code", 0); + Util.println(" remote_control "+code); + if(progView == null || code > progView.pages.size()) return; + if(! progView.avas.isEmpty()) page(progView.curAva).hide(); + var millis = (System.currentTimeMillis()+999)/1000*1000; + if(code > 0) { + progView.avas.clear(); + progView.avas.add(code-1); + progView.curAva = 0; + progView.curTimes = 1; + progView.waitTo = 0; //点播 + var page = page(0); + page.setMillis(millis); + if(state != 6) { + setContentView(progView); + state = 6; + } + } else { + progView.waitTo = Long.MAX_VALUE; + syncProg(millis); + } + } catch (Throwable e) { + Util.makeText(MainActivity.this, Util.toStr(e)).show(); + Util.printStackTrace(e); + } + } + }, new IntentFilter("com.xixun.yzd.REMOTE_CONTROL")); var intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); intentFilter.addDataScheme("file"); @@ -194,72 +310,6 @@ public class MainActivity extends ComponentActivity implements Choreographer.Fra } }, intentFilter); - registerReceiver(new BroadcastReceiver(){ - @Override - public void onReceive(Context context, Intent intent) { - Util.println("Receive PAUSE_PLAYER"); - Util.isScreenOn = ! intent.getBooleanExtra("pause", false); - Util.println(" isScreenOn: "+Util.isScreenOn); - if(! Util.isScreenOn) { - state = 8; - if(progView!=null) { - progView.release(); - progView = null; - setContentView(backView); - } - } else if(progView==null) initProg(); - } - }, new IntentFilter("com.xixun.action.PAUSE_PLAYER")); - -// registerReceiver(new BroadcastReceiver(){ -// @Override -// public void onReceive(Context context, Intent intent) { -// } -// }, new IntentFilter("com.xixun.joey.CHANGE_COMPANYID"), RECEIVER_EXPORTED); - - registerReceiver(new BroadcastReceiver(){ - @Override - public void onReceive(Context context, Intent intent) { - MainActivity.this.environIntent = intent; - for(var environ : environs) { - environ.onReceive(intent); - ((View)environ).invalidate(); - } - } - }, new IntentFilter("xixun.intent.action.TEMPERATURE_HUMIDITY")); - - registerReceiver(new BroadcastReceiver(){ - @Override - public void onReceive(Context context, Intent intent) { - try { - var code = intent.getIntExtra("code", 0); - Util.println(" remote_control "+code); - if(progView == null || code > progView.pages.size()) return; - if(! progView.avas.isEmpty()) page(progView.curAva).hide(); - var millis = (System.currentTimeMillis()+999)/1000*1000; - if(code > 0) { - progView.avas.clear(); - progView.avas.add(code-1); - progView.curAva = 0; - progView.curTimes = 1; - progView.waitTo = 0; //点播 - var page = page(0); - page.setMillis(millis); - if(state != 6) { - setContentView(progView); - state = 6; - } - } else { - progView.waitTo = Long.MAX_VALUE; - syncProg(millis); - } - } catch (Throwable e) { - Util.makeText(MainActivity.this, Util.toStr(e)).show(); - Util.printStackTrace(e); - } - } - }, new IntentFilter("com.xixun.yzd.REMOTE_CONTROL")); - new Thread(this).start(); } diff --git a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Prog.java b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Prog.java index 1d83924..124b866 100644 --- a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Prog.java +++ b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Prog.java @@ -2,6 +2,7 @@ package com.xixun.xixunplayer; import android.annotation.SuppressLint; import android.content.Context; +import android.graphics.Color; import android.net.Uri; import android.speech.tts.TextToSpeech; import android.view.Choreographer; @@ -31,6 +32,7 @@ public class Prog extends AbsLayout { int curAva, curTimes = 1; long waitTo = Long.MAX_VALUE; + @SuppressLint("SetJavaScriptEnabled") public Prog(JSMap task, Context context) { super(context); JSList jpages = task.jslist("items"); @@ -72,6 +74,7 @@ public class Prog extends AbsLayout { for(var pageMap : jpages) { var _program = pageMap.jsmap("_program"); JSList layers = _program.jslist("layers"); + var isSimple = _program.intg("version")==2; if(layers==null || layers.isEmpty()) continue; var page = new Page(); page.repeatTimes = pageMap.intg("repeatTimes", 1); @@ -94,10 +97,10 @@ public class Prog extends AbsLayout { if(src.type.isEmpty()) continue; var timeSpan = source.intg("timeSpan")*1000; if(timeSpan==0) continue; - var geo = new AbsLayout.LayoutParams(source.intg("left")+bdWidth, source.intg("top")+bdWidth, source.intg("width")-bdWidth-bdWidth, source.intg("height")-bdWidth-bdWidth); - boolean notAudio = ! src.type.equals("Audio"); + var geo = isSimple ? new AbsLayout.LayoutParams(0, 0, width, height) : new AbsLayout.LayoutParams(source.intg("left")+bdWidth, source.intg("top")+bdWidth, source.intg("width")-bdWidth-bdWidth, source.intg("height")-bdWidth-bdWidth); + var notAudio = ! src.type.equals("Audio"); if((geo.width<=0 || geo.height<=0 || (geo.y>=height && height>0) || (geo.x>=width && width>0)) && notAudio) continue; - src.startTime = source.intg("playTime")*1000; + src.startTime = isSimple ? (layer.srcs.isEmpty() ? 0 : layer.srcs.get(layer.srcs.size()-1).endTime) : source.intg("playTime")*1000; if(bdStart > src.startTime) bdStart = src.startTime; src.endTime = src.startTime + timeSpan; if(bdEnd < src.endTime) bdEnd = src.endTime; @@ -249,6 +252,11 @@ public class Prog extends AbsLayout { } } else if(src.type.equals("WebURL")) { var webView = new WebView(context); + webView.setBackgroundColor(Color.TRANSPARENT); + webView.setVerticalScrollBarEnabled(false); + webView.setHorizontalScrollBarEnabled(false); + webView.setInitialScale(100); + webView.getSettings().setJavaScriptEnabled(true); webView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { diff --git a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Server.java b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Server.java index 9ae0561..8f07c06 100644 --- a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Server.java +++ b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Server.java @@ -103,10 +103,9 @@ public class Server extends Service { var json = JSMap.from(jsonBytes); var _type = json.stnn("_type"); commandId = json.stnn("id"); - boolean is2 = false; - if(_type.equals("PlayXixunTask") || (is2 = _type.equals("PlayProgramTask"))) { + if(_type.equals("PlayXixunTask") || _type.equals("PlayProgramTask")) { var preDownloadURL = json.str("preDownloadURL"); - if(preDownloadURL==null && is2) preDownloadURL = "https://m2mled.net/file/download?id="; + if(preDownloadURL==null) preDownloadURL = Util.serverURL+"file/download?id="; var task = json.jsmap("task"); JSList jpages = task.jslist("items"); int proSize = 0; diff --git a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcSensor.java b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcSensor.java index fd29626..446ca44 100644 --- a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcSensor.java +++ b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcSensor.java @@ -1,22 +1,27 @@ package com.xixun.xixunplayer; +import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.graphics.Color; +import android.view.Choreographer; import android.webkit.WebView; import java.text.DecimalFormat; import gnph.util.JSMap; import gnph.util.NumFmts; +import gnph.util.URLConn; -public class SrcSensor extends WebView implements IntentReceiver { +public class SrcSensor extends WebView implements IntentReceiver, Choreographer.FrameCallback { static String directs[] = {"NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW", "N"}; MainActivity act; - String html, lineHeight, prefix; + String html, prefix, url, text; + int interval; boolean isFirst = true; + @SuppressLint("SetJavaScriptEnabled") public SrcSensor(Context context, JSMap json) { super(context); act = (MainActivity) context; @@ -24,9 +29,23 @@ public class SrcSensor extends WebView implements IntentReceiver { setVerticalScrollBarEnabled(false); setHorizontalScrollBarEnabled(false); setInitialScale(100); + getSettings().setJavaScriptEnabled(true); + html = json.stnn("html").replace("%Co2", "%CO2"); - lineHeight = json.str("lineHeight"); + url = json.str("sUrl"); + interval = json.intg("sInterval") * 1000; + if(url!=null && interval>0 && html.contains("%s")) { + nextMs = System.currentTimeMillis() + interval; + Util.println("url: "+url); + try { + text = URLConn.send(url); + } catch (Exception e) { + text = ""; + Util.printStackTrace(e); + } + } prefix = ""; } @@ -66,6 +85,7 @@ public class SrcSensor extends WebView implements IntentReceiver { //int brightness = intent.getIntExtra("brightness", -1); var dp = intent.getFloatExtra("dpTemperature", -99f); + if(text!=null) htm = htm.replace("%s", text); htm = htm.replace("%T2", t2 + '℃').replace("%T1", t1 + '℃').replace("%T", tn + '℃').replace("%c2", t2).replace("%c1", t1).replace("%c", t0) .replace("%t2", f2 + '℉').replace("%t1", f1 + '℉').replace("%t", fn + '℉').replace("%f2", f2).replace("%f1", f1).replace("%f", f0) .replace("%RH", h+'%').replace("%h", h) @@ -92,6 +112,8 @@ public class SrcSensor extends WebView implements IntentReceiver { } } + long nextMs; + @Override public void onVisibilityAggregated(boolean isVisible) { super.onVisibilityAggregated(isVisible); @@ -106,4 +128,17 @@ public class SrcSensor extends WebView implements IntentReceiver { isFirst = true; } } + + @Override + public void doFrame(long ms) { + if(! isShown()) return; + if(text!=null && ms>=nextMs) { + nextMs = ms + interval; + try { + text = URLConn.send(url); + } catch (Exception e) { + Util.printStackTrace(e); + } + } + } } diff --git a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcTimer.java b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcTimer.java index 76d45e3..02e632f 100644 --- a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcTimer.java +++ b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcTimer.java @@ -9,10 +9,10 @@ import android.graphics.Paint; import android.view.Choreographer; import android.view.View; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; -import gnph.util.Dates; import gnph.util.JSMap; import gnph.util.NumFmts; @@ -40,7 +40,13 @@ public class SrcTimer extends View implements Choreographer.FrameCallback { sec = imgMap.get("sec"); spaceWidth = (int) Math.round(json.dbl("spaceWidth")); isDown = json.bool("isDown"); - targetTime = Dates.milli(json.stnn("targetTime")) / 1000; + var dateFmt = new SimpleDateFormat("y-M-d H:m:s"); + try { + targetTime = dateFmt.parse(json.stnn("targetTime")).getTime() / 1000; + } catch (Exception e) { + Util.makeText(prog.getContext(), Util.toStr(e)).show(); + Util.printStackTrace(e); + } hasDay = json.bool("hasDay"); hasHour = json.bool("hasHour"); hasMin = json.bool("hasMin"); diff --git a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcVisitor.java b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcVisitor.java index 11d5bf3..5c011a9 100644 --- a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcVisitor.java +++ b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcVisitor.java @@ -87,7 +87,7 @@ public class SrcVisitor extends WebView implements Choreographer.FrameCallback { public void doFrame(long ms) { if(! isShown()) return; if(ms>=nextMs) { - nextMs += 15000; + nextMs = ms + 15000; refresh(); } } diff --git a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcWeather.java b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcWeather.java index 57be973..227bdb0 100644 --- a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcWeather.java +++ b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/SrcWeather.java @@ -227,6 +227,7 @@ public class SrcWeather extends WebView { nitImgMap.put("小到中雪", "15"); nitImgMap.put("无天气类型", "unknown"); } + long nextMs; @Override @@ -235,7 +236,7 @@ public class SrcWeather extends WebView { if(isVisible) { var ms = System.currentTimeMillis(); if(ms>=nextMs) { - nextMs += 1800000; + nextMs = ms + 1800000; refresh(); } } diff --git a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Util.java b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Util.java index 06ad091..f62a598 100644 --- a/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Util.java +++ b/XixunPlayer/app/src/main/java/com/xixun/xixunplayer/Util.java @@ -20,7 +20,8 @@ import java.util.concurrent.CountDownLatch; import gnph.util.IOs; public class Util { - + public static String serverURL; + public static int screenWidth, screenHeight; public static boolean isScreenOn; public static final HashMap stateDescs = new HashMap<>(); diff --git a/XixunPlayer/app/src/main/res/xml/backup_rules.xml b/XixunPlayer/app/src/main/res/xml/backup_rules.xml deleted file mode 100644 index fa0f996..0000000 --- a/XixunPlayer/app/src/main/res/xml/backup_rules.xml +++ /dev/null @@ -1,13 +0,0 @@ - - - - \ No newline at end of file diff --git a/XixunPlayer/app/src/main/res/xml/data_extraction_rules.xml b/XixunPlayer/app/src/main/res/xml/data_extraction_rules.xml deleted file mode 100644 index 9ee9997..0000000 --- a/XixunPlayer/app/src/main/res/xml/data_extraction_rules.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - \ No newline at end of file