This commit is contained in:
Gangphon 2024-03-12 18:28:10 +08:00
parent 05ff5a7488
commit 92f364cf63
13 changed files with 194 additions and 127 deletions

View File

@ -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() {

Binary file not shown.

View File

@ -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"

View File

@ -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();
}

View File

@ -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<JSMap> jpages = task.jslist("items");
@ -72,6 +74,7 @@ public class Prog extends AbsLayout {
for(var pageMap : jpages) {
var _program = pageMap.jsmap("_program");
JSList<JSMap> 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) {

View File

@ -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<JSMap> jpages = task.jslist("items");
int proSize = 0;

View File

@ -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 = "<body style=\"color:#fff;margin:0;padding:0;";
var lineHeight = json.str("lineHeight");
if(lineHeight!=null) prefix += "line-height:"+lineHeight+";";
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);
}
}
}
}

View File

@ -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");

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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<Integer, String[]> stateDescs = new HashMap<>();

View File

@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample backup rules file; uncomment and customize as necessary.
See https://developer.android.com/guide/topics/data/autobackup
for details.
Note: This file is ignored for devices older that API 31
See https://developer.android.com/about/versions/12/backup-restore
-->
<full-backup-content>
<!--
<include domain="sharedpref" path="."/>
<exclude domain="sharedpref" path="device.xml"/>
-->
</full-backup-content>

View File

@ -1,19 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--
Sample data extraction rules file; uncomment and customize as necessary.
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
for details.
-->
<data-extraction-rules>
<cloud-backup>
<!-- TODO: Use <include> and <exclude> to control what is backed up.
<include .../>
<exclude .../>
-->
</cloud-backup>
<!--
<device-transfer>
<include .../>
<exclude .../>
</device-transfer>
-->
</data-extraction-rules>