|
|
|
|
package com.xypower.mpapp;
|
|
|
|
|
|
|
|
|
|
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.ComponentCallbacks2;
|
|
|
|
|
import android.content.ComponentName;
|
|
|
|
|
import android.content.Context;
|
|
|
|
|
import android.content.Intent;
|
|
|
|
|
import android.content.IntentFilter;
|
|
|
|
|
import android.content.pm.ApplicationInfo;
|
|
|
|
|
import android.content.pm.PackageManager;
|
|
|
|
|
import android.graphics.Bitmap;
|
|
|
|
|
import android.graphics.BitmapFactory;
|
|
|
|
|
import android.graphics.ImageDecoder;
|
|
|
|
|
import android.graphics.Matrix;
|
|
|
|
|
import android.location.Location;
|
|
|
|
|
import android.location.LocationListener;
|
|
|
|
|
import android.location.LocationManager;
|
|
|
|
|
import android.location.LocationProvider;
|
|
|
|
|
import android.net.ConnectivityManager;
|
|
|
|
|
import android.net.LinkAddress;
|
|
|
|
|
import android.net.LinkProperties;
|
|
|
|
|
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.Looper;
|
|
|
|
|
import android.os.Message;
|
|
|
|
|
import android.os.Messenger;
|
|
|
|
|
import android.os.PowerManager;
|
|
|
|
|
import android.os.RemoteException;
|
|
|
|
|
import android.os.SystemClock;
|
|
|
|
|
|
|
|
|
|
import androidx.annotation.NonNull;
|
|
|
|
|
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.view.Gravity;
|
|
|
|
|
import android.widget.RemoteViews;
|
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
|
|
import com.dev.devapi.api.SysApi;
|
|
|
|
|
import com.xypower.common.FileDownloader;
|
|
|
|
|
import com.xypower.common.FilesUtils;
|
|
|
|
|
import com.xypower.common.NetworkUtils;
|
|
|
|
|
import com.xypower.common.MicroPhotoContext;
|
|
|
|
|
import com.xypower.mpapp.adb.CameraAdb;
|
|
|
|
|
import com.xypower.mpapp.utils.DeviceUtil;
|
|
|
|
|
import com.xypower.mpapp.v2.Camera2VideoActivity;
|
|
|
|
|
import com.xypower.mpapp.video.RawActivity;
|
|
|
|
|
|
|
|
|
|
import java.io.BufferedReader;
|
|
|
|
|
import java.io.File;
|
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
|
import java.io.InputStream;
|
|
|
|
|
import java.io.InputStreamReader;
|
|
|
|
|
import java.io.Reader;
|
|
|
|
|
import java.lang.reflect.Method;
|
|
|
|
|
import java.net.Inet4Address;
|
|
|
|
|
import java.net.InetAddress;
|
|
|
|
|
import java.nio.channels.FileLock;
|
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
import java.util.Date;
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
|
|
|
|
|
|
|
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_MAX = 1000;
|
|
|
|
|
|
|
|
|
|
public final static int MEDIA_TYPE_PHOTO = 0;
|
|
|
|
|
public final static int MEDIA_TYPE_VIDEO = 1;
|
|
|
|
|
|
|
|
|
|
public final static int MEDIA_TYPE_LOG = 2;
|
|
|
|
|
|
|
|
|
|
public final static int MEDIA_TYPE_STREAMING = 0x10;
|
|
|
|
|
public final static int MEDIA_TYPE_STREAMING_OFF = 0x11;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public final static int BROADCAST_REQUEST_CODE_HEARTBEAT = 1;
|
|
|
|
|
public final static int BROADCAST_REQUEST_CODE_TAKING_PHOTO = 2;
|
|
|
|
|
public final static int BROADCAST_REQUEST_CODE_GPS = 3;
|
|
|
|
|
public final static int BROADCAST_REQUEST_CODE_STOP_SERVICE = 4;
|
|
|
|
|
|
|
|
|
|
public static final int NOTIFICATION_ID_FOREGROUND_SERVICE = 8466503;
|
|
|
|
|
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_RESTART = "com.xypower.mpapp.ACT_RESTART";
|
|
|
|
|
public static final String ACTION_MAIN = "com.xypower.mpapp.ACT_MAIN";
|
|
|
|
|
private static final String ACTION_HEARTBEAT = MicroPhotoContext.ACTION_HEARTBEAT_MP;
|
|
|
|
|
private static final String ACTION_TAKE_PHOTO = "com.xypower.mpapp.ACT_TP";
|
|
|
|
|
private static final String ACTION_GPS_TIMEOUT = "com.xypower.mpapp.GPS_TIMEOUT";
|
|
|
|
|
|
|
|
|
|
private static final String ACTION_IMP_PUBKRY = "com.xypower.mpapp.ACT_IMP_PUBKEY";
|
|
|
|
|
|
|
|
|
|
private static final String ACTION_TAKE_PHOTO_MANUALLY = "com.xypower.mpapp.ACT_TP_M";
|
|
|
|
|
|
|
|
|
|
private static final String ACTION_CAMERA_CTRL = "com.xypower.mpapp.ACT_CAM_CTRL";
|
|
|
|
|
|
|
|
|
|
private static final String ACTION_HEARTBEAT_MANUALLY = "com.xypower.mpapp.ACT_HB_M";
|
|
|
|
|
private static final String ACTION_UPDATE_CONFIGS = "com.xypower.mpapp.ACT_UPD_CFG";
|
|
|
|
|
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_MEDIA_TYPE = "MediaType";
|
|
|
|
|
|
|
|
|
|
private static final String EXTRA_PARAM_URL = "Url";
|
|
|
|
|
private static final String EXTRA_PARAM_SCHEDULES = "Schedules";
|
|
|
|
|
private static final String EXTRA_PARAM_SCHEDULE = "Schedule_";
|
|
|
|
|
private static final String EXTRA_PARAM_TAKING_TIME = "TakingTime";
|
|
|
|
|
private static final String EXTRA_PARAM_TIME = "Time";
|
|
|
|
|
|
|
|
|
|
private static final String FOREGROUND_CHANNEL_ID = "fg_mpapp";
|
|
|
|
|
|
|
|
|
|
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; // MUST BE 0!!!
|
|
|
|
|
// private long mNextHeartbeatTime = 0;
|
|
|
|
|
|
|
|
|
|
// private final Map<Long, PendingIntent> mTimers = new HashMap<>();
|
|
|
|
|
|
|
|
|
|
protected long mNativeHandle = 0;
|
|
|
|
|
private AlarmReceiver mAlarmReceiver = null;
|
|
|
|
|
private AlarmReceiver mLocalMsgReceiver = null;
|
|
|
|
|
private ScreenActionReceiver mScreenaAtionReceiver = null;
|
|
|
|
|
private NetworkChangedReceiver mNetworkChangedReceiver = null;
|
|
|
|
|
|
|
|
|
|
private long mGpsTimeout = 60000; // 1 minute
|
|
|
|
|
private PendingIntent mPreviousGpsTimer = null;
|
|
|
|
|
private long mLastLocationRequested = 0;
|
|
|
|
|
|
|
|
|
|
private ServiceHandler mHander = null;
|
|
|
|
|
private Messenger mMessenger = null;
|
|
|
|
|
|
|
|
|
|
private String mModelName = null;
|
|
|
|
|
|
|
|
|
|
public static boolean isRunning = false;
|
|
|
|
|
|
|
|
|
|
FileOutputStream mAppRunningFile;
|
|
|
|
|
FileLock mAppLock;
|
|
|
|
|
|
|
|
|
|
private ConnectivityManager mConnectivityManager = null;
|
|
|
|
|
private ConnectivityManager.NetworkCallback mNetworkCallback = null;
|
|
|
|
|
|
|
|
|
|
private Runnable delayedSleep = new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
Log.i(TAG, "Device Sleep");
|
|
|
|
|
// SysApi.sleep(getApplicationContext());
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
public MicroPhotoService() {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void convertDngToPng(String dngFile, String pngFile) {
|
|
|
|
|
ImageDecoder.Source src = ImageDecoder.createSource(new File(dngFile));
|
|
|
|
|
Bitmap bmp = null;
|
|
|
|
|
FileOutputStream output = null;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
bmp = ImageDecoder.decodeBitmap(src);
|
|
|
|
|
output = new FileOutputStream(new File(pngFile));
|
|
|
|
|
bmp.compress(Bitmap.CompressFormat.JPEG, 95, output);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
} finally {
|
|
|
|
|
FilesUtils.closeFriendly(output);
|
|
|
|
|
if (bmp != null) {
|
|
|
|
|
bmp.recycle();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onTrimMemory(int level) {
|
|
|
|
|
infoLog("Event onTrimMemory level=" + level);
|
|
|
|
|
if (level >= ComponentCallbacks2.TRIM_MEMORY_BACKGROUND) {
|
|
|
|
|
// Clear the caches. Note all pending requests will be removed too.
|
|
|
|
|
final Context context = getApplicationContext();
|
|
|
|
|
try {
|
|
|
|
|
infoLog("Restart MpApp as for TrimMemory");
|
|
|
|
|
mHander.postDelayed(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
// restartApp(context, MicroPhotoContext.PACKAGE_NAME_MPAPP, "TrimMemory");
|
|
|
|
|
}
|
|
|
|
|
}, 1000);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onLowMemory() {
|
|
|
|
|
final Context context = getApplicationContext();
|
|
|
|
|
try {
|
|
|
|
|
Intent intent = new Intent(this, MainActivity.class);
|
|
|
|
|
int noDelay = 1;
|
|
|
|
|
intent.putExtra("noDelay", noDelay);
|
|
|
|
|
PendingIntent pi = PendingIntent.getActivity(this,0, intent,0);
|
|
|
|
|
AlarmManager alarmManager=(AlarmManager)getSystemService(ALARM_SERVICE);
|
|
|
|
|
alarmManager.set(AlarmManager.RTC_WAKEUP,System.currentTimeMillis() + 5000, pi);
|
|
|
|
|
infoLog("Restart MpApp after 5s as for LowMemory");
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@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();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (usingEthernet()) {
|
|
|
|
|
mConnectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
|
|
|
|
|
|
|
|
Network[] nws = mConnectivityManager.getAllNetworks();
|
|
|
|
|
for (Network nw : nws) {
|
|
|
|
|
NetworkInfo ni = mConnectivityManager.getNetworkInfo(nw);
|
|
|
|
|
if (ni.getType() == ConnectivityManager.TYPE_ETHERNET) {
|
|
|
|
|
updateEhernet(mNativeHandle, nw.getNetworkHandle(), true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
final String appPath = MicroPhotoContext.buildMpAppDir(this);
|
|
|
|
|
|
|
|
|
|
File lockerFile = new File(appPath);
|
|
|
|
|
lockerFile = new File(lockerFile, "data/alive");
|
|
|
|
|
try {
|
|
|
|
|
lockerFile.mkdirs();
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
lockerFile = new File(lockerFile, "running");
|
|
|
|
|
mAppRunningFile = new FileOutputStream(lockerFile);
|
|
|
|
|
|
|
|
|
|
for (int idx = 0; idx < 3; idx++) {
|
|
|
|
|
try {
|
|
|
|
|
mAppLock = mAppRunningFile.getChannel().tryLock();
|
|
|
|
|
if (mAppLock != null && mAppLock.isValid()) {
|
|
|
|
|
infoLog("App Locked");
|
|
|
|
|
break;
|
|
|
|
|
}else {
|
|
|
|
|
infoLog("Lock App Failed");
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
Thread.sleep(16);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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_UPDATE_CONFIGS);
|
|
|
|
|
intentFilter.addAction(ACTION_IMP_PUBKRY);
|
|
|
|
|
intentFilter.addAction(ACTION_TAKE_PHOTO_MANUALLY);
|
|
|
|
|
intentFilter.addAction(ACTION_CAMERA_CTRL);
|
|
|
|
|
intentFilter.addAction(ACTION_HEARTBEAT_MANUALLY);
|
|
|
|
|
intentFilter.addAction(ACTION_GPS_TIMEOUT);
|
|
|
|
|
intentFilter.addAction(ACTION_RESTART);
|
|
|
|
|
getApplicationContext().registerReceiver(mAlarmReceiver, intentFilter, Context.RECEIVER_EXPORTED | Context.RECEIVER_VISIBLE_TO_INSTANT_APPS);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
mLocalMsgReceiver = new AlarmReceiver(this);
|
|
|
|
|
IntentFilter intentFilter = new IntentFilter();
|
|
|
|
|
intentFilter.addAction(ACTION_HEARTBEAT);
|
|
|
|
|
intentFilter.addAction(ACTION_TAKE_PHOTO);
|
|
|
|
|
intentFilter.addAction(ACTION_TAKE_PHOTO_MANUALLY);
|
|
|
|
|
intentFilter.addAction(ACTION_HEARTBEAT_MANUALLY);
|
|
|
|
|
intentFilter.addAction(ACTION_MSG_BROADCAST);
|
|
|
|
|
intentFilter.addAction(ACTION_VIDEO_FINISHED);
|
|
|
|
|
intentFilter.addAction(ACTION_STOP);
|
|
|
|
|
intentFilter.addAction(ACTION_UPDATE_CONFIGS);
|
|
|
|
|
|
|
|
|
|
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver (mLocalMsgReceiver, intentFilter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
getApplicationContext().registerReceiver(mNetworkChangedReceiver, filter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(ALARM_SERVICE);
|
|
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
|
AlarmManager.AlarmClockInfo aci = alarmManager.getNextAlarmClock();
|
|
|
|
|
if (aci == null) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
enableGps(true);
|
|
|
|
|
requestPosition();
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public void onDestroy() {
|
|
|
|
|
try {
|
|
|
|
|
if (mAppLock != null) {
|
|
|
|
|
mAppLock.close();
|
|
|
|
|
}
|
|
|
|
|
if (mAppRunningFile != null) {
|
|
|
|
|
mAppRunningFile.close();
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mStateService = STATE_SERVICE.NOT_CONNECTED;
|
|
|
|
|
|
|
|
|
|
infoLog("MicroPhotoService::onDestroy called");
|
|
|
|
|
|
|
|
|
|
if (mNativeHandle != 0) {
|
|
|
|
|
uninit(mNativeHandle);
|
|
|
|
|
mNativeHandle = 0;
|
|
|
|
|
isRunning = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
getApplicationContext().unregisterReceiver(mAlarmReceiver);
|
|
|
|
|
getApplicationContext().unregisterReceiver(mScreenaAtionReceiver);
|
|
|
|
|
getApplicationContext().unregisterReceiver(mNetworkChangedReceiver);
|
|
|
|
|
|
|
|
|
|
if (mConnectivityManager != null) {
|
|
|
|
|
if (mNetworkCallback != null) {
|
|
|
|
|
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(mLocalMsgReceiver);
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
|
try {
|
|
|
|
|
ProcessReceivedAction(context, intent);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
private void restartSelfImpl(Context context, String reason) {
|
|
|
|
|
Intent intent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
|
|
|
|
|
int noDelay = 1;
|
|
|
|
|
intent.putExtra("noDelay", noDelay);
|
|
|
|
|
if (!TextUtils.isEmpty(reason)) {
|
|
|
|
|
intent.putExtra("reason", reason);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
|
|
|
context.startActivity(intent);
|
|
|
|
|
Log.i(TAG, "Restart Self");
|
|
|
|
|
System.exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ProcessReceivedAction(Context context, Intent intent) {
|
|
|
|
|
String action = intent.getAction();
|
|
|
|
|
if (TextUtils.equals(ACTION_HEARTBEAT, action)) {
|
|
|
|
|
long ts = System.currentTimeMillis();
|
|
|
|
|
long expectedHbTime = intent.getLongExtra("HeartbeatTime", ts);
|
|
|
|
|
|
|
|
|
|
infoLog("HB Timer Fired ACTION=" + action + " ExpTS=" + Long.toString(expectedHbTime));
|
|
|
|
|
Runnable runnable = new Runnable() {
|
|
|
|
|
public void run() {
|
|
|
|
|
mService.sendHeartbeat(mService.mNativeHandle, mService.getSignalLevel());
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
Thread th = new Thread(runnable);
|
|
|
|
|
th.start();
|
|
|
|
|
|
|
|
|
|
long nextHbTime = expectedHbTime + mService.mHeartbeatDuration;
|
|
|
|
|
while (nextHbTime <= ts) {
|
|
|
|
|
nextHbTime += mService.mHeartbeatDuration;
|
|
|
|
|
}
|
|
|
|
|
long timeout = (expectedHbTime != 0) ? (nextHbTime - System.currentTimeMillis()) : mService.mHeartbeatDuration;
|
|
|
|
|
mService.registerHeartbeatTimer(timeout);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
|
|
mService.detectGpsStatus();
|
|
|
|
|
|
|
|
|
|
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
|
|
|
|
if (connectivityManager != null) {
|
|
|
|
|
if (!connectivityManager.isDefaultNetworkActive()) {
|
|
|
|
|
infoLog("DefaultNetwork is NOT Active");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(MicroPhotoContext.PACKAGE_NAME_MPMASTER);
|
|
|
|
|
// launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
|
|
|
|
context.startActivity(launchIntent);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
} 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 & 0xFFFF000L) >> 12);
|
|
|
|
|
int preset = (int) ((val & 0xFF0L) >> 4);
|
|
|
|
|
int mediaType = (int)(val & 0xFL);
|
|
|
|
|
|
|
|
|
|
if (channel >= 256)
|
|
|
|
|
{
|
|
|
|
|
infoLog("SERIAL Timer Fired: CH=" + (channel - 256) + " PR=" + preset);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
infoLog("IMG Timer Fired: CH=" + channel + " PR=" + preset);
|
|
|
|
|
}
|
|
|
|
|
mService.notifyToTakePhoto(mService.mNativeHandle, channel, preset, ts, null, mediaType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Register Next Photo Timer
|
|
|
|
|
long startTime = (ts == 0) ? (((new Date()).getTime() + 999) / 1000 + 1) : (ts + 1); // Add one second
|
|
|
|
|
mService.updateCaptureSchedule(startTime);
|
|
|
|
|
} else if (TextUtils.equals(ACTION_HEARTBEAT_MANUALLY, action)) {
|
|
|
|
|
Log.i(TAG, "HB Timer Fired ACTION=" + action);
|
|
|
|
|
mService.sendHeartbeat(mService.mNativeHandle, mService.getSignalLevel());
|
|
|
|
|
} else if (TextUtils.equals(ACTION_TAKE_PHOTO_MANUALLY, action)) {
|
|
|
|
|
int channel = intent.getIntExtra(EXTRA_PARAM_CHANNEL, 0);
|
|
|
|
|
int preset = intent.getIntExtra(EXTRA_PARAM_PRESET, 0xFF);
|
|
|
|
|
String url = intent.getStringExtra(EXTRA_PARAM_URL);
|
|
|
|
|
// long ts = intent.getLongExtra(EXTRA_PARAM_TIME, 0);
|
|
|
|
|
|
|
|
|
|
int mediaType = 0;
|
|
|
|
|
if (intent.hasExtra(EXTRA_PARAM_MEDIA_TYPE)) {
|
|
|
|
|
mediaType = intent.getIntExtra(EXTRA_PARAM_MEDIA_TYPE, 0);
|
|
|
|
|
} else if (intent.hasExtra(EXTRA_PARAM_PHOTO_OR_VIDEO)) {
|
|
|
|
|
boolean photoOrVideo = intent.getBooleanExtra(EXTRA_PARAM_PHOTO_OR_VIDEO, true);
|
|
|
|
|
mediaType = photoOrVideo ? 0 : 1;
|
|
|
|
|
}
|
|
|
|
|
long ts = System.currentTimeMillis() / 1000;
|
|
|
|
|
|
|
|
|
|
Log.i(TAG, "Take Photo CH=" + channel + " PR=" + preset + " Mannually");
|
|
|
|
|
mService.notifyToTakePhoto(mService.mNativeHandle, channel, preset, 0, url, mediaType);
|
|
|
|
|
} else if (TextUtils.equals(ACTION_CAMERA_CTRL, action)) {
|
|
|
|
|
int channel = intent.getIntExtra("channel", 0);
|
|
|
|
|
int preset = intent.getIntExtra("preset", 0);
|
|
|
|
|
int cmd = intent.getIntExtra("cmd", 0);
|
|
|
|
|
mService.sendCameraCtrl(mService.mNativeHandle, channel, preset, cmd);
|
|
|
|
|
} else if (TextUtils.equals(ACTION_UPDATE_CONFIGS, action)) {
|
|
|
|
|
int restart = intent.getIntExtra("restart", 0);
|
|
|
|
|
Log.i(TAG, "UPD CFG Fired ACTION=" + action + " restart=" + restart);
|
|
|
|
|
if (restart != 0) {
|
|
|
|
|
restartSelfImpl(context, "Cfg Updated");
|
|
|
|
|
} else if (mService.mNativeHandle != 0) {
|
|
|
|
|
mService.reloadConfigs(mService.mNativeHandle);
|
|
|
|
|
}
|
|
|
|
|
} else if (TextUtils.equals(ACTION_VIDEO_FINISHED, action)) {
|
|
|
|
|
final boolean photoOrVideo = intent.getBooleanExtra("photoOrVideo", false);
|
|
|
|
|
final boolean result = intent.getBooleanExtra("result", false);
|
|
|
|
|
final String path = intent.getStringExtra("path");
|
|
|
|
|
final long videoId = intent.getLongExtra("videoId", 0);
|
|
|
|
|
final int orientation = intent.getIntExtra("orientation", 0);
|
|
|
|
|
final boolean frontCamera = intent.getBooleanExtra("frontCamera", false);
|
|
|
|
|
final int numberOfCaptures = intent.getIntExtra("captures", 1);
|
|
|
|
|
final List<String> paths = new ArrayList<>();
|
|
|
|
|
if (numberOfCaptures > 1) {
|
|
|
|
|
for (int idx = 0; idx < numberOfCaptures; idx++) {
|
|
|
|
|
String p = intent.getStringExtra("path" + Integer.toString(idx));
|
|
|
|
|
if (!TextUtils.isEmpty(p)) {
|
|
|
|
|
paths.add(p);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Log.i(TAG, "Recording received(" + Long.toString(videoId) + "):" + path);
|
|
|
|
|
|
|
|
|
|
if (photoOrVideo) {
|
|
|
|
|
Thread thread = new Thread(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
if (numberOfCaptures == 1) {
|
|
|
|
|
processCapture();
|
|
|
|
|
} else {
|
|
|
|
|
processCaptures();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void processCaptures() {
|
|
|
|
|
Bitmap bm = null;
|
|
|
|
|
File rawFile = new File(path);
|
|
|
|
|
|
|
|
|
|
String pathsStr = String.join("\t", paths);
|
|
|
|
|
mService.burstCaptureFinished(mService.mNativeHandle, result, numberOfCaptures, pathsStr, frontCamera, orientation, videoId);
|
|
|
|
|
for (String p : paths) {
|
|
|
|
|
try {
|
|
|
|
|
File f = new File(p);
|
|
|
|
|
f.delete();
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void processCapture() {
|
|
|
|
|
Bitmap bm = null;
|
|
|
|
|
File rawFile = new File(path);
|
|
|
|
|
try {
|
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
|
|
|
|
|
|
|
|
|
|
ImageDecoder.Source src = ImageDecoder.createSource(rawFile);
|
|
|
|
|
ImageDecoder.OnHeaderDecodedListener listener =
|
|
|
|
|
new ImageDecoder.OnHeaderDecodedListener(){
|
|
|
|
|
@Override
|
|
|
|
|
public void onHeaderDecoded(@NonNull ImageDecoder decoder, @NonNull ImageDecoder.ImageInfo info, @NonNull ImageDecoder.Source source) {
|
|
|
|
|
decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE);
|
|
|
|
|
// decoder.setTargetSize(info.getSize().getWidth(), info.getSize().getHeight());
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bm = ImageDecoder.decodeBitmap(src, listener);
|
|
|
|
|
} else {
|
|
|
|
|
bm = BitmapFactory.decodeFile(path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (orientation != 0 || frontCamera) {
|
|
|
|
|
Matrix matrix = new Matrix();
|
|
|
|
|
if (orientation != 0) {
|
|
|
|
|
matrix.postRotate(orientation);
|
|
|
|
|
}
|
|
|
|
|
if (frontCamera) {
|
|
|
|
|
matrix.postScale(-1, 1);
|
|
|
|
|
}
|
|
|
|
|
bm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true);
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
}
|
|
|
|
|
mService.captureFinished(mService.mNativeHandle, photoOrVideo, result && bm != null, bm, videoId);
|
|
|
|
|
try {
|
|
|
|
|
rawFile.delete();
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
thread.start();
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
mService.recordingFinished(mService.mNativeHandle, photoOrVideo, result, path, videoId);
|
|
|
|
|
}
|
|
|
|
|
} else if (TextUtils.equals(ACTION_STOP, action)) {
|
|
|
|
|
mService.stopTerminalService();
|
|
|
|
|
} else if (TextUtils.equals(ACTION_IMP_PUBKRY, action)) {
|
|
|
|
|
String path = intent.getStringExtra("path");
|
|
|
|
|
String md5 = intent.getStringExtra("md5");
|
|
|
|
|
} else if (TextUtils.equals(ACTION_GPS_TIMEOUT, action)) {
|
|
|
|
|
Log.i(TAG, action);
|
|
|
|
|
try {
|
|
|
|
|
mService.mLocationManager.removeUpdates(mService.mLocationListener);
|
|
|
|
|
Log.i(TAG, "After removeUpdates");
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
mService.enableGps(false);
|
|
|
|
|
Log.i(TAG, "After disable GPS");
|
|
|
|
|
mService.mPreviousGpsTimer = null;
|
|
|
|
|
} else if (TextUtils.equals(ACTION_RESTART, action)) {
|
|
|
|
|
String reason = intent.getStringExtra("reason");
|
|
|
|
|
MicroPhotoService.infoLog("Recv RESTART APP cmd, reason=" + (TextUtils.isEmpty(reason) ? "" : reason));
|
|
|
|
|
try {
|
|
|
|
|
Thread.sleep(100);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
restartSelfImpl(context, reason);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Will be called fron native
|
|
|
|
|
private void registerHeartbeatTimer(int duration, long nextPhotoTime) {
|
|
|
|
|
int orgHeartbeatDuration = mHeartbeatDuration;
|
|
|
|
|
|
|
|
|
|
if (orgHeartbeatDuration == 0) {
|
|
|
|
|
if (nextPhotoTime == 0) {
|
|
|
|
|
mHeartbeatDuration = duration;
|
|
|
|
|
registerHeartbeatTimer(duration);
|
|
|
|
|
} else {
|
|
|
|
|
long ts = System.currentTimeMillis();
|
|
|
|
|
nextPhotoTime *= 1000;
|
|
|
|
|
if (nextPhotoTime > ts) {
|
|
|
|
|
mHeartbeatDuration = duration;
|
|
|
|
|
registerHeartbeatTimer((int) ((nextPhotoTime - ts) % duration));
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
mHeartbeatDuration = duration;
|
|
|
|
|
registerHeartbeatTimer(duration);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
mHeartbeatDuration = duration;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void registerHeartbeatTimer(long timeoutMs) {
|
|
|
|
|
|
|
|
|
|
// 创建延迟意图
|
|
|
|
|
long triggerTime = System.currentTimeMillis() + timeoutMs;
|
|
|
|
|
triggerTime -= (triggerTime % 1000);
|
|
|
|
|
Intent alarmIntent = new Intent();
|
|
|
|
|
alarmIntent.setAction(ACTION_HEARTBEAT);
|
|
|
|
|
alarmIntent.putExtra("HeartbeatDuration", mHeartbeatDuration);
|
|
|
|
|
alarmIntent.putExtra("HeartbeatTime", triggerTime);
|
|
|
|
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, BROADCAST_REQUEST_CODE_HEARTBEAT, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
|
|
|
|
|
|
|
|
Date date = new Date(triggerTime);
|
|
|
|
|
String dateStr = (String) DateFormat.format("kk:mm:ss", date);
|
|
|
|
|
infoLog( "HB Reg " + Long.toString(triggerTime) + " at " + dateStr);
|
|
|
|
|
|
|
|
|
|
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
|
|
|
|
|
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void registerPhotoTimer(Context context, long scheduleTime, long takingTime, long timeout, List<Long> schedules) {
|
|
|
|
|
|
|
|
|
|
// 创建延迟意图
|
|
|
|
|
Intent intent = new Intent();
|
|
|
|
|
intent.setAction(ACTION_TAKE_PHOTO);
|
|
|
|
|
int cnt = schedules.size();
|
|
|
|
|
intent.putExtra(EXTRA_PARAM_SCHEDULES, cnt);
|
|
|
|
|
StringBuilder channelStr = new StringBuilder();
|
|
|
|
|
long val = 0;
|
|
|
|
|
long channel = 0;
|
|
|
|
|
for (int idx = 0; idx < cnt; idx++) {
|
|
|
|
|
val = schedules.get(idx).longValue();
|
|
|
|
|
channel = ((val & 0XFFFF000) >> 12);
|
|
|
|
|
intent.putExtra(EXTRA_PARAM_SCHEDULE + idx, schedules.get(idx).longValue());
|
|
|
|
|
if (channel > 0xFF)
|
|
|
|
|
{
|
|
|
|
|
channel &= 0xFF;
|
|
|
|
|
channelStr.append("(" + channel + "-" + Long.toString (((val & 0XFF0) >> 4), 16).toUpperCase() + "/SERIAL) ");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
channelStr.append("(" + channel + "-" + Long.toString (((val & 0XFF0) >> 4), 16).toUpperCase() + "/IMG) ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
intent.putExtra(EXTRA_PARAM_TIME, scheduleTime);
|
|
|
|
|
intent.putExtra(EXTRA_PARAM_TAKING_TIME, takingTime);
|
|
|
|
|
|
|
|
|
|
if (timeout == 0) {
|
|
|
|
|
// LocalBroadcast
|
|
|
|
|
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
|
|
|
|
|
localBroadcastManager.sendBroadcast(intent);
|
|
|
|
|
} else {
|
|
|
|
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, BROADCAST_REQUEST_CODE_TAKING_PHOTO, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
|
|
|
|
|
|
|
|
AlarmManager alarmManager = (AlarmManager) context.getSystemService(ALARM_SERVICE);
|
|
|
|
|
try {
|
|
|
|
|
alarmManager.cancel(pendingIntent);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + timeout, pendingIntent);
|
|
|
|
|
|
|
|
|
|
long currentTimeMillis = System.currentTimeMillis();
|
|
|
|
|
Date date = new Date(currentTimeMillis + timeout);
|
|
|
|
|
String dateStr = (String) DateFormat.format("MM-dd kk:mm:ss", date);
|
|
|
|
|
infoLog( "Timer Reg: " + dateStr + " TS=" + currentTimeMillis + " Timeout=" + timeout + " " + channelStr.toString());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void registerPhotoTimer(long scheduleTime, long timeout, List<Long> schedules) {
|
|
|
|
|
|
|
|
|
|
registerPhotoTimer(getApplicationContext(), scheduleTime, scheduleTime, timeout, schedules);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// From Native
|
|
|
|
|
public void startRecording(boolean photoOrVideo, int cameraId, long videoId, int duration, int width, int height, int quality, int orientation, String leftTopOsd, String rightTopOsd, String rightBottomOsd, String leftBottomOsd) {
|
|
|
|
|
Context context = getApplicationContext();
|
|
|
|
|
|
|
|
|
|
Intent intent = makeRecordingIntent(context, photoOrVideo, cameraId, videoId, duration, width, height, quality, orientation,
|
|
|
|
|
leftTopOsd, rightTopOsd, rightBottomOsd, leftBottomOsd, null);
|
|
|
|
|
|
|
|
|
|
intent.putExtra("resultType", 2);
|
|
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
|
|
|
|
|
|
|
context.startActivity(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static Intent makeRecordingIntent(Context context, boolean photoOrVideo, int cameraId, long videoId, int duration, int width, int height, int quality, int orientation, String leftTopOsd, String rightTopOsd, String rightBottomOsd, String leftBottomOsd, String path) {
|
|
|
|
|
// Intent intent = new Intent(this, VideoActivity.class);
|
|
|
|
|
Intent intent = photoOrVideo ? new Intent(context, RawActivity.class) : new Intent(context, Camera2VideoActivity.class);
|
|
|
|
|
|
|
|
|
|
intent.putExtra("cameraId", cameraId);
|
|
|
|
|
intent.putExtra("videoId", videoId);
|
|
|
|
|
if (!TextUtils.isEmpty(path)) {
|
|
|
|
|
intent.putExtra("path", path);
|
|
|
|
|
}
|
|
|
|
|
intent.putExtra("duration", duration);
|
|
|
|
|
intent.putExtra("width", width);
|
|
|
|
|
intent.putExtra("height", height);
|
|
|
|
|
intent.putExtra("quality", quality);
|
|
|
|
|
intent.putExtra("orientation", orientation);
|
|
|
|
|
intent.putExtra("leftTopOsd", leftTopOsd);
|
|
|
|
|
intent.putExtra("rightTopOsd", rightTopOsd);
|
|
|
|
|
intent.putExtra("rightBottomOsd", rightBottomOsd);
|
|
|
|
|
intent.putExtra("leftBottomOsd", leftBottomOsd);
|
|
|
|
|
|
|
|
|
|
String tmpPath = MicroPhotoContext.buildMpAppDir(context);
|
|
|
|
|
tmpPath += "tmp";
|
|
|
|
|
intent.putExtra("cameraTmpPath", tmpPath);
|
|
|
|
|
|
|
|
|
|
if (photoOrVideo) {
|
|
|
|
|
intent.putExtra("burstCaptures", 8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
|
|
|
|
|
|
|
return intent;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected boolean updateCaptureSchedule(long startTime) {
|
|
|
|
|
|
|
|
|
|
long[] photoTimeData = getPhotoTimeData(mNativeHandle, startTime);
|
|
|
|
|
if (photoTimeData == null || photoTimeData.length < 4) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// int maxDuration = 35 * 60 * 1000 + 1000;
|
|
|
|
|
List<Long> schedules = new ArrayList<>();
|
|
|
|
|
for (int idx = 0; idx < photoTimeData[2]; idx++) {
|
|
|
|
|
schedules.add(Long.valueOf(photoTimeData[3 + idx]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (schedules.isEmpty()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long expectedTs = photoTimeData[0] + photoTimeData[1];
|
|
|
|
|
|
|
|
|
|
registerPhotoTimer(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 << 12);
|
|
|
|
|
val |= ((long)preset << 4);
|
|
|
|
|
val |= photoOrVideo ? 0L : 1L;
|
|
|
|
|
|
|
|
|
|
schedules.add(Long.valueOf(val));
|
|
|
|
|
|
|
|
|
|
registerPhotoTimer(context, 0, ts, 0, schedules);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void sendHeartbeat(Context context) {
|
|
|
|
|
Intent intent = new Intent();
|
|
|
|
|
intent.setAction(ACTION_HEARTBEAT_MANUALLY);
|
|
|
|
|
// PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
|
|
|
|
|
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
|
|
|
|
|
localBroadcastManager.sendBroadcast(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void updateConfigs(Context context) {
|
|
|
|
|
Intent intent = new Intent();
|
|
|
|
|
intent.setAction(ACTION_UPDATE_CONFIGS);
|
|
|
|
|
// PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
|
|
|
|
|
LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);
|
|
|
|
|
localBroadcastManager.sendBroadcast(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@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();
|
|
|
|
|
|
|
|
|
|
getApplicationContext().registerReceiver(mScreenaAtionReceiver, mScreenaAtionReceiver.getFilter());
|
|
|
|
|
if (intent.hasExtra("messenger")) {
|
|
|
|
|
mMessenger = intent.getParcelableExtra("messenger");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int network = intent.getIntExtra("network", 0);
|
|
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
try {
|
|
|
|
|
getApplicationContext().unregisterReceiver(mScreenaAtionReceiver);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
stopForeground(true);
|
|
|
|
|
stopSelf();
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
stopForeground(true);
|
|
|
|
|
stopSelf();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return START_NOT_STICKY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long getDefaultNetworkHandle() {
|
|
|
|
|
long defaultNetHandle = 0;
|
|
|
|
|
if (mConnectivityManager != null) {
|
|
|
|
|
Network network = mConnectivityManager.getActiveNetwork();
|
|
|
|
|
if (network != null) {
|
|
|
|
|
NetworkInfo networkInfo = mConnectivityManager.getNetworkInfo(network);
|
|
|
|
|
int type = networkInfo.getType();
|
|
|
|
|
if (type == ConnectivityManager.TYPE_MOBILE || type == ConnectivityManager.TYPE_VPN ||
|
|
|
|
|
type == ConnectivityManager.TYPE_MOBILE_DUN || type == ConnectivityManager.TYPE_MOBILE_HIPRI) {
|
|
|
|
|
defaultNetHandle = network.getNetworkHandle();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return defaultNetHandle;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void startTerminalService(Intent intent) {
|
|
|
|
|
|
|
|
|
|
if (MicroPhotoService.this.mNativeHandle != 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final String appPath = MicroPhotoContext.buildAppDir(this.getApplicationContext());
|
|
|
|
|
|
|
|
|
|
final String server = intent.getStringExtra("server");
|
|
|
|
|
final int port = intent.getIntExtra("port", 0);
|
|
|
|
|
final String cmdid = intent.getStringExtra("cmdid");
|
|
|
|
|
final int protocol = intent.getIntExtra("protocol", 0);
|
|
|
|
|
final int networkProtocol = intent.getIntExtra("networkProtocol", 0);
|
|
|
|
|
final int encryptData = intent.getIntExtra("encryption", 0);
|
|
|
|
|
|
|
|
|
|
Runnable runnable = new Runnable() {
|
|
|
|
|
public void run() {
|
|
|
|
|
|
|
|
|
|
String ip = server;
|
|
|
|
|
if (!NetworkUtils.isIPv4Address(ip) && !NetworkUtils.isIPv6Address(ip)) {
|
|
|
|
|
// It is a domain
|
|
|
|
|
InetAddress addr = null;
|
|
|
|
|
try {
|
|
|
|
|
addr = InetAddress.getByName(server);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
if (addr != null) {
|
|
|
|
|
ip = addr.getHostAddress();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Log.i(TAG, "AppPath=" + appPath + " Server=" + ip + ":" + port + " cmdid=" + cmdid + " Protocol=" + protocol + " Network=" + networkProtocol);
|
|
|
|
|
|
|
|
|
|
MicroPhotoService service = MicroPhotoService.this;
|
|
|
|
|
|
|
|
|
|
Context context = service.getApplicationContext();
|
|
|
|
|
int versionCode = MicroPhotoContext.getVersionCode(context);
|
|
|
|
|
String simcard = SysApi.getImei(getApplicationContext());
|
|
|
|
|
if (simcard == null) {
|
|
|
|
|
simcard = "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String tfCardPath = MicroPhotoContext.getSecondaryStoragePath(context);
|
|
|
|
|
String nativeLibraryDir = null;
|
|
|
|
|
ApplicationInfo applicationInfo = null;
|
|
|
|
|
try {
|
|
|
|
|
applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_SHARED_LIBRARY_FILES);
|
|
|
|
|
nativeLibraryDir = applicationInfo.nativeLibraryDir;
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
long defaultNetHandle = service.getDefaultNetworkHandle();
|
|
|
|
|
service.mNativeHandle = init(appPath, server, port, cmdid, protocol, networkProtocol,
|
|
|
|
|
encryptData, defaultNetHandle, service.getSignalLevel(), versionCode,
|
|
|
|
|
BuildConfig.BUILD_TIMESTAMP, simcard, tfCardPath, nativeLibraryDir);
|
|
|
|
|
|
|
|
|
|
if (service.mNativeHandle != 0) {
|
|
|
|
|
isRunning = true;
|
|
|
|
|
service.mCmdid = cmdid;
|
|
|
|
|
|
|
|
|
|
Date date = new Date();
|
|
|
|
|
long startTime = (date.getTime() + 999) / 1000;
|
|
|
|
|
service.updateCaptureSchedule(startTime);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (usingEthernet()) {
|
|
|
|
|
mNetworkCallback = new ConnectivityManager.NetworkCallback() {
|
|
|
|
|
@Override
|
|
|
|
|
public void onLost(Network network) {
|
|
|
|
|
infoLog("Network Lost " + network.toString());
|
|
|
|
|
updateEhernet(mNativeHandle, network.getNetworkHandle(), false);
|
|
|
|
|
updateDefaultNetwork();
|
|
|
|
|
}
|
|
|
|
|
@Override
|
|
|
|
|
public void onAvailable(final Network network) {
|
|
|
|
|
String ip = "";
|
|
|
|
|
try {
|
|
|
|
|
NetworkInfo ni = mConnectivityManager.getNetworkInfo(network);
|
|
|
|
|
LinkProperties lp = mConnectivityManager.getLinkProperties(network);
|
|
|
|
|
if (lp != null) {
|
|
|
|
|
List<LinkAddress> addresses = lp.getLinkAddresses();
|
|
|
|
|
if (addresses != null && addresses.size() > 0) {
|
|
|
|
|
for (LinkAddress linkAddress : addresses) {
|
|
|
|
|
InetAddress inetAddress = linkAddress.getAddress();
|
|
|
|
|
if (inetAddress != null && inetAddress instanceof Inet4Address) {
|
|
|
|
|
ip = inetAddress.getHostAddress();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
infoLog("Network Available " + network.toString() + " IP=" + ip + " Handle=" + Long.toString(network.getNetworkHandle()));
|
|
|
|
|
updateEhernet(mNativeHandle, network.getNetworkHandle(), true);
|
|
|
|
|
updateDefaultNetwork();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void updateDefaultNetwork() {
|
|
|
|
|
MicroPhotoService thisService = MicroPhotoService.this;
|
|
|
|
|
long defaultNetHandle = thisService.getDefaultNetworkHandle();
|
|
|
|
|
if (defaultNetHandle != 0) {
|
|
|
|
|
thisService.updateActiveNetwork(thisService.mNativeHandle, defaultNetHandle, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
NetworkRequest request = new NetworkRequest.Builder()
|
|
|
|
|
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
|
|
|
|
|
.build();
|
|
|
|
|
|
|
|
|
|
mConnectivityManager.registerNetworkCallback(request, mNetworkCallback);
|
|
|
|
|
|
|
|
|
|
Network[] nws = mConnectivityManager.getAllNetworks();
|
|
|
|
|
for (Network nw : nws) {
|
|
|
|
|
NetworkInfo ni = mConnectivityManager.getNetworkInfo(nw);
|
|
|
|
|
if (ni.getType() == ConnectivityManager.TYPE_ETHERNET) {
|
|
|
|
|
updateEhernet(mNativeHandle, nw.getNetworkHandle(), true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (mPreviousLocation != null) {
|
|
|
|
|
service.updatePosition(mNativeHandle, mPreviousLocation.getLongitude(), mPreviousLocation.getLatitude(),
|
|
|
|
|
mPreviousLocation.getAccuracy(), mPreviousLocation.getTime() / 1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
try {
|
|
|
|
|
Location location = mLocationManager.getLastKnownLocation(mLocateType);
|
|
|
|
|
if (location != null) {
|
|
|
|
|
service.updatePosition(service.mNativeHandle, location.getLongitude(), location.getLatitude(), location.getAccuracy(), location.getTime() / 1000);
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Log.d(TAG, "Start Service from MicroPhotoService");
|
|
|
|
|
Thread th = new Thread(runnable);
|
|
|
|
|
th.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void stopTerminalService(Context context) {
|
|
|
|
|
|
|
|
|
|
Intent alarmIntent = new Intent();
|
|
|
|
|
|
|
|
|
|
alarmIntent.setPackage(context.getPackageName());
|
|
|
|
|
alarmIntent.setAction(ACTION_STOP);
|
|
|
|
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), BROADCAST_REQUEST_CODE_STOP_SERVICE, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
|
|
|
|
|
|
|
|
|
AlarmManager alarmManager = (AlarmManager) context.getApplicationContext().getSystemService(ALARM_SERVICE);
|
|
|
|
|
alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 100, pendingIntent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void stopTerminalService() {
|
|
|
|
|
|
|
|
|
|
if (mNativeHandle == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Runnable runnable = new Runnable() {
|
|
|
|
|
public void run() {
|
|
|
|
|
uninit(mNativeHandle);
|
|
|
|
|
mNativeHandle = 0;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
getApplicationContext().unregisterReceiver(mScreenaAtionReceiver);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
stopForeground(true);
|
|
|
|
|
stopSelf();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
Thread thread = new Thread(runnable);
|
|
|
|
|
thread.start();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
mHander.removeCallbacks(delayedSleep);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
// ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
if (mWakeLocks.isEmpty()) {
|
|
|
|
|
// mHander.postDelayed(delayedSleep, 2000);
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (wl != null) {
|
|
|
|
|
Log.i(TAG, "Release wakelock:" + name);
|
|
|
|
|
try {
|
|
|
|
|
final PowerManager.WakeLock finalWl = wl;
|
|
|
|
|
wl = null;
|
|
|
|
|
mHander.postDelayed(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
try {
|
|
|
|
|
finalWl.setReferenceCounted(false);
|
|
|
|
|
finalWl.release();
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}, 200);
|
|
|
|
|
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 toast = Toast.makeText(getApplicationContext(), "MP Connected!", Toast.LENGTH_SHORT);
|
|
|
|
|
toast.setGravity(Gravity.TOP, 0, 0);
|
|
|
|
|
toast.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.drawable.ic_notification_mp)
|
|
|
|
|
.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(android.location.LocationManager.GPS_PROVIDER)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mLocateType = mLocationManager.GPS_PROVIDER;
|
|
|
|
|
// Set Listener
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
enableGps(true);
|
|
|
|
|
mLastLocationRequested = System.currentTimeMillis();
|
|
|
|
|
mLocationManager.requestLocationUpdates(mLocateType, 30000, 1, mLocationListener, Looper.getMainLooper());
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Location location = mLocationManager.getLastKnownLocation(mLocateType);
|
|
|
|
|
if (location != null && mNativeHandle != 0) {
|
|
|
|
|
updatePosition(mNativeHandle, location.getLongitude(), location.getLatitude(), location.getAccuracy(), location.getTime() / 1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
} catch (SecurityException ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void detectGpsStatus() {
|
|
|
|
|
if (System.currentTimeMillis() - mLastLocationRequested > 10 * 60000) {
|
|
|
|
|
// 10minutes close it
|
|
|
|
|
enableGps(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();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected int getSignalLevel() {
|
|
|
|
|
try {
|
|
|
|
|
final TelephonyManager telephonyManager = (TelephonyManager) getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
|
|
|
|
|
SignalStrength ss = telephonyManager.getSignalStrength();
|
|
|
|
|
|
|
|
|
|
if (ss != null) {
|
|
|
|
|
return ss.getLevel();
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
}
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public String getFlowInfo() {
|
|
|
|
|
|
|
|
|
|
Date dt = new Date();
|
|
|
|
|
dt.setDate(1);
|
|
|
|
|
dt.setHours(0);
|
|
|
|
|
dt.setMinutes(0);
|
|
|
|
|
dt.setSeconds(0);
|
|
|
|
|
|
|
|
|
|
long startTime = dt.getTime();
|
|
|
|
|
if (dt.getMonth() == 12) {
|
|
|
|
|
dt.setYear(dt.getYear() + 1);
|
|
|
|
|
dt.setMonth(1);
|
|
|
|
|
} else {
|
|
|
|
|
dt.setMonth(dt.getMonth() + 1);
|
|
|
|
|
}
|
|
|
|
|
long endTime = dt.getTime() - 1;
|
|
|
|
|
NetworkUtils.Usage usage = NetworkUtils.getApplicationQuerySummary(this.getApplicationContext(), startTime, endTime, getApplicationInfo().uid);
|
|
|
|
|
|
|
|
|
|
return "RX=" + Long.toString(usage.mobleRxBytes) + "&TX=" + Long.toString(usage.mobleTxBytes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean installApp(final String path, long delayedTime) {
|
|
|
|
|
if (delayedTime < 0) {
|
|
|
|
|
delayedTime = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
final Context context = getApplicationContext();
|
|
|
|
|
Runnable runnable = new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
SysApi.installApk(context, path, context.getPackageName(), true);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
mHander.postDelayed(runnable, delayedTime);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void reboot(final int rebootType, final long timeout, final String reason) {
|
|
|
|
|
|
|
|
|
|
Runnable runnable = new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
if (rebootType == 0) {
|
|
|
|
|
Context context = MicroPhotoService.this.getApplicationContext();
|
|
|
|
|
restartSelf(context, reason);
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
Log.w(TAG, "Recv REBOOT command");
|
|
|
|
|
SysApi.reboot(MicroPhotoService.this.getApplicationContext());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
mHander.postDelayed(runnable, timeout > 0 ? timeout : 1000);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void restartSelf(Context context, String reason) {
|
|
|
|
|
|
|
|
|
|
Intent intent = new Intent();
|
|
|
|
|
intent.setAction(ACTION_RESTART);
|
|
|
|
|
intent.setPackage(context.getPackageName());
|
|
|
|
|
intent.putExtra("noDelay", 1);
|
|
|
|
|
intent.putExtra("reason", reason);
|
|
|
|
|
intent.putExtra("packageName", context.getPackageName());
|
|
|
|
|
context.sendBroadcast(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void enableGps(boolean enabled) {
|
|
|
|
|
if (enabled) {
|
|
|
|
|
try {
|
|
|
|
|
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
|
|
|
|
|
if (mPreviousGpsTimer != null) {
|
|
|
|
|
alarmManager.cancel(mPreviousGpsTimer);
|
|
|
|
|
mPreviousGpsTimer = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Intent intent = new Intent();
|
|
|
|
|
intent.setAction(ACTION_GPS_TIMEOUT);
|
|
|
|
|
mPreviousGpsTimer = PendingIntent.getBroadcast(this, BROADCAST_REQUEST_CODE_GPS, intent, 0);
|
|
|
|
|
|
|
|
|
|
alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + mGpsTimeout, mPreviousGpsTimer);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (mPreviousGpsTimer != null) {
|
|
|
|
|
try {
|
|
|
|
|
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
|
|
|
|
|
alarmManager.cancel(mPreviousGpsTimer);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
} finally {
|
|
|
|
|
mPreviousGpsTimer = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SysApi.enableGps(getApplicationContext(), enabled);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int execHdrplus(int rotation, int frontCamera, String outputPath, String pathsWithSpace) {
|
|
|
|
|
|
|
|
|
|
ApplicationInfo applicationInfo = null;
|
|
|
|
|
Context context = getApplicationContext();
|
|
|
|
|
try {
|
|
|
|
|
applicationInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_SHARED_LIBRARY_FILES);
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String exeFilePath = applicationInfo.nativeLibraryDir + '/' + "libhdrp.so";
|
|
|
|
|
File hdrpFile = new File(exeFilePath);
|
|
|
|
|
if (!hdrpFile.exists()) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String cmd = exeFilePath + " " + Integer.toString(rotation) + " ";
|
|
|
|
|
cmd += Integer.toString(frontCamera) + " ";
|
|
|
|
|
cmd += outputPath + " " + pathsWithSpace;
|
|
|
|
|
|
|
|
|
|
String[] params = new String[]{""};
|
|
|
|
|
File workDir = context.getFilesDir();
|
|
|
|
|
int exitCode = -1;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
Process process = Runtime.getRuntime().exec(cmd, params, workDir.getAbsoluteFile());
|
|
|
|
|
// Intrinsics.checkNotNullExpressionValue(process, "process");
|
|
|
|
|
InputStream inputStream = process.getInputStream();
|
|
|
|
|
BufferedReader reader = new BufferedReader((Reader)(new InputStreamReader(inputStream)));
|
|
|
|
|
|
|
|
|
|
// StringBuilder stringBuilder = new StringBuilder();
|
|
|
|
|
while(true) {
|
|
|
|
|
String line = reader.readLine();
|
|
|
|
|
if (line == null) {
|
|
|
|
|
exitCode = process.exitValue();
|
|
|
|
|
reader.close();
|
|
|
|
|
process.destroy();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (line != null) {
|
|
|
|
|
// this.outputCallback.invoke(var5);
|
|
|
|
|
Log.d("HDRPlus", line);
|
|
|
|
|
// stringBuilder.append(line);
|
|
|
|
|
// stringBuilder.append("\r\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} catch (Exception ex) {
|
|
|
|
|
ex.printStackTrace();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return exitCode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setStaticNetwork(String iface, String ip, String netmask, String gateway)
|
|
|
|
|
{
|
|
|
|
|
if (!TextUtils.equals("0.0.0.0", ip)) {
|
|
|
|
|
Intent intent = new Intent();
|
|
|
|
|
intent.putExtra("cmd", "setnet");
|
|
|
|
|
intent.putExtra("staticip", true);
|
|
|
|
|
intent.putExtra("iface", iface);
|
|
|
|
|
intent.putExtra("ip", ip);
|
|
|
|
|
intent.putExtra("netmask", netmask);
|
|
|
|
|
if (!TextUtils.isEmpty(gateway)) {
|
|
|
|
|
intent.putExtra("gateway", gateway);
|
|
|
|
|
}
|
|
|
|
|
intent.putExtra("dns1", "0.0.0.0");
|
|
|
|
|
intent.putExtra("dns2", "0.0.0.0");
|
|
|
|
|
sendBroadcast(getApplicationContext(), intent);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void sendBroadcast(Context context, Intent intent)
|
|
|
|
|
{
|
|
|
|
|
intent.setAction("com.xy.xsetting.action");
|
|
|
|
|
intent.setPackage("com.android.systemui");
|
|
|
|
|
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
|
|
|
|
|
context.sendBroadcast(intent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
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, int encryptData, long netHandle, int signalLevel,
|
|
|
|
|
int versionCode, long buildTime, String simcard, String tfCardPath, String nativeLibraryDir);
|
|
|
|
|
protected native long getHeartbeatDuration(long handler);
|
|
|
|
|
protected native long[] getPhotoTimeData(long handler, long startTime);
|
|
|
|
|
protected native long[] getPhotoTimeData2(long handler);
|
|
|
|
|
// protected native long[] getNextScheduleItem(long handler);
|
|
|
|
|
protected native boolean notifyToTakePhoto(long handler, int channel, int preset, long scheduleTime, String url, int mediaType);
|
|
|
|
|
|
|
|
|
|
protected native boolean sendHeartbeat(long handler, int signalLevel);
|
|
|
|
|
protected native boolean reloadConfigs(long handler);
|
|
|
|
|
protected native void updatePosition(long handler, double lon, double lat, double radius, long ts);
|
|
|
|
|
protected native boolean updateEhernet(long handler, long nativeNetworkHandle, boolean available);
|
|
|
|
|
protected native boolean updateActiveNetwork(long handler, long nativeNetworkHandle, boolean available);
|
|
|
|
|
protected native boolean uninit(long handler);
|
|
|
|
|
protected native void recordingFinished(long handler, boolean photoOrVideo, boolean result, String path, long videoId);
|
|
|
|
|
protected native void captureFinished(long handler, boolean photoOrVideo, boolean result, Bitmap bm, long videoId);
|
|
|
|
|
protected native void burstCaptureFinished(long handler, boolean result, int numberOfCaptures, String pathsJoinedByTab, boolean frontCamera, int rotation, long photoId);
|
|
|
|
|
|
|
|
|
|
public static native long takePhoto(int channel, int preset, boolean photoOrVideo, String configFilePath, String path);
|
|
|
|
|
|
|
|
|
|
protected native void sendCameraCtrl(long handler, int channel, int preset, int cmd);
|
|
|
|
|
|
|
|
|
|
public static native void releaseDeviceHandle(long deviceHandle);
|
|
|
|
|
public static native boolean sendExternalPhoto(long deviceHandle, String path, long photoInfo);
|
|
|
|
|
public static native void infoLog(String log);
|
|
|
|
|
|
|
|
|
|
public static native boolean usingEthernet();
|
|
|
|
|
|
|
|
|
|
public static native void setOtgState(boolean enabled);
|
|
|
|
|
public static native void setCam3V3Enable(boolean enabled);
|
|
|
|
|
public static native String getSerialNumber();
|
|
|
|
|
public static native boolean importPublicKeyFile(int index, String outputPath, String md5);
|
|
|
|
|
public static native boolean importPublicKey(int index, byte cert[]);
|
|
|
|
|
public static native boolean importPrivateKey(int index, byte cert[]);
|
|
|
|
|
public static native boolean genKeys(int index);
|
|
|
|
|
|
|
|
|
|
public native static int getGpioInt(int cmd);
|
|
|
|
|
|
|
|
|
|
public static native int[] recoganizePicture(String paramPath, String binPath, String blobName8, String blobName16, String blobName32, String picPath);
|
|
|
|
|
public static native String querySecVersion();
|
|
|
|
|
public static native boolean genCertRequest(int index, int type, String subject, String outputPath);
|
|
|
|
|
public static native boolean importPrivateKeyFile(int index, String outputPath, String md5);
|
|
|
|
|
public static native boolean exportPublicKeyFile(int index, String outputPath);
|
|
|
|
|
public static native boolean exportPrivateFile(int index, String outputPath);
|
|
|
|
|
|
|
|
|
|
public static native long requestPowerControl(int type);
|
|
|
|
|
public static native boolean releasePowerControl(long powerControlHandle);
|
|
|
|
|
|
|
|
|
|
public static native int getCustomAppId();
|
|
|
|
|
|
|
|
|
|
////////////////////////GPS////////////////////
|
|
|
|
|
// private static final String GPS_LOCATION_NAME = android.location.LocationManager.GPS_PROVIDER;
|
|
|
|
|
private LocationManager mLocationManager;
|
|
|
|
|
private Location mPreviousLocation = null;
|
|
|
|
|
private String mLocateType;
|
|
|
|
|
|
|
|
|
|
private LocationListener mLocationListener = new LocationListener() {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void onLocationChanged(Location location) {
|
|
|
|
|
|
|
|
|
|
if (mNativeHandle != 0) {
|
|
|
|
|
updatePosition(mNativeHandle, location.getLongitude(), location.getLatitude(), location.getAccuracy(), location.getTime() / 1000);
|
|
|
|
|
} else {
|
|
|
|
|
mPreviousLocation = location;
|
|
|
|
|
}
|
|
|
|
|
mLocationManager.removeUpdates(this);
|
|
|
|
|
// Close GPS
|
|
|
|
|
enableGps(false);
|
|
|
|
|
Log.i(TAG, "Time:" + location.getTime() + " Lon=" + location.getLongitude() + "Lat=" + location.getLatitude() + "Alt=" + 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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void callSystemCamera(final int cameraId, final long photoId) {
|
|
|
|
|
Context context = getApplicationContext();
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Intent intent = null;
|
|
|
|
|
if (cameraId == 1) {
|
|
|
|
|
|
|
|
|
|
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
|
|
|
|
|
|
|
|
|
intent.putExtra("android.intent.extras.CAMERA_FACING", android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT);
|
|
|
|
|
|
|
|
|
|
intent.putExtra("android.intent.extras.LENS_FACING_FRONT", 1);
|
|
|
|
|
|
|
|
|
|
intent.putExtra("android.intent.extra.USE_FRONT_CAMERA", true);
|
|
|
|
|
|
|
|
|
|
} else{
|
|
|
|
|
intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String appPath = MicroPhotoContext.buildMpAppDir(context);
|
|
|
|
|
File targetPath = new File(new File(appPath), "tmp/" + Long.toString(photoId) + ".jpg");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Uri uri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", targetPath);
|
|
|
|
|
|
|
|
|
|
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(targetPath));
|
|
|
|
|
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
|
|
|
|
|
|
|
|
if (intent.resolveActivity(getPackageManager()) != null) {
|
|
|
|
|
startActivity(intent);
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
final CameraAdb cameraAdb = new CameraAdb(context, MicroPhotoContext.buildMpAppDir(context));
|
|
|
|
|
|
|
|
|
|
cameraAdb.setCallback(new Runnable() {
|
|
|
|
|
@Override
|
|
|
|
|
public void run() {
|
|
|
|
|
List<String> targetPaths = cameraAdb.getTargetPaths();
|
|
|
|
|
if (targetPaths.isEmpty()) {
|
|
|
|
|
recordingFinished(mNativeHandle, true, false, null, photoId);
|
|
|
|
|
} else {
|
|
|
|
|
for (String targetPath : targetPaths) {
|
|
|
|
|
recordingFinished(mNativeHandle, true, true, targetPath, photoId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
cameraAdb.takePhoto(cameraId);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
////////////////////////GPS////////////////////
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|