diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt index d654663b..ce4ceccd 100644 --- a/app/src/main/cpp/CMakeLists.txt +++ b/app/src/main/cpp/CMakeLists.txt @@ -190,6 +190,7 @@ add_library( # Sets the name of the library. ${TERM_CORE_ROOT}/SpecData.cpp ${TERM_CORE_ROOT}/SpecData_I1.cpp ${TERM_CORE_ROOT}/SpecData_I1_AH.cpp + ${TERM_CORE_ROOT}/SpecData_I1_JS.cpp ${TERM_CORE_ROOT}/SpecData_I1_HN.cpp ${TERM_CORE_ROOT}/SpecData_I1_HEN.cpp ${TERM_CORE_ROOT}/SpecData_I1_SHX.cpp diff --git a/app/src/main/cpp/PhoneDevice.cpp b/app/src/main/cpp/PhoneDevice.cpp index 3c193226..f720a63f 100644 --- a/app/src/main/cpp/PhoneDevice.cpp +++ b/app/src/main/cpp/PhoneDevice.cpp @@ -32,6 +32,7 @@ #include #include +#include #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) #define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) @@ -49,6 +50,68 @@ extern bool GetJniEnv(JavaVM *vm, JNIEnv **env); // are normalized to eight bits. static const int kMaxChannelValue = 262143; +static long getFreeMemoryImpl(const char* const sums[], const size_t sumsLen[], size_t num) +{ + int fd = open("/proc/meminfo", O_RDONLY | O_CLOEXEC); + + if (fd < 0) { + ALOGW("Unable to open /proc/meminfo"); + return -1; + } + + char buffer[2048]; + const int len = read(fd, buffer, sizeof(buffer)-1); + close(fd); + + if (len < 0) { + ALOGW("Unable to read /proc/meminfo"); + return -1; + } + buffer[len] = 0; + + size_t numFound = 0; + jlong mem = 0; + + char* p = buffer; + while (*p && numFound < num) { + int i = 0; + while (sums[i]) { + if (strncmp(p, sums[i], sumsLen[i]) == 0) { + p += sumsLen[i]; + while (*p == ' ') p++; + char* num = p; + while (*p >= '0' && *p <= '9') p++; + if (*p != 0) { + *p = 0; + p++; + if (*p == 0) p--; + } + mem += atoll(num) * 1024; + numFound++; + break; + } + i++; + } + p++; + } + + return numFound > 0 ? mem : -1; +} + +static jlong android_os_Process_getFreeMemory() +{ + static const char* const sums[] = { "MemFree:", "Cached:", NULL }; + static const size_t sumsLen[] = { strlen("MemFree:"), strlen("Cached:"), 0 }; + return getFreeMemoryImpl(sums, sumsLen, 2); +} + +static jlong android_os_Process_getTotalMemory() +{ + static const char* const sums[] = { "MemTotal:", NULL }; + static const size_t sumsLen[] = { strlen("MemTotal:"), 0 }; + return getFreeMemoryImpl(sums, sumsLen, 1); +} + static inline uint32_t YUV2RGB(int nY, int nU, int nV) { nY -= 16; nU -= 128; @@ -146,7 +209,16 @@ bool CPhoneDevice::UpdateTime(time_t ts) return (ret == JNI_TRUE); } -bool GetNextScheduleItem(uint32_t tsBasedZero, uint32_t scheduleTime, vector& items) +bool CPhoneDevice::QuerySystemProperties(map& properties) +{ + char value[128] = { 0 }; + __system_property_get("ro.telephony.default_network", value); + + return true; +} + + +bool CPhoneDevice::GetNextScheduleItem(uint32_t tsBasedZero, uint32_t scheduleTime, vector& items) { return false; } diff --git a/app/src/main/cpp/PhoneDevice.h b/app/src/main/cpp/PhoneDevice.h index b1ee8a87..62bfb2cd 100644 --- a/app/src/main/cpp/PhoneDevice.h +++ b/app/src/main/cpp/PhoneDevice.h @@ -37,6 +37,7 @@ public: virtual void SetListener(IListener* listener); virtual bool UpdateTime(time_t ts); + virtual bool QuerySystemProperties(map& properties); virtual bool Reboot(); virtual timer_uid_t RegisterHeartbeat(unsigned int timerType, unsigned int timeout); virtual bool TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector& osds, const string& path); diff --git a/app/src/main/cpp/camera2/ndkcamera.cpp b/app/src/main/cpp/camera2/ndkcamera.cpp index 68433607..89fbad64 100644 --- a/app/src/main/cpp/camera2/ndkcamera.cpp +++ b/app/src/main/cpp/camera2/ndkcamera.cpp @@ -15,11 +15,9 @@ #include "ndkcamera.h" #include - +#include #include - #include - #include "mat.h" static void onDisconnected(void* context, ACameraDevice* device) @@ -34,97 +32,7 @@ static void onError(void* context, ACameraDevice* device, int error) static void onImageAvailable(void* context, AImageReader* reader) { -// __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onImageAvailable %p", reader); - - AImage* image = 0; - media_status_t status = AImageReader_acquireLatestImage(reader, &image); - - if (status != AMEDIA_OK) - { - // error - return; - } - - int32_t format; - AImage_getFormat(image, &format); - - // ASSERT(format == AIMAGE_FORMAT_YUV_420_888); - - int32_t width = 0; - int32_t height = 0; - AImage_getWidth(image, &width); - AImage_getHeight(image, &height); - - int32_t y_pixelStride = 0; - int32_t u_pixelStride = 0; - int32_t v_pixelStride = 0; - AImage_getPlanePixelStride(image, 0, &y_pixelStride); - AImage_getPlanePixelStride(image, 1, &u_pixelStride); - AImage_getPlanePixelStride(image, 2, &v_pixelStride); - - int32_t y_rowStride = 0; - int32_t u_rowStride = 0; - int32_t v_rowStride = 0; - AImage_getPlaneRowStride(image, 0, &y_rowStride); - AImage_getPlaneRowStride(image, 1, &u_rowStride); - AImage_getPlaneRowStride(image, 2, &v_rowStride); - - uint8_t* y_data = 0; - uint8_t* u_data = 0; - uint8_t* v_data = 0; - int y_len = 0; - int u_len = 0; - int v_len = 0; - AImage_getPlaneData(image, 0, &y_data, &y_len); - AImage_getPlaneData(image, 1, &u_data, &u_len); - AImage_getPlaneData(image, 2, &v_data, &v_len); - - if (u_data == v_data + 1 && v_data == y_data + width * height && y_pixelStride == 1 && u_pixelStride == 2 && v_pixelStride == 2 && y_rowStride == width && u_rowStride == width && v_rowStride == width) - { - // already nv21 :) - ((NdkCamera*)context)->on_image((unsigned char*)y_data, (int)width, (int)height); - } - else - { - // construct nv21 - unsigned char* nv21 = new unsigned char[width * height + width * height / 2]; - { - // Y - unsigned char* yptr = nv21; - for (int y=0; yon_image((unsigned char*)nv21, (int)width, (int)height); - - delete[] nv21; - } - - AImage_delete(image); + ((NdkCamera*)context)->onImageAvailable(reader); } static void onSessionActive(void* context, ACameraCaptureSession *session) @@ -167,6 +75,8 @@ NdkCamera::NdkCamera(int32_t width, int32_t height) camera_facing = 0; camera_orientation = 0; + m_firstFrame = true; + camera_manager = 0; camera_device = 0; image_reader = 0; @@ -183,14 +93,13 @@ NdkCamera::NdkCamera(int32_t width, int32_t height) AImageReader_ImageListener listener; listener.context = this; - listener.onImageAvailable = onImageAvailable; + listener.onImageAvailable = ::onImageAvailable; AImageReader_setImageListener(image_reader, &listener); AImageReader_getWindow(image_reader, &image_reader_surface); - ANativeWindow_setBuffersGeometry(image_reader_surface, width, height, - WINDOW_FORMAT_RGBX_8888); + // ANativeWindow_setBuffersGeometry(image_reader_surface, width, height,WINDOW_FORMAT_RGBX_8888); ANativeWindow_acquire(image_reader_surface); } @@ -297,6 +206,7 @@ int NdkCamera::open(const char* cameraId) ACameraManager_openCamera(camera_manager, camera_id.c_str(), &camera_device_state_callbacks, &camera_device); } + std::this_thread::sleep_for(std::chrono::milliseconds(128)); // capture request { ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_STILL_CAPTURE, &capture_request); @@ -332,6 +242,7 @@ int NdkCamera::open(const char* cameraId) camera_capture_session_capture_callbacks.onCaptureBufferLost = 0; ACameraCaptureSession_setRepeatingRequest(capture_session, &camera_capture_session_capture_callbacks, 1, &capture_request, nullptr); + // ACameraCaptureSession_capture(capture_session, &camera_capture_session_capture_callbacks, 1, &capture_request,nullptr); } return 0; @@ -385,6 +296,111 @@ void NdkCamera::close() } } +void NdkCamera::onImageAvailable(AImageReader* reader) +{ + __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onImageAvailable %p", reader); + + AImage* image = 0; + media_status_t status = AImageReader_acquireLatestImage(reader, &image); + + if (status != AMEDIA_OK) + { + // error + return; + } + + if (m_firstFrame) + { + // AImage_delete(image); + // m_firstFrame = false; + // return; + } + + + int32_t format; + AImage_getFormat(image, &format); + + // ASSERT(format == AIMAGE_FORMAT_YUV_420_888); + + int32_t width = 0; + int32_t height = 0; + AImage_getWidth(image, &width); + AImage_getHeight(image, &height); + + int32_t y_pixelStride = 0; + int32_t u_pixelStride = 0; + int32_t v_pixelStride = 0; + AImage_getPlanePixelStride(image, 0, &y_pixelStride); + AImage_getPlanePixelStride(image, 1, &u_pixelStride); + AImage_getPlanePixelStride(image, 2, &v_pixelStride); + + int32_t y_rowStride = 0; + int32_t u_rowStride = 0; + int32_t v_rowStride = 0; + AImage_getPlaneRowStride(image, 0, &y_rowStride); + AImage_getPlaneRowStride(image, 1, &u_rowStride); + AImage_getPlaneRowStride(image, 2, &v_rowStride); + + uint8_t* y_data = 0; + uint8_t* u_data = 0; + uint8_t* v_data = 0; + int y_len = 0; + int u_len = 0; + int v_len = 0; + AImage_getPlaneData(image, 0, &y_data, &y_len); + AImage_getPlaneData(image, 1, &u_data, &u_len); + AImage_getPlaneData(image, 2, &v_data, &v_len); + + if (u_data == v_data + 1 && v_data == y_data + width * height && y_pixelStride == 1 && u_pixelStride == 2 && v_pixelStride == 2 && y_rowStride == width && u_rowStride == width && v_rowStride == width) + { + // already nv21 :) + on_image((unsigned char*)y_data, (int)width, (int)height); + } + else + { + // construct nv21 + unsigned char* nv21 = new unsigned char[width * height + width * height / 2]; + { + // Y + unsigned char* yptr = nv21; + for (int y=0; y mTimers = new HashMap<>(); private static int stateService = STATE_SERVICE.NOT_CONNECTED; + public MicroPhotoService() { } @@ -101,13 +115,15 @@ public class MicroPhotoService extends Service { mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); stateService = STATE_SERVICE.NOT_CONNECTED; + getPhoneState(this.getApplicationContext()); + alarmReceiver = new AlarmReceiver(this); // 注册广播接受者 IntentFilter intentFilter = new IntentFilter(ACTION_HEARTBEAT); intentFilter.addAction(ACTION_TAKE_PHOTO); intentFilter.addAction(ACTION_TIMEOUT); intentFilter.addAction(ACTION_TAKE_PHOTO_MANUALLY); - registerReceiver( alarmReceiver, intentFilter); + registerReceiver(alarmReceiver, intentFilter); AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); @@ -143,8 +159,10 @@ public class MicroPhotoService extends Service { // File path = getApplicationContext().getFilesDir(); String appPath = path.getAbsolutePath(); Log.i(TAG, "AppPath=" + appPath); - String ip = "180.166.218.222"; - int port = 40032; + // String ip = "180.166.218.222"; + // int port = 40032; + String ip = "192.168.137.102"; + int port = 6891; String cmdid = "XYDEV100230100012"; init(appPath, ip, port, cmdid); @@ -167,25 +185,26 @@ public class MicroPhotoService extends Service { public static class AlarmReceiver extends BroadcastReceiver { private MicroPhotoService mService; + public AlarmReceiver(MicroPhotoService service) { mService = service; } + public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if(TextUtils.equals(ACTION_HEARTBEAT, action)){ + if (TextUtils.equals(ACTION_HEARTBEAT, action)) { Log.i(TAG, "receiver ACTION=" + action); mService.sendHeartbeat(); mService.registerHeartbeatTimer(); - } - else if(TextUtils.equals(ACTION_TAKE_PHOTO, action)) { + } 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); + int channel = (int) ((val & 0xFF0000L) >> 16); + int preset = (int) ((val & 0xFF00L) >> 8); mService.notifyToTakePhoto(channel, preset, ts, mService.buildPhotoDir(channel), mService.buildPhotoFileName(channel, preset, ts), true); } @@ -201,8 +220,7 @@ public class MicroPhotoService extends Service { long baseTime = nowTs - startTime; mService.registerCaptureSchedule(startTime, baseTime); - } - else if(TextUtils.equals(ACTION_TAKE_PHOTO_MANUALLY, action)) { + } 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); @@ -210,15 +228,14 @@ public class MicroPhotoService extends Service { long ts = System.currentTimeMillis() / 1000; mService.notifyToTakePhoto(channel, preset, ts, mService.buildPhotoDir(channel), mService.buildPhotoFileName(channel, preset, ts), photoOrVideo); - } - else if(TextUtils.equals(ACTION_TIMEOUT, action)) { + } else if (TextUtils.equals(ACTION_TIMEOUT, action)) { long uid = intent.getLongExtra(EXTRA_PARAM_TIMER_UID, 0); Log.i(TAG, "Timeout:" + uid); mService.fireTimeout(uid); int timeout = intent.getIntExtra(EXTRA_PARAM_TIMEOUT, 0); Long uidObj = Long.valueOf(uid); - PendingIntent pendingIntent = mService.mTimers.get(uidObj); + PendingIntent pendingIntent = mService.mTimers.get(uidObj); if (pendingIntent != null) { mService.registerTimer(pendingIntent, uid, timeout); @@ -235,6 +252,7 @@ public class MicroPhotoService extends Service { } } + private void registerHeartbeatTimer() { // 创建延迟意图 @@ -248,6 +266,7 @@ public class MicroPhotoService extends Service { mNextHeartbeatTime = System.currentTimeMillis() + mHeartbeatDuration; // alarmManager.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + timeout, pendingIntent); } + private void registerPhotoTimer(int channel, int preset, long ts, long timeout, List schedules) { // 创建延迟意图 @@ -304,7 +323,7 @@ public class MicroPhotoService extends Service { public boolean unregisterTimer(long uid) { Long uidObj = Long.valueOf(uid); - PendingIntent pendingIntent = mTimers.get(uidObj); + PendingIntent pendingIntent = mTimers.get(uidObj); if (pendingIntent != null) { AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); @@ -316,6 +335,7 @@ public class MicroPhotoService extends Service { return true; } + private boolean registerCaptureSchedule(long startTime, long baseTime) { long[] photoTimeData = getPhotoTimeData(); @@ -336,7 +356,7 @@ public class MicroPhotoService extends Service { 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; + ts = (int) ((val & 0x00FFFFFF00000000L) >> 32) + offset; if (ts < baseTime) { continue; @@ -348,8 +368,8 @@ public class MicroPhotoService extends Service { if (currentTs == 0) { currentTs = ts; - channel = (short)((val & 0xFF0000L) >> 16); - preset = (short)((val & 0xFF00L) >> 8); + channel = (short) ((val & 0xFF0000L) >> 16); + preset = (short) ((val & 0xFF00L) >> 8); schedules.add(Long.valueOf(val)); } else if (ts > currentTs) { @@ -416,17 +436,18 @@ public class MicroPhotoService extends Service { return START_NOT_STICKY; } + private void connect() { // after 10 seconds its connected new android.os.Handler().postDelayed( - new Runnable() { - public void run() { - Log.d(TAG, "Bluetooth Low Energy device is connected!!"); - Toast.makeText(getApplicationContext(),"Connected!",Toast.LENGTH_SHORT).show(); - stateService = STATE_SERVICE.CONNECTED; - startForeground(NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification()); - } - }, 10000); + new Runnable() { + public void run() { + Log.d(TAG, "Bluetooth Low Energy device is connected!!"); + Toast.makeText(getApplicationContext(), "Connected!", Toast.LENGTH_SHORT).show(); + stateService = STATE_SERVICE.CONNECTED; + startForeground(NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification()); + } + }, 10000); } @@ -462,7 +483,7 @@ public class MicroPhotoService extends Service { remoteViews.setOnClickPendingIntent(R.id.btn_stop, pendingStopIntent); // if it is connected - switch(stateService) { + switch (stateService) { case STATE_SERVICE.NOT_CONNECTED: remoteViews.setTextViewText(R.id.tv_state, "DISCONNECTED"); break; @@ -494,6 +515,124 @@ public class MicroPhotoService extends Service { return notificationBuilder.build(); } + protected String getNetworkType() { + + // ConnectionManager instance + ConnectivityManager connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE); + NetworkInfo ni = connectivityManager.getActiveNetworkInfo(); + + // If not connected, "-" will be displayed + if (ni == null || !ni.isConnected()) return ""; + + // If Connected to Wifi + if (ni.getType() == ConnectivityManager.TYPE_WIFI) return "WIFI"; + + // If Connected to Mobile + String subTypeName = ""; + if (ni.getType() == ConnectivityManager.TYPE_MOBILE) { + int subType = ni.getSubtype(); + switch (subType) { + case TelephonyManager.NETWORK_TYPE_GPRS: + case TelephonyManager.NETWORK_TYPE_EDGE: + case TelephonyManager.NETWORK_TYPE_CDMA: + case TelephonyManager.NETWORK_TYPE_1xRTT: + case TelephonyManager.NETWORK_TYPE_IDEN: + case TelephonyManager.NETWORK_TYPE_GSM: + subTypeName = "2G"; + break; + case TelephonyManager.NETWORK_TYPE_UMTS: + case TelephonyManager.NETWORK_TYPE_EVDO_0: + case TelephonyManager.NETWORK_TYPE_EVDO_A: + case TelephonyManager.NETWORK_TYPE_HSDPA: + case TelephonyManager.NETWORK_TYPE_HSUPA: + case TelephonyManager.NETWORK_TYPE_HSPA: + case TelephonyManager.NETWORK_TYPE_EVDO_B: + case TelephonyManager.NETWORK_TYPE_EHRPD: + case TelephonyManager.NETWORK_TYPE_HSPAP: + case TelephonyManager.NETWORK_TYPE_TD_SCDMA: + subTypeName = "3G"; + break; + case TelephonyManager.NETWORK_TYPE_LTE: + case TelephonyManager.NETWORK_TYPE_IWLAN: + case 19: + subTypeName = "4G"; + break; + case TelephonyManager.NETWORK_TYPE_NR: + subTypeName = "5G"; + break; + default: + subTypeName = ""; + break; + } + } + return subTypeName; + } + + public static void getPhoneState(Context context) { + final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + PhoneStateListener MyPhoneListener = new PhoneStateListener() { + @Override + //获取对应网络的ID,这个方法在这个程序中没什么用处 + public void onCellLocationChanged(CellLocation location) { + if (location instanceof GsmCellLocation) { + int CID = ((GsmCellLocation) location).getCid(); + } else if (location instanceof CdmaCellLocation) { + int ID = ((CdmaCellLocation) location).getBaseStationId(); + } + } + + //系统自带的服务监听器,实时监听网络状态 + @Override + public void onServiceStateChanged(ServiceState serviceState) { + super.onServiceStateChanged(serviceState); + } + + //这个是我们的主角,就是获取对应网络信号强度 + @Override + public void onSignalStrengthsChanged(SignalStrength signalStrength) { + //这个ltedbm 是4G信号的值 + String signalinfo = signalStrength.toString(); + String[] parts = signalinfo.split(" "); + String ltedbm = parts[9]; + //这个dbm 是2G和3G信号的值 + int asu = signalStrength.getGsmSignalStrength(); + int dbm = -113 + 2 * asu; + + if (telephonyManager.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE) { + Log.i("NetWorkUtil", "网络:LTE 信号强度:" + ltedbm + "======Detail:" + signalinfo); + } else if (telephonyManager.getNetworkType() == TelephonyManager.NETWORK_TYPE_HSDPA || + telephonyManager.getNetworkType() == TelephonyManager.NETWORK_TYPE_HSPA || + telephonyManager.getNetworkType() == TelephonyManager.NETWORK_TYPE_HSUPA || + telephonyManager.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS) { + String bin; + if (dbm > -75) { + bin = "网络很好"; + } else if (dbm > -85) { + bin = "网络不错"; + } else if (dbm > -95) { + bin = "网络还行"; + } else if (dbm > -100) { + bin = "网络很差"; + } else { + bin = "网络错误"; + } + Log.i("NetWorkUtil", "网络:WCDMA 信号值:" + dbm + "========强度:" + bin + "======Detail:" + signalinfo); + } else { + String bin; + if (asu < 0 || asu >= 99) bin = "网络错误"; + else if (asu >= 16) bin = "网络很好"; + else if (asu >= 8) bin = "网络不错"; + else if (asu >= 4) bin = "网络还行"; + else bin = "网络很差"; + Log.i("NetWorkUtil", "网络:GSM 信号值:" + dbm + "========强度:" + bin + "======Detail:" + signalinfo); + } + super.onSignalStrengthsChanged(signalStrength); + } + }; + telephonyManager.listen(MyPhoneListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS); + } + + /* public boolean takePhoto(short channel, short preset, String path) {