You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
TermApp/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java

1104 lines
44 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.xypower.mpapp;
import static java.lang.System.in;
import static java.lang.System.loadLibrary;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.PowerManager;
import android.os.RemoteException;
import android.os.SystemClock;
import androidx.core.app.NotificationCompat;
import androidx.core.content.FileProvider;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.telephony.SignalStrength;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;
import com.dev.devapi.api.SysApi;
import com.xypower.common.FileDownloader;
import com.xypower.common.InetAddressUtils;
import com.xypower.common.MicroPhotoContext;
import java.io.File;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MicroPhotoService extends Service {
public static final String TAG = "MPLOG";
// Used to load the 'microphoto' library on application startup.
static {
loadLibrary("microphoto");
}
public static final int MSG_WHAT_LOG = 10;
public final static int MSG_WHAT_NETWORK_CHANGE = 20;
public final static int MSG_WHAT_SERVICE_STATUS_CHANGE = 30;
public final static int MSG_WHAT_SENDING_HB = 40;
public final static int MSG_WHAT_MAX = 1000;
private static final String ALARM_EVENT = "com.xinyingpower.mp.MicroPhotoService.AlarmReceiver";
public static final int NOTIFICATION_ID_FOREGROUND_SERVICE = 8466503;
// public static final int NOTIFICATION_ID_FOREGROUND_SERVICE = 0;
public static final String ACTION_MSG_BROADCAST = "ACT_MSG_BROADCAST";
public static final String ACTION_START = "com.xypower.mpapp.ACT_START";
public static final String ACTION_STOP = "com.xypower.mpapp.ACT_STOP";
public static final String ACTION_MAIN = "com.xypower.mpapp.ACT_MAIN";
private static final String ACTION_HEARTBEAT = "com.xypower.mpapp.ACT_HB";
private static final String ACTION_TAKE_PHOTO = "com.xypower.mpapp.ACT_TP";
private static final String ACTION_TAKE_PHOTO_MANUALLY = "com.xypower.mpapp.ACT_TP_M";
private static final String ACTION_HEARTBEAT_MANUALLY = "com.xypower.mpapp.ACT_HB_M";
private static final String ACTION_TIMEOUT = "com.xypower.mpapp.ACT_TIMEOUT";
public static final String ACTION_VIDEO_FINISHED = "com.xypower.mpapp.ACT_V_FINISHED";
private static final String EXTRA_PARAM_CHANNEL = "Channel";
private static final String EXTRA_PARAM_PRESET = "Preset";
private static final String EXTRA_PARAM_PHOTO_OR_VIDEO = "PhotoOrVideo";
private static final String EXTRA_PARAM_SCHEDULES = "Schedules";
private static final String EXTRA_PARAM_SCHEDULE = "Schedule_";
private static final String EXTRA_PARAM_TIME = "Time";
// private static String EXTRA_PARAM_FILENAME = "FileName";
private static final String EXTRA_PARAM_TIMER_UID = "TimerUid";
// private static String EXTRA_PARAM_TIMER_TYPE = "TimerType";
private static final String EXTRA_PARAM_TIMEOUT = "Timeout";
private static final String EXTRA_PARAM_TIMES = "Times";
private static final String EXTRA_PARAM_ELASPED_TIMES = "ElapsedTimes";
private static final String FOREGROUND_CHANNEL_ID = "foreground_channel_id";
public static class STATE_SERVICE {
public static final int CONNECTED = 10;
public static final int NOT_CONNECTED = 0;
}
private static int mStateService = STATE_SERVICE.NOT_CONNECTED;
private String mCmdid = "";
private NotificationManager mNotificationManager;
private final Map<String, PowerManager.WakeLock> mWakeLocks = new HashMap<>();
private int mHeartbeatDuration = 0; // Default 1m: 10 * 60 * 1000 from NDK
private long mNextHeartbeatTime = 0;
private PositionManager mPositionManager = null;
private final Map<Long, PendingIntent> mTimers = new HashMap<>();
protected long mNativeHandle = 0;
private AlarmReceiver mAlarmReceiver = null;
private ScreenActionReceiver mScreenaAtionReceiver = null;
private NetworkChangedReceiver mNetworkChangedReceiver = null;
private ServiceHandler mHander = null;
private Messenger mMessenger = null;
private String mModelName = null;
public MicroPhotoService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
mHander = new ServiceHandler();
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mStateService = STATE_SERVICE.NOT_CONNECTED;
DeviceUtil.getPhoneState(this.getApplicationContext());
mScreenaAtionReceiver = new ScreenActionReceiver();
// 注册广播接受者
{
mAlarmReceiver = new AlarmReceiver(this);
IntentFilter intentFilter = new IntentFilter(ACTION_HEARTBEAT);
intentFilter.addAction(ACTION_TAKE_PHOTO);
intentFilter.addAction(ACTION_TIMEOUT);
intentFilter.addAction(ACTION_TAKE_PHOTO_MANUALLY);
intentFilter.addAction(ACTION_HEARTBEAT_MANUALLY);
intentFilter.addAction(ACTION_MSG_BROADCAST);
intentFilter.addAction(ACTION_VIDEO_FINISHED);
getApplicationContext().registerReceiver(mAlarmReceiver, intentFilter);
// IntentFilter intentFilter2 = new IntentFilter(ACTION_MSG_BROADCAST);
// registerReceiver(mAlarmReceiver, intentFilter2);
// registerRe
}
{
mNetworkChangedReceiver = new NetworkChangedReceiver(this);
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(mNetworkChangedReceiver, filter);
}
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
while (true) {
AlarmManager.AlarmClockInfo aci = alarmManager.getNextAlarmClock();
if (aci == null) {
break;
}
/*
if (aci.getShowIntent().isBroadcast()) {
// alarmManager.cancel(aci.getShowIntent());
}
*/
}
// alarmManager.cancel();
// boolean res = false;
// Environment.getExternalStoragePublicDirectory(String)
// registerHeartbeatTimer(getHeartbeatDuration());
}
@Override
public void onDestroy() {
mStateService = STATE_SERVICE.NOT_CONNECTED;
Log.w(TAG, "MicroPhotoService::onDestroy called");
uninit(mNativeHandle);
mNativeHandle = 0;
getApplicationContext().unregisterReceiver(mAlarmReceiver);
unregisterReceiver(mScreenaAtionReceiver);
unregisterReceiver(mNetworkChangedReceiver);
for(Map.Entry<String, PowerManager.WakeLock> entry : mWakeLocks.entrySet()) {
try {
PowerManager.WakeLock wl = entry.getValue();
wl.setReferenceCounted(false);
wl.release();
wl = null;
} catch (Exception ex) {
ex.printStackTrace();
}
}
mWakeLocks.clear();
super.onDestroy();
}
public static class ServiceHandler extends Handler {
@Override
public void dispatchMessage(Message msg) {
super.dispatchMessage(msg);
// Log.i("life", "MyHandler----dispatchMessage");
// Log.i("life", Thread.currentThread().getName());
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// Log.i("life", "MyHandler----handleMessage");
}
}
public String getCmdid() {
return mCmdid;
}
public static void sendMessage(Context context, int what, int data) {
Intent intent = new Intent(ACTION_MSG_BROADCAST);
intent.putExtra("what", what);
intent.putExtra("data", data);
intent.setPackage(context.getPackageName());
String typeName = AlarmReceiver.class.getTypeName();
intent.setComponent( new ComponentName(context.getPackageName(), AlarmReceiver.class.getTypeName()) );
context.sendBroadcast(intent);
}
public static class AlarmReceiver extends BroadcastReceiver {
private MicroPhotoService mService;
public AlarmReceiver() {
mService = null;
}
public AlarmReceiver(MicroPhotoService service) {
mService = service;
}
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (TextUtils.equals(ACTION_HEARTBEAT, action)) {
Log.i(TAG, "HB Timer Fired ACTION=" + action);
mService.sendHeartbeat(mService.mNativeHandle);
mService.registerHeartbeatTimer();
} else if (TextUtils.equals(ACTION_TAKE_PHOTO, action)) {
long ts = intent.getLongExtra(EXTRA_PARAM_TIME, 0);
int cnt = intent.getIntExtra(EXTRA_PARAM_SCHEDULES, 0);
if (cnt > 0) {
for (int idx = 0; idx < cnt; idx++) {
long val = intent.getLongExtra(EXTRA_PARAM_SCHEDULE + idx, 0);
int channel = (int) ((val & 0xFF0000L) >> 16);
int preset = (int) ((val & 0xFF00L) >> 8);
boolean photoOrVideo = ((val & 0xFFL) == 0);
Log.i(TAG, "PhotoTimer Fired: CH=" + channel + " PR=" + preset);
mService.notifyToTakePhoto(mService.mNativeHandle, channel, preset, ts, photoOrVideo);
}
}
// Register Next Photo Timer
Date date = new Date();
long nowTs = date.getTime() / 1000;
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
long startTime = date.getTime() / 1000;
long baseTime = nowTs - startTime;
mService.registerCaptureSchedule(startTime, baseTime);
} else if (TextUtils.equals(ACTION_HEARTBEAT_MANUALLY, action)) {
Log.i(TAG, "HB Timer Fired ACTION=" + action);
mService.sendHeartbeat(mService.mNativeHandle);
} else if (TextUtils.equals(ACTION_TAKE_PHOTO_MANUALLY, action)) {
int channel = intent.getIntExtra(EXTRA_PARAM_CHANNEL, 0);
int preset = intent.getIntExtra(EXTRA_PARAM_PRESET, 0);
// long ts = intent.getLongExtra(EXTRA_PARAM_TIME, 0);
boolean photoOrVideo = intent.getBooleanExtra(EXTRA_PARAM_PHOTO_OR_VIDEO, true);
long ts = System.currentTimeMillis() / 1000;
Log.i(TAG, "Take Photo CH=" + channel + " PR=" + preset + " Mannually");
mService.notifyToTakePhoto(mService.mNativeHandle, channel, preset, ts, photoOrVideo);
} else if (TextUtils.equals(ACTION_TIMEOUT, action)) {
long uid = intent.getLongExtra(EXTRA_PARAM_TIMER_UID, 0);
long expectedTimes = intent.getLongExtra(EXTRA_PARAM_TIMES, 0);
long elapsedTimes = intent.getLongExtra(EXTRA_PARAM_ELASPED_TIMES, 0);
elapsedTimes++;
Log.i(TAG, "Timeout uid=" + uid + " expectedTimes=" + expectedTimes + " Times=" + elapsedTimes);
mService.fireTimeout(mService.mNativeHandle, uid, elapsedTimes);
intent.putExtra(EXTRA_PARAM_ELASPED_TIMES, elapsedTimes);
Long uidObj = Long.valueOf(uid);
if ((expectedTimes == 0) || (elapsedTimes < expectedTimes)) {
int timeout = intent.getIntExtra(EXTRA_PARAM_TIMEOUT, 0);
PendingIntent pendingIntent = mService.mTimers.get(uidObj);
if (pendingIntent != null) {
mService.registerTimer(pendingIntent, uid, timeout);
}
} else {
mService.mTimers.remove(uidObj);
}
} else if (TextUtils.equals(ACTION_MSG_BROADCAST, action)) {
int what = intent.getIntExtra("what", 0);
int data = intent.getIntExtra("data", 0);
if (what == MSG_WHAT_SENDING_HB) {
mService.sendHeartbeat(mService.mNativeHandle);
}
} else if (TextUtils.equals(ACTION_VIDEO_FINISHED, action)) {
boolean result = intent.getBooleanExtra("result", false);
String path = intent.getStringExtra("path");
long videoId = intent.getLongExtra("videoId", 0);
Log.i(TAG, "Recording received(" + Long.toString(videoId) + "):" + path);
mService.recordingFinished(mService.mNativeHandle, result, path, videoId);
}
}
}
private void registerHeartbeatTimer(int duration) {
int orgHeartbeatDuration = mHeartbeatDuration;
mHeartbeatDuration = duration;
if (orgHeartbeatDuration == 0) {
registerHeartbeatTimer();
}
}
private void registerHeartbeatTimer() {
// 创建延迟意图
Intent alarmIntent = new Intent();
alarmIntent.setAction(ACTION_HEARTBEAT);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + mHeartbeatDuration, pendingIntent);
mNextHeartbeatTime = System.currentTimeMillis() + mHeartbeatDuration;
// alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + timeout, pendingIntent);
}
private static void registerPhotoTimer(Context context, int channel, int preset, long ts, long timeout, List<Long> schedules) {
// 创建延迟意图
Intent alarmIntent = new Intent();
alarmIntent.setAction(ACTION_TAKE_PHOTO);
int cnt = schedules.size();
alarmIntent.putExtra(EXTRA_PARAM_SCHEDULES, cnt);
String channelStr = "";
for (int idx = 0; idx < cnt; idx++) {
long val = schedules.get(idx).longValue();
alarmIntent.putExtra(EXTRA_PARAM_SCHEDULE + idx, schedules.get(idx).longValue());
channelStr += "CH=" + ((val & 0XFF0000) >> 16) + "-PR=" + ((val & 0XFF00) >> 8) + " ";
}
alarmIntent.putExtra(EXTRA_PARAM_TIME, ts);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
long currentTimeMillis = System.currentTimeMillis();
Date date = new Date(currentTimeMillis + timeout);
String dateStr = (String) DateFormat.format("MM-dd kk:mm:ss", date);
Log.d(TAG, "PhotoTimer Reg: " + dateStr + " currentTimeMillis=" + currentTimeMillis + " timeout=" + timeout + " Channels=" + channelStr);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + timeout, pendingIntent);
}
private void registerPhotoTimer(int channel, int preset, long ts, long timeout, List<Long> schedules) {
registerPhotoTimer(this.getApplicationContext(), channel, preset, ts, timeout, schedules);
}
public void startRecording(int cameraId, long videoId, int duration, int width, int height, int quality) {
Context context = getApplicationContext();
Intent intent = context.getPackageManager().getLaunchIntentForPackage("com.xypower.mvapp");
intent.putExtra("cameraId", cameraId);
intent.putExtra("videoId", videoId);
intent.putExtra("duration", duration);
intent.putExtra("width", width);
intent.putExtra("height", height);
intent.putExtra("quality", quality);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
}
// private HashMap<Long, Integer> mTimers = new HashMap<Long, Integer>();
public boolean registerTimer(long uid, int timeout, long times) {
// 创建延迟意图
Intent alarmIntent = new Intent();
alarmIntent.setAction(ACTION_TIMEOUT);
alarmIntent.putExtra(EXTRA_PARAM_TIMER_UID, uid);
alarmIntent.putExtra(EXTRA_PARAM_TIMEOUT, timeout);
alarmIntent.putExtra(EXTRA_PARAM_TIMES, times);
alarmIntent.putExtra(EXTRA_PARAM_ELASPED_TIMES, 0L);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mTimers.put(Long.valueOf(uid), pendingIntent);
return registerTimer(pendingIntent, uid, timeout);
}
private void setDefaultDataSubId(int subId) {
SubscriptionManager subscriptionManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
try {
Method method = subscriptionManager.getClass().getDeclaredMethod("setDefaultDataSubId", int.class);
method.invoke(subscriptionManager, subId);
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Method method1 = telephonyManager.getClass().getDeclaredMethod("setDataEnabled", boolean.class);
method1.invoke(telephonyManager, true);
} catch (Exception e) {
Log.e(TAG, "wjz debug setDefaultDataSubId: error is " + e.getMessage());
}
}
private int getDefaultDataSubId() {
SubscriptionManager subscriptionManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
try {
Method method = subscriptionManager.getClass().getDeclaredMethod("getDefaultDataSubscriptionId");
return (int) method.invoke(subscriptionManager);
} catch (Exception e) {
Log.e(TAG, "wjz debug getDefaultDataSubId: error is " + e.getMessage());
}
return 0;
}
public boolean registerTimer(PendingIntent pendingIntent, long uid, int timeout) {
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + timeout, pendingIntent);
Log.i(TAG, "RegTimer:" + uid + " timeout=" + timeout);
return true;
}
public boolean unregisterTimer(long uid) {
Long uidObj = Long.valueOf(uid);
PendingIntent pendingIntent = mTimers.get(uidObj);
if (pendingIntent != null) {
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
mTimers.remove(uidObj);
Log.i(TAG, "UnregTimer:" + uid);
}
return true;
}
private boolean registerCaptureSchedule(long timeOfZeroPoint, long secondsOfToday) {
long[] photoTimeData = getPhotoTimeData(mNativeHandle);
if (photoTimeData == null) {
return false;
}
int cnt = photoTimeData.length;
short channel = 0;
short preset = 0;
int ts = 0;
long val = 0L;
// int maxDuration = mHeartbeatDuration * 2 / 1000;
int maxDuration = 35 * 60 * 1000 + 1000;
int currentTs = -1;
List<Long> schedules = new ArrayList<>();
int offset = 0;
for (int day = 0; day < 2; day++, offset += 86400) {
for (int idx = 0; idx < cnt; idx++) {
val = photoTimeData[idx];
ts = (int) ((val & 0x00FFFFFF00000000L) >> 32) + offset;
if (ts < secondsOfToday) {
continue;
}
if ((ts - secondsOfToday) > maxDuration) {
break;
}
if (currentTs == -1) {
currentTs = ts;
channel = (short) ((val & 0xFF0000L) >> 16);
preset = (short) ((val & 0xFF00L) >> 8);
schedules.add(Long.valueOf(val));
Log.i(TAG, "PhotoTimer Reg: CH=" + channel + " PR=" + preset);
} else if (ts > currentTs) {
break;
} else {
channel = (short) ((val & 0xFF0000L) >> 16);
preset = (short) ((val & 0xFF00L) >> 8);
Log.i(TAG, "PhotoTimer Reg: CH=" + channel + " PR=" + preset);
schedules.add(Long.valueOf(val));
}
}
if (!schedules.isEmpty()) {
break;
}
}
if (!schedules.isEmpty()) {
long expectedTs = timeOfZeroPoint + ts;
// Date date = new Date(expectedTs * 1000);
// Log.d(TAG, "Register Photo Time: " + date.toString() + " BaseTime=" + secondsOfToday + " ts=" + ts + " startTime=" + startTime + " expectedTs=" + expectedTs);
registerPhotoTimer(channel, preset, expectedTs, expectedTs * 1000 - System.currentTimeMillis(), schedules);
}
return true;
}
public static void takePhoto(Context context, int channel, int preset, boolean photoOrVideo) {
List<Long> schedules = new ArrayList<>();
long ts = System.currentTimeMillis() / 1000;
// long val = (ts << 24);
long val = 0;
val |= ((long)channel << 16);
val |= ((long)preset << 8);
val |= photoOrVideo ? 0L : 1L;
schedules.add(Long.valueOf(val));
registerPhotoTimer(context, channel, preset, 0, 0, schedules);
}
public static void sendHeartbeat(Context context) {
Intent alarmIntent = new Intent();
// if(Build.VERSION.SDK_INT >= 26) {
// alarmIntent.addFlags(0x01000000);
//}
alarmIntent.setPackage(context.getPackageName());
alarmIntent.setAction(ACTION_HEARTBEAT_MANUALLY);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
// context.sendBroadcast(alarmIntent);
// LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
// localBroadcastManager.sendBroadcast(alarmIntent);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 100, pendingIntent);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent == null) {
stopForeground(true);
stopSelf();
return START_NOT_STICKY;
}
// if user starts the service
switch (intent.getAction()) {
case ACTION_START:
Log.d(TAG, "Received user starts foreground intent");
startForeground(NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification());
connect();
registerReceiver(mScreenaAtionReceiver, mScreenaAtionReceiver.getFilter());
if (intent.hasExtra("messenger")) {
mMessenger = intent.getParcelableExtra("messenger");
}
int network = intent.getIntExtra("network", 0);
if (network == 0) {
startTerminalService(intent);
} else {
ConnectivityManager cm =(ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder builder = new NetworkRequest.Builder();
builder.addCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
List<NetworkInfo> availableNetworkInfos = new ArrayList<>();
cm.registerNetworkCallback(builder.build(), new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
super.onAvailable(network);
availableNetworkInfos.add(cm.getNetworkInfo(network));
Log.i(TAG, "Network");
}
});
NetworkInfo[] networkInfos = cm.getAllNetworkInfo();
for (NetworkInfo ni : networkInfos) {
if (ni.getType() == ConnectivityManager.TYPE_MOBILE ||
ni.getType() == ConnectivityManager.TYPE_MOBILE_DUN ||
ni.getType() == ConnectivityManager.TYPE_WIFI) {
// availableNetworkInfos.add(ni);
}
}
Network[] networks = cm.getAllNetworks();
for (Network nw : networks) {
NetworkInfo nwi = cm.getNetworkInfo(nw);
String name = nwi.toString();
if (name.equals("")) {
}
}
}
break;
case ACTION_STOP:
unregisterReceiver(mScreenaAtionReceiver);
stopForeground(true);
stopSelf();
break;
default:
stopForeground(true);
stopSelf();
}
return START_NOT_STICKY;
}
private void startTerminalService(Intent intent) {
String appPath = MicroPhotoContext.buildAppDir(this.getApplicationContext());
String server = intent.getStringExtra("server");
int port = intent.getIntExtra("port", 0);
String cmdid = intent.getStringExtra("cmdid");
int protocol = intent.getIntExtra("protocol", 0);
int networkProtocol = intent.getIntExtra("networkProtocol", 0);
if (!InetAddressUtils.isIPv4Address(server) && !InetAddressUtils.isIPv6Address(server)) {
// It is a domain
InetAddress addr = null;
try {
addr = InetAddress.getByName(server);
} catch (Exception e) {
e.printStackTrace();
}
if (addr != null) {
server = addr.getHostAddress();
}
}
Log.i(TAG, "AppPath=" + appPath + " Server=" + server + ":" + port + " cmdid=" + cmdid + " Protocol=" + protocol + " Network=" + networkProtocol);
MicroPhotoService service = MicroPhotoService.this;
service.mNativeHandle = init(appPath, server, port, cmdid, protocol, networkProtocol, 0);
if (service.mNativeHandle !=0) {
service.mCmdid = cmdid;
Date date = new Date();
long nowTs = date.getTime() / 1000;
date.setHours(0);
date.setMinutes(0);
date.setSeconds(0);
long startTime = date.getTime() / 1000;
long baseTime = nowTs - startTime;
service.registerCaptureSchedule(startTime, baseTime);
}
}
public void requestWakelock(String name, long timeout) {
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK/* | PowerManager.ON_AFTER_RELEASE*/, name);
PowerManager.WakeLock wl2 = null;
synchronized (mWakeLocks) {
wl2 = mWakeLocks.get(name);
mWakeLocks.put(name, wl);
}
if (wl2 != null) {
Log.i(TAG, "Release same name wakelock:" + name);
wl2.setReferenceCounted(false);
wl2.release();
}
Log.i(TAG, "Request wakelock:" + name);
if (timeout == 0) wl.acquire();
else wl.acquire(timeout);
}
public void releaseWakelock(String name) {
PowerManager.WakeLock wl = null;
synchronized (mWakeLocks) {
try {
wl = mWakeLocks.get(name);
mWakeLocks.remove(name);
} catch (Exception ex) {
ex.printStackTrace();
}
}
if (wl != null) {
Log.i(TAG, "Release wakelock:" + name);
try {
wl.setReferenceCounted(false);
wl.release();
} catch (Exception ex) {
ex.printStackTrace();
}
wl = null;
}
}
private void connect() {
// after 10 seconds its connected
mHander.postDelayed(
new Runnable() {
public void run() {
Log.d(TAG, "Bluetooth Low Energy device is connected!!");
Toast.makeText(getApplicationContext(), "Connected!", Toast.LENGTH_SHORT).show();
mStateService = STATE_SERVICE.CONNECTED;
startForeground(NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification());
}
}, 10000);
}
private Notification prepareNotification() {
// handle build version above android oreo
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O &&
mNotificationManager.getNotificationChannel(FOREGROUND_CHANNEL_ID) == null) {
CharSequence name = getString(R.string.text_name_notification);
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(FOREGROUND_CHANNEL_ID, name, importance);
channel.enableVibration(false);
mNotificationManager.createNotificationChannel(channel);
}
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction(ACTION_MAIN);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// if min sdk goes below honeycomb
/*if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
} else {
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}*/
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// make a stop intent
Intent stopIntent = new Intent(this, MicroPhotoService.class);
stopIntent.setAction(ACTION_STOP);
PendingIntent pendingStopIntent = PendingIntent.getService(this, 0, stopIntent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification);
remoteViews.setOnClickPendingIntent(R.id.btn_stop, pendingStopIntent);
// if it is connected
switch (mStateService) {
case STATE_SERVICE.NOT_CONNECTED:
remoteViews.setTextViewText(R.id.tv_state, "DISCONNECTED");
break;
case STATE_SERVICE.CONNECTED:
remoteViews.setTextViewText(R.id.tv_state, "CONNECTED");
break;
}
// notification builder
NotificationCompat.Builder notificationBuilder;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
notificationBuilder = new NotificationCompat.Builder(this, FOREGROUND_CHANNEL_ID);
} else {
notificationBuilder = new NotificationCompat.Builder(this);
}
notificationBuilder
.setContent(remoteViews)
.setSmallIcon(R.mipmap.ic_launcher)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setOnlyAlertOnce(true)
.setOngoing(true)
.setAutoCancel(true)
.setContentIntent(pendingIntent);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
notificationBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
}
return notificationBuilder.build();
}
public boolean updateTime(long timeInMillis) {
try {
SysApi.setSystemTime(getApplicationContext(), timeInMillis);
} catch (Exception ex) {
}
return true;
}
public static Uri getUriForFile(Context context, File file) {
if (Build.VERSION.SDK_INT > 24) {
return FileProvider.getUriForFile(context, context.getPackageName() + ".fileProvider", file);
}
return Uri.fromFile(file);
}
public boolean requestPosition() {
try {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getSystemService (Context.LOCATION_SERVICE);
if (!mLocationManager.isProviderEnabled(GPS_LOCATION_NAME)) {
return false;
}
mLocateType = mLocationManager.GPS_PROVIDER;
}
Location location = mLocationManager.getLastKnownLocation(mLocateType);
if (location != null) {
updatePosition(mNativeHandle, location.getLongitude(), location.getLatitude(), location.getTime());
}
// Set Listener
mLocationManager.requestLocationUpdates(mLocateType, 100,0, locationListener);
return true;
} catch (SecurityException ex) {
}
return false;
}
public void downloadAndInstall(final String url) {
final Context context = getApplicationContext();
final String tempPath = MicroPhotoContext.buildAppDir(context) + File.separator + "tmp";
File file = new File(tempPath);
file.mkdirs();
final String filePath = tempPath + File.separator + "mp.apk";
Thread th =new Thread(new Runnable() {
@Override
public void run() {
PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE, "com.xinyingpower.microphoto:Upgrader");
FileDownloader fd = new FileDownloader();
fd.download(url, filePath);
SysApi.installApk(context, filePath, context.getPackageName(), true);
try {
wl.setReferenceCounted(false);
wl.release();
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
th.start();
}
public String getSystemInfo() {
boolean isXyPlatform = mModelName.startsWith("tb8788");
StringBuilder sb = new StringBuilder();
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
Intent intent = getApplicationContext().registerReceiver(null, intentFilter);
int batteryStatus = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
int isCahrging = ((batteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) ||
(batteryStatus == BatteryManager.BATTERY_STATUS_FULL)) ? 1 : 0;
int level = intent.getIntExtra("level", 0); ///电池剩余电量
int scale = intent.getIntExtra("scale", 0); ///获取电池满电量数值
// intent.getStringExtra("technology"); ///获取电池技术支持
// intent.getIntExtra("status",BatteryManager.BATTERY_STATUS_UNKNOWN); ///获取电池状态
// intent.getIntExtra("plugged", 0); ///获取电源信息
// intent.getIntExtra("health",BatteryManager.BATTERY_HEALTH_UNKNOWN); ///获取电池健康度
int bv = intent.getIntExtra("voltage", 0); /// mv
int temp = intent.getIntExtra("temperature", 0); ///获取电池温度
BatteryManager manager = (BatteryManager) getSystemService(BATTERY_SERVICE);
// manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CHARGE_COUNTER);
int bca = manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_AVERAGE);
int bc = manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CURRENT_NOW);
level = manager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
float bcaVal = (bca < 0) ? ((-bca)/1000000000) : (bca / 1000000000);
sb.append("&BC=" + Float.toString(bcaVal));
sb.append("&BV=" + Float.toString(((float)bv) / 1000));
sb.append("&BP=" + level);
sb.append("&BS=" + scale);
sb.append("&CS=" + isCahrging);
ConnectivityManager cm = (ConnectivityManager)getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
boolean isMetered = cm.isActiveNetworkMetered();
sb.append("&NS=" + (isMetered ? "1" : "0"));
final TelephonyManager telephonyManager = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
SignalStrength ss = telephonyManager.getSignalStrength();
// List<CellSignalStrength> css = ss.getCellSignalStrengths();
if (ss != null) {
int signalLevel = ss.getLevel();
sb.append("&Signal4G=" + signalLevel);
sb.append("&Signal2G=" + signalLevel);
sb.append("&SL=" + signalLevel);
}
if (isXyPlatform) {
java.text.DecimalFormat fmt=new java.text.DecimalFormat("0.0");
double val = SysApi.getChargingVoltage() / 200.0;
sb.append("&CV=" + fmt.format(val)); // ChargeVol *5/1000
sb.append("&CC=" + SysApi.getChargingCurrent()); // ChargeCurrent
sb.append("&CP=" + SysApi.getChargingPower()); // ChargePower:
sb.append("&CBV=" + SysApi.getChargingBusVoltage()); // ChargeBusVol
val = SysApi.getBatteryVoltage() * 3.0 / 1000.0;
sb.append("&BV=" + fmt.format(val)); // BatVol
sb.append("&BC=" + SysApi.getBatteryCurrent()); // BatCurrent
sb.append("&BP=" + SysApi.getBatteryPower()); // BattaryPower
sb.append("&BBV=" + SysApi.getBatteryBusVoltage()); // BattaryBusVol
}
// SysApi.getCpuRate();
return sb.toString();
}
public void reboot(final int rebootType) {
Runnable runnable = new Runnable() {
@Override
public void run() {
if (rebootType == 0) {
Context context = MicroPhotoService.this.getApplicationContext();
restartApp(context, context.getPackageName());
} else {
Log.w(TAG, "Recv REBOOT command");
SysApi.reboot(MicroPhotoService.this.getApplicationContext());
}
}
};
mHander.postDelayed(runnable, 1000);
}
public static void restartApp(Context context, String packageName) {
/*
Context context = MicroPhotoService.this.getApplicationContext();
Intent intent = getPackageManager().getLaunchIntentForPackage(context.getPackageName());
int noDelay = 1;
intent.putExtra("noDelay", noDelay);
PendingIntent restartIntent = PendingIntent.getActivity(context, 0, intent, 0);
AlarmManager mgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); // 1秒钟后重启应用
System.exit(0);
*/
Intent LaunchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
LaunchIntent.putExtra("noDelay", 1);
LaunchIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(LaunchIntent);
}
public void enableGps(boolean enabled) {
SysApi.enableGps(getApplicationContext(), enabled);
}
public void selectSimCard(int num) {
SysApi.selectSimCard4Data(getApplicationContext(), num);
}
/*
TelephonyManager telephonyManager = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE);
// for example value of first element
CellInfoGsm cellInfoGsm = (CellInfoGsm)telephonyManager.getAllCellInfo().get(0);
CellSignalStrengthGsm cellSignalStrengthGsm = cellInfoGsm.getCellSignalStrength();
cellSignalStrengthGsm.getDbm();
*/
protected native long init(String appPath, String ip, int port, String cmdid, int protocol, int networkProtocl, long netHandle);
protected native long getHeartbeatDuration(long handler);
protected native long[] getPhotoTimeData(long handler);
// protected native long[] getNextScheduleItem(long handler);
protected native boolean notifyToTakePhoto(long handler, int channel, int preset, long scheduleTime, boolean photoOrVideo);
protected native boolean sendHeartbeat(long handler);
protected native boolean fireTimeout(long handler, long uid, long times);
protected native void updatePosition(long handler, double lon, double lat, long ts);
protected native boolean uninit(long handler);
protected native void recordingFinished(long handler, boolean result, String path, long videoId);
////////////////////////GPS////////////////////
private static final String GPS_LOCATION_NAME = android.location.LocationManager.GPS_PROVIDER;
private LocationManager mLocationManager;
private String mLocateType;
private LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
updatePosition(mNativeHandle, location.getLongitude(), location.getLatitude(), location.getTime());
// Log.i(TAG, "Time: " + location.getTime());
// Log.i(TAG, "经度:" + location.getLongitude());
// Log.i(TAG, "纬度:" + location.getLatitude());
// Log.i(TAG, "海拔:" + location.getAltitude());
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
switch (status) {
case LocationProvider.AVAILABLE:
// Toast.makeText(MainActivity.this, "onStatusChanged当前GPS状态为可见状态", Toast.LENGTH_SHORT).show();
break;
case LocationProvider.OUT_OF_SERVICE:
// Toast.makeText(MainActivity.this, "onStatusChanged:当前GPS状态为服务区外状态", Toast.LENGTH_SHORT).show();
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
// Toast.makeText(MainActivity.this, "onStatusChanged:当前GPS状态为暂停服务状态", Toast.LENGTH_SHORT).show();
break;
}
}
/**
* @param provider
*/
@Override
public void onProviderEnabled(String provider) {
// Toast.makeText(MainActivity.this, "onProviderEnabled:方法被触发", Toast.LENGTH_SHORT).show();
requestPosition();
}
/**
* @param provider
*/
@Override
public void onProviderDisabled(String provider) {
}
protected void writeLog(String log) {
if (mMessenger != null) {
Message msg = Message.obtain();
msg.what = MSG_WHAT_LOG;
msg.obj = log;
try {
mMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
};
////////////////////////GPS////////////////////
}