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

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;
2 years ago
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;
2 years ago
import android.os.RemoteException;
import android.os.SystemClock;
2 years ago
import androidx.core.app.NotificationCompat;
import androidx.core.content.FileProvider;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import android.telephony.SignalStrength;
2 years ago
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;
2 years ago
import com.xypower.common.FileDownloader;
import com.xypower.common.InetAddressUtils;
import com.xypower.common.MicroPhotoContext;
import java.io.File;
2 years ago
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 {
2 years ago
public static final String TAG = "MPLOG";
// Used to load the 'microphoto' library on application startup.
static {
loadLibrary("microphoto");
}
2 years ago
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;
2 years ago
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;
2 years ago
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);
2 years ago
intentFilter.addAction(ACTION_MSG_BROADCAST);
intentFilter.addAction(ACTION_VIDEO_FINISHED);
getApplicationContext().registerReceiver(mAlarmReceiver, intentFilter);
2 years ago
// 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());
}
2 years ago
@Override
public void onDestroy() {
mStateService = STATE_SERVICE.NOT_CONNECTED;
2 years ago
Log.w(TAG, "MicroPhotoService::onDestroy called");
uninit(mNativeHandle);
mNativeHandle = 0;
2 years ago
getApplicationContext().unregisterReceiver(mAlarmReceiver);
unregisterReceiver(mScreenaAtionReceiver);
unregisterReceiver(mNetworkChangedReceiver);
for(Map.Entry<String, PowerManager.WakeLock> entry : mWakeLocks.entrySet()) {
2 years ago
try {
PowerManager.WakeLock wl = entry.getValue();
wl.setReferenceCounted(false);
wl.release();
wl = null;
} catch (Exception ex) {
ex.printStackTrace();
}
}
mWakeLocks.clear();
2 years ago
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;
}
2 years ago
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;
2 years ago
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);
}
2 years ago
} 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);
}
}
}
2 years ago
private void registerHeartbeatTimer(int duration) {
int orgHeartbeatDuration = mHeartbeatDuration;
mHeartbeatDuration = duration;
2 years ago
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);
2 years ago
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);
2 years ago
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);
2 years ago
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);
}
2 years ago
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;
}
2 years ago
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;
2 years ago
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;
2 years ago
if (ts < secondsOfToday) {
continue;
}
2 years ago
if ((ts - secondsOfToday) > maxDuration) {
break;
}
2 years ago
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()) {
2 years ago
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);
2 years ago
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;
2 years ago
// long val = (ts << 24);
long val = 0;
val |= ((long)channel << 16);
val |= ((long)preset << 8);
val |= photoOrVideo ? 0L : 1L;
schedules.add(Long.valueOf(val));
2 years ago
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));
2 years ago
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);
2 years ago
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);
2 years ago
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) {
2 years ago
try {
wl = mWakeLocks.get(name);
mWakeLocks.remove(name);
} catch (Exception ex) {
ex.printStackTrace();
}
}
if (wl != null) {
Log.i(TAG, "Release wakelock:" + name);
2 years ago
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);
2 years ago
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();
2 years ago
if (ss != null) {
int signalLevel = ss.getLevel();
sb.append("&Signal4G=" + signalLevel);
sb.append("&Signal2G=" + signalLevel);
sb.append("&SL=" + signalLevel);
}
if (isXyPlatform) {
2 years ago
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
2 years ago
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 {
2 years ago
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);
}
2 years ago
/*
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);
2 years ago
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);
2 years ago
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);
2 years ago
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) {
}
2 years ago
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////////////////////
}