From caa31cb86596bed28792524abd8da780d38b180d Mon Sep 17 00:00:00 2001 From: Matthew Date: Sun, 10 Sep 2023 22:28:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96android=E6=8B=8D=E7=85=A7?= =?UTF-8?q?=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 +- app/src/main/cpp/MicroPhoto.cpp | 14 +- app/src/main/cpp/PhoneDevice.cpp | 149 ++++++-- app/src/main/cpp/PhoneDevice.h | 16 +- app/src/main/cpp/PhoneDevice2.h | 2 +- .../main/cpp/{ => camera2}/Camera2Helper.h | 0 app/src/main/cpp/camera2/ndkcamera.cpp | 111 ++++-- app/src/main/cpp/camera2/ndkcamera.h | 6 +- app/src/main/cpp/yamc/posix_semaphore.hpp | 2 + .../xinyingpower/microphoto/DeviceUtil.java | 169 +++++++++ .../xinyingpower/microphoto/MainActivity.java | 29 +- .../microphoto/MicroPhotoService.java | 333 ++++++------------ app/src/main/res/layout/activity_main.xml | 128 ++++--- 13 files changed, 628 insertions(+), 335 deletions(-) rename app/src/main/cpp/{ => camera2}/Camera2Helper.h (100%) create mode 100644 app/src/main/java/com/xinyingpower/microphoto/DeviceUtil.java diff --git a/app/build.gradle b/app/build.gradle index 811a732c..b9d79815 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,8 +2,8 @@ plugins { id 'com.android.application' } -def AppVersionName = "1.0.0" -def AppVersionCode = ((1 * 100 + 1) * 100 + 0) * 10 + 0 +def AppVersionName = "1.0.4" +def AppVersionCode = ((1 * 100 + 1) * 100 + 0) * 10 + 4 android { namespace 'com.xinyingpower.microphoto' diff --git a/app/src/main/cpp/MicroPhoto.cpp b/app/src/main/cpp/MicroPhoto.cpp index 31b9e9e0..962dd2e6 100644 --- a/app/src/main/cpp/MicroPhoto.cpp +++ b/app/src/main/cpp/MicroPhoto.cpp @@ -17,6 +17,7 @@ #include "Camera2Reader.h" + bool GetJniEnv(JavaVM *vm, JNIEnv **env) { bool did_attach_thread = false; @@ -75,7 +76,6 @@ Java_com_xinyingpower_microphoto_MainActivity_takePhoto( unsigned char id = (unsigned char)channel - 1; - Camera2Reader *camera = new Camera2Reader(id); const char *pathStr = env->GetStringUTFChars(path, 0); const char *fileNameStr = env->GetStringUTFChars(fileName, 0); @@ -143,7 +143,7 @@ Java_com_xinyingpower_microphoto_MicroPhotoService_notifyToTakePhoto( return JNI_FALSE; } - pTerminal->NotifyToTakePhoto((unsigned int)channel, (unsigned int)preset, 0, (unsigned long)scheduleTime); + pTerminal->RequestCapture((unsigned int)channel, (unsigned int)preset, 0, (unsigned long)scheduleTime); return JNI_TRUE; } @@ -207,8 +207,13 @@ Java_com_xinyingpower_microphoto_MicroPhotoService_getHeartbeatDuration( JNIEnv* env, jobject pThis, jlong handler) { + CTerminal* pTerminal = reinterpret_cast(handler); + if (pTerminal == NULL) + { + return DEFAULT_HEARTBEAT_DURATION; + } - return 60000; + return pTerminal->GetHeartbeatDuration(); } extern "C" JNIEXPORT jlongArray JNICALL @@ -276,7 +281,7 @@ Java_com_xinyingpower_microphoto_MicroPhotoService_getPhotoTimeData( return data; } - +/* extern "C" JNIEXPORT jlongArray JNICALL Java_com_xinyingpower_microphoto_MicroPhotoService_getNextScheduleItem( JNIEnv* env, @@ -341,3 +346,4 @@ Java_com_xinyingpower_microphoto_MicroPhotoService_getNextScheduleItem( return data; } + */ diff --git a/app/src/main/cpp/PhoneDevice.cpp b/app/src/main/cpp/PhoneDevice.cpp index 674017c4..6af7054d 100644 --- a/app/src/main/cpp/PhoneDevice.cpp +++ b/app/src/main/cpp/PhoneDevice.cpp @@ -43,7 +43,7 @@ extern bool GetJniEnv(JavaVM *vm, JNIEnv **env); - +#define WAKELOCK_NAME "NDK_WK_" // This value is 2 ^ 18 - 1, and is used to clamp the RGB values before their // ranges // are normalized to eight bits. @@ -142,30 +142,45 @@ CPhoneDevice::CPhoneCamera::CPhoneCamera(CPhoneDevice* dev, int32_t width, int32 { } -void CPhoneDevice::CPhoneCamera::on_image(const cv::Mat& rgb) const +bool CPhoneDevice::CPhoneCamera::on_image(const cv::Mat& rgb) const +{ + if (m_dev != NULL) + { + return m_dev->OnImageReady(rgb); + } + + return false; +} + +void CPhoneDevice::CPhoneCamera::on_error(const std::string& msg) const { if (m_dev != NULL) { - m_dev->OnImageReady(rgb); + m_dev->onError(msg); } } CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service) { + mCamera = NULL; + m_listener = NULL; + mHeartbeatStartTime = 0; + mHeartbeatDuration = 0; + m_vm = vm; JNIEnv* env = NULL; bool attached = GetJniEnv(m_vm, &env); m_javaService = env->NewGlobalRef(service); - mHeartbeatStartTime = 0; - mHeartbeatDuration = 0; - jclass classService = env->GetObjectClass(m_javaService); mRegisterTimerMid = env->GetMethodID(classService, "registerTimer", "(JI)Z"); mRegisterHeartbeatMid = env->GetMethodID(classService, "registerHeartbeatTimer", "(I)V"); mUnregisterTimerMid = env->GetMethodID(classService, "unregisterTimer", "(J)Z"); mUpdateTimeMid = env->GetMethodID(classService, "updateTime", "(J)Z"); + mRequestWakelockMid = env->GetMethodID(classService, "requestWakelock", "(Ljava/lang/String;J)V"); + mReleaseWakelockMid = env->GetMethodID(classService, "releaseWakelock", "(Ljava/lang/String;)V"); + env->DeleteLocalRef(classService); if (attached) @@ -173,7 +188,8 @@ CPhoneDevice::CPhoneDevice(JavaVM* vm, jobject service) vm->DetachCurrentThread(); } - m_timerUidFeed = time(NULL); + m_timerUidFeed = time(NULL) * 1000; + m_wakelockIdFeed = (unsigned long)m_timerUidFeed; } CPhoneDevice::~CPhoneDevice() @@ -219,11 +235,9 @@ bool CPhoneDevice::QuerySystemProperties(map& properties) __system_property_get("ro.product.model", value); properties[PROP_MODEL] = value; - __system_property_get("ro.product.manufacturer", value); properties[PROP_BS_MANU] = value; - properties[PROP_BS_ID] = "SHXY"; __system_property_get("ro.build.version.release", value); @@ -238,7 +252,6 @@ bool CPhoneDevice::QuerySystemProperties(map& properties) __system_property_get("phone.imei", value); properties[PROP_IMEI] = value; - return true; } @@ -296,6 +309,54 @@ bool CPhoneDevice::UnregisterTimer(IDevice::timer_uid_t uid) return false; } +unsigned long CPhoneDevice::RequestWakelock(unsigned long timeout) +{ + unsigned long wakelockId = m_wakelockIdFeed.fetch_add(1); + std::string name = WAKELOCK_NAME; + name += to_string(wakelockId); + + JNIEnv* env = NULL; + jboolean ret = JNI_FALSE; + bool attached = GetJniEnv(m_vm, &env); + if (attached) + { + jstring jname = env->NewStringUTF(name.c_str()); + jlong jtimeout = (jlong)timeout; + + env->CallVoidMethod(m_javaService, mRequestWakelockMid, jname, jtimeout); + // env->ReleaseStringUTFChars(jname, name.c_str()); + env->DeleteLocalRef(jname); + + m_vm->DetachCurrentThread(); + } + + // return (ret == JNI_TRUE); + + return wakelockId; +} + +bool CPhoneDevice::ReleaseWakelock(unsigned long wakelock) +{ + std::string name = WAKELOCK_NAME; + name += to_string(wakelock); + + JNIEnv* env = NULL; + jboolean ret = JNI_FALSE; + bool attached = GetJniEnv(m_vm, &env); + if (attached) + { + jstring jname = env->NewStringUTF(name.c_str()); + + env->CallVoidMethod(m_javaService, mReleaseWakelockMid, jname); + env->DeleteLocalRef(jname); + // env->ReleaseStringUTFChars(jname, name.c_str()); + + m_vm->DetachCurrentThread(); + } + + return true; +} + bool CPhoneDevice::FireTimer(timer_uid_t uid) { std::map::iterator it = mTimers.find(uid); @@ -345,43 +406,91 @@ IDevice::timer_uid_t CPhoneDevice::RegisterHeartbeat(unsigned int timerType, uns bool CPhoneDevice::TakePhoto(const IDevice::PHOTO_INFO& photoInfo, const vector& osds, const string& path) { + if (mCamera != NULL) + { + delete mCamera; + mCamera = NULL; + } + LOGI("TAKE_PHOTO: CH=%u PR=%u\n", (unsigned int)photoInfo.channel, (unsigned int)photoInfo.preset); mPhotoInfo = photoInfo; mPath = path; mOsds = osds; mCamera = new CPhoneCamera(this, photoInfo.width, photoInfo.height); - mCamera->open(to_string(photoInfo.channel - 1).c_str()); + if (mCamera->open(to_string(photoInfo.channel - 1).c_str()) == 0) + { + } + else + { + delete mCamera; + mCamera = NULL; + return false; + } return true; } -void CPhoneDevice::OnImageReady(const cv::Mat& mat) const +bool CPhoneDevice::CloseCamera() { + if (mCamera != NULL) + { + delete mCamera; + mCamera = NULL; + } + return true; +} +bool CPhoneDevice::OnImageReady(const cv::Mat& mat) const +{ int baseline = 0; cv::Size textSize, textSize2; + double fontScale = 1; // base 1024 + double height = mat.size().height; + double width = mat.size().width; + double ratio = std::min(height / 1024, width / 1920); + fontScale = fontScale * ratio; + double thickness1 = 4 * ratio; + double thickness2 = 2 * ratio; for (vector::const_iterator it = mOsds.cbegin(); it != mOsds.cend(); ++it) { // getTextSize(value, font, scale, 1, &bottom); - textSize = cv::getTextSize(it->text, cv::FONT_HERSHEY_COMPLEX, 1, 4, &baseline); - cv::Point pt(it->x, it->y + textSize.height); - putText(mat, it->text, pt, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(0, 0, 0), 4,cv::LINE_AA); - textSize2 = cv::getTextSize(it->text, cv::FONT_HERSHEY_COMPLEX, 1, 2, &baseline); + textSize = cv::getTextSize(it->text, cv::FONT_HERSHEY_COMPLEX, fontScale, thickness1, &baseline); + cv::Point pt(it->x * ratio, it->y * ratio + textSize.height); + putText(mat, it->text, pt, cv::FONT_HERSHEY_COMPLEX, fontScale, cv::Scalar(0, 0, 0), thickness1,cv::LINE_AA); + textSize2 = cv::getTextSize(it->text, cv::FONT_HERSHEY_COMPLEX, fontScale, thickness2, &baseline); pt.y -= (textSize.height - textSize2.height) / 2; - putText(mat, it->text, pt, cv::FONT_HERSHEY_COMPLEX, 1, cv::Scalar(255, 255, 255), 2,cv::LINE_AA); + putText(mat, it->text, pt, cv::FONT_HERSHEY_COMPLEX, fontScale, cv::Scalar(255, 255, 255), thickness2,cv::LINE_AA); } vector compression_params; compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); - compression_params.push_back(80); + compression_params.push_back(mPhotoInfo.quality); + ALOGI("Will write photo: %s", mPath.c_str()); bool res = cv::imwrite(mPath.c_str(), mat, compression_params); + if (!res) + { + ALOGE("Failed to write photo: %s", mPath.c_str()); + } + // mCamera->close(); TakePhotoCb(res, mPhotoInfo, mPath, time(NULL)); - delete mCamera; - mCamera = NULL; + // delete mCamera; + // mCamera = NULL; + return res; +} + +void CPhoneDevice::onError(const std::string& msg) const +{ + // XFLOG(XFLOG_SEVERITY_ERROR, "Failed to Take Photo: %s", msg.c_str()); + + ALOGE("Failed to Take Photo: %s", msg.c_str()); + + // mCamera->close(); + + TakePhotoCb(false, mPhotoInfo, mPath, 0); } std::string CPhoneDevice::GetFileName() const diff --git a/app/src/main/cpp/PhoneDevice.h b/app/src/main/cpp/PhoneDevice.h index 62bfb2cd..dde8e781 100644 --- a/app/src/main/cpp/PhoneDevice.h +++ b/app/src/main/cpp/PhoneDevice.h @@ -25,7 +25,7 @@ #include #include -#include "Camera2Helper.h" +#include "camera2/Camera2Helper.h" #include "camera2/ndkcamera.h" @@ -41,8 +41,11 @@ public: 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); + virtual bool CloseCamera(); virtual timer_uid_t RegisterTimer(unsigned int timerType, unsigned int timeout); virtual bool UnregisterTimer(timer_uid_t uid); + virtual unsigned long RequestWakelock(unsigned long timeout); + virtual bool ReleaseWakelock(unsigned long wakelock); virtual bool FireTimer(timer_uid_t uid); @@ -65,7 +68,8 @@ protected: return false; } - void OnImageReady(const cv::Mat& mat) const; + bool OnImageReady(const cv::Mat& mat) const; + void onError(const std::string& msg) const; protected: @@ -77,18 +81,23 @@ protected: jmethodID mUnregisterTimerMid; jmethodID mUpdateTimeMid; + jmethodID mRequestWakelockMid; + jmethodID mReleaseWakelockMid; + std::string mPath; IDevice::PHOTO_INFO mPhotoInfo; vector mOsds; IListener* m_listener; atomic_ulong m_timerUidFeed; + atomic_ulong m_wakelockIdFeed; std::map mTimers; class CPhoneCamera : public NdkCamera { public: CPhoneCamera(CPhoneDevice* dev, int32_t width, int32_t height); - virtual void on_image(const cv::Mat& rgb) const; + virtual bool on_image(const cv::Mat& rgb) const; + virtual void on_error(const std::string& msg) const; protected: CPhoneDevice* m_dev; @@ -98,7 +107,6 @@ protected: time_t mHeartbeatStartTime; unsigned int mHeartbeatDuration; - }; diff --git a/app/src/main/cpp/PhoneDevice2.h b/app/src/main/cpp/PhoneDevice2.h index 16c2015f..871a7625 100644 --- a/app/src/main/cpp/PhoneDevice2.h +++ b/app/src/main/cpp/PhoneDevice2.h @@ -25,7 +25,7 @@ #include #include -#include "Camera2Helper.h" +#include "camera2/Camera2Helper.h" class CPhoneDevice2 : public IDevice { diff --git a/app/src/main/cpp/Camera2Helper.h b/app/src/main/cpp/camera2/Camera2Helper.h similarity index 100% rename from app/src/main/cpp/Camera2Helper.h rename to app/src/main/cpp/camera2/Camera2Helper.h diff --git a/app/src/main/cpp/camera2/ndkcamera.cpp b/app/src/main/cpp/camera2/ndkcamera.cpp index cebdf602..ece74ec7 100644 --- a/app/src/main/cpp/camera2/ndkcamera.cpp +++ b/app/src/main/cpp/camera2/ndkcamera.cpp @@ -19,6 +19,7 @@ #include #include #include "mat.h" +#include "Camera2Helper.h" static void onDisconnected(void* context, ACameraDevice* device) { @@ -27,7 +28,9 @@ static void onDisconnected(void* context, ACameraDevice* device) static void onError(void* context, ACameraDevice* device, int error) { - __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onError %p %d", device, error); + std::string msg = "NdkCamera error code=" + std::to_string(error); + ((NdkCamera*)context)->on_error(msg); + // __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onError %p %d", device, error); } static void onImageAvailable(void* context, AImageReader* reader) @@ -76,6 +79,8 @@ NdkCamera::NdkCamera(int32_t width, int32_t height) camera_orientation = 0; m_firstFrame = true; + mWidth = width; + mHeight = height; camera_manager = 0; camera_device = 0; @@ -87,22 +92,7 @@ NdkCamera::NdkCamera(int32_t width, int32_t height) capture_session_output = 0; capture_session = 0; - // setup imagereader and its surface - { - AImageReader_new(width, height, AIMAGE_FORMAT_YUV_420_888, /*maxImages*/2, &image_reader); - AImageReader_ImageListener listener; - listener.context = this; - 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_acquire(image_reader_surface); - } } NdkCamera::~NdkCamera() @@ -124,7 +114,7 @@ NdkCamera::~NdkCamera() int NdkCamera::open(const char* cameraId) { - __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "open"); + __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "DBG::open %s", cameraId); // camera_facing = _camera_facing; @@ -132,6 +122,10 @@ int NdkCamera::open(const char* cameraId) // find front camera std::string camera_id; + bool foundIt = false; + DisplayDimension disp(mWidth, mHeight); + DisplayDimension foundRes = disp; + { ACameraIdList* camera_id_list = 0; ACameraManager_getCameraIdList(camera_manager, &camera_id_list); @@ -181,6 +175,36 @@ int NdkCamera::open(const char* cameraId) camera_orientation = orientation; + + { + ACameraMetadata_const_entry e = { 0 }; + ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &e); + // format of the data: format, width, height, input?, type int32 + + // DisplayDimension foundRes(4000, 4000); + // DisplayDimension maxJPG(0, 0); + + for (int i = 0; i < e.count; i += 4) { + int32_t input = e.data.i32[i + 3]; + int32_t format = e.data.i32[i + 0]; + if (input) continue; + + if (format == AIMAGE_FORMAT_YUV_420_888 || format == AIMAGE_FORMAT_JPEG) { + DisplayDimension res(e.data.i32[i + 1], e.data.i32[i + 2]); + if (!disp.IsSameRatio(res)) continue; + + if (format == AIMAGE_FORMAT_YUV_420_888 && res > disp) { + foundIt = true; + foundRes = res; + }/* else if (format == AIMAGE_FORMAT_JPEG && res > maxJPG) { + maxJPG = res; + }*/ + } + } + + } + + ACameraMetadata_free(camera_metadata); break; @@ -189,11 +213,31 @@ int NdkCamera::open(const char* cameraId) ACameraManager_deleteCameraIdList(camera_id_list); } - if (camera_id.empty()) + if (camera_id.empty() || !foundIt) { return 1; } + mCameraId = camera_id; + + camera_status_t res = ACAMERA_OK; + // setup imagereader and its surface + { + AImageReader_new(foundRes.width(), foundRes.height(), AIMAGE_FORMAT_YUV_420_888, /*maxImages*/2, &image_reader); + + AImageReader_ImageListener listener; + listener.context = this; + 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_acquire(image_reader_surface); + } + __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "open %s %d", camera_id.c_str(), camera_orientation); // open camera @@ -203,16 +247,20 @@ int NdkCamera::open(const char* cameraId) camera_device_state_callbacks.onDisconnected = onDisconnected; camera_device_state_callbacks.onError = onError; - ACameraManager_openCamera(camera_manager, camera_id.c_str(), &camera_device_state_callbacks, &camera_device); + res = ACameraManager_openCamera(camera_manager, camera_id.c_str(), &camera_device_state_callbacks, &camera_device); + if (res != ACAMERA_OK) + { + return 1; + } } std::this_thread::sleep_for(std::chrono::milliseconds(128)); // capture request { - ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_STILL_CAPTURE, &capture_request); + res = ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_STILL_CAPTURE, &capture_request); - ACameraOutputTarget_create(image_reader_surface, &image_reader_target); - ACaptureRequest_addTarget(capture_request, image_reader_target); + res = ACameraOutputTarget_create(image_reader_surface, &image_reader_target); + res = ACaptureRequest_addTarget(capture_request, image_reader_target); } // capture session @@ -223,7 +271,7 @@ int NdkCamera::open(const char* cameraId) camera_capture_session_state_callbacks.onReady = onSessionReady; camera_capture_session_state_callbacks.onClosed = onSessionClosed; - ACaptureSessionOutputContainer_create(&capture_session_output_container); + res = ACaptureSessionOutputContainer_create(&capture_session_output_container); ACaptureSessionOutput_create(image_reader_surface, &capture_session_output); @@ -250,7 +298,7 @@ int NdkCamera::open(const char* cameraId) void NdkCamera::close() { - __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "close"); + __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "DBG::close %s", mCameraId.c_str()); if (capture_session) { @@ -316,7 +364,6 @@ void NdkCamera::onImageAvailable(AImageReader* reader) // return; } - int32_t format; AImage_getFormat(image, &format); @@ -401,7 +448,11 @@ void NdkCamera::onImageAvailable(AImageReader* reader) ACameraCaptureSession_stopRepeating(capture_session); } -void NdkCamera::on_image(const cv::Mat& rgb) const +void NdkCamera::on_error(const std::string& msg) const +{ +} + +bool NdkCamera::on_image(const cv::Mat& rgb) const { } @@ -461,6 +512,12 @@ void NdkCamera::on_image(const unsigned char* nv21, int nv21_width, int nv21_hei // cv::Mat rgb(h, w, CV_8UC3); // ncnn::yuv420sp2rgb_nv12(nv21, w, h, rgb.data); - on_image(rgb); + if (on_image(rgb)) + { + if (capture_session) + { + ACameraCaptureSession_stopRepeating(capture_session); + } + } } diff --git a/app/src/main/cpp/camera2/ndkcamera.h b/app/src/main/cpp/camera2/ndkcamera.h index 8392ea67..277a8155 100644 --- a/app/src/main/cpp/camera2/ndkcamera.h +++ b/app/src/main/cpp/camera2/ndkcamera.h @@ -33,7 +33,8 @@ public: void close(); void onImageAvailable(AImageReader* reader); - virtual void on_image(const cv::Mat& rgb) const; + virtual bool on_image(const cv::Mat& rgb) const; + virtual void on_error(const std::string& msg) const; virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const; @@ -41,6 +42,9 @@ public: int camera_facing; int camera_orientation; bool m_firstFrame; + int32_t mWidth; + int32_t mHeight; + std::string mCameraId; private: ACameraManager* camera_manager; diff --git a/app/src/main/cpp/yamc/posix_semaphore.hpp b/app/src/main/cpp/yamc/posix_semaphore.hpp index 4775445f..ca06bdc0 100644 --- a/app/src/main/cpp/yamc/posix_semaphore.hpp +++ b/app/src/main/cpp/yamc/posix_semaphore.hpp @@ -77,7 +77,9 @@ class counting_semaphore { static void throw_errno(const char* what_arg) { +#ifndef __ANDROID__ throw std::system_error(std::error_code(errno, std::generic_category()), what_arg); +#endif } bool do_try_acquirewait(const std::chrono::system_clock::time_point& tp) diff --git a/app/src/main/java/com/xinyingpower/microphoto/DeviceUtil.java b/app/src/main/java/com/xinyingpower/microphoto/DeviceUtil.java new file mode 100644 index 00000000..c548da2e --- /dev/null +++ b/app/src/main/java/com/xinyingpower/microphoto/DeviceUtil.java @@ -0,0 +1,169 @@ +package com.xinyingpower.microphoto; + +import android.app.AlarmManager; +import android.content.Context; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.telephony.CellLocation; +import android.telephony.PhoneStateListener; +import android.telephony.ServiceState; +import android.telephony.SignalStrength; +import android.telephony.TelephonyManager; +import android.telephony.cdma.CdmaCellLocation; +import android.telephony.gsm.GsmCellLocation; +import android.util.Log; + +public class DeviceUtil { + + + public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; + + public static final int SIGNAL_STRENGTH_POOR = 1; + + public static final int SIGNAL_STRENGTH_MODERATE = 2; + + public static final int SIGNAL_STRENGTH_GOOD = 3; + + public static final int SIGNAL_STRENGTH_GREAT = 4; + + public static final int NUM_SIGNAL_STRENGTH_BINS = 5; + + + + //无 ,低劣的 ,适度的 ,好 ,优异的 + public static final String[] SIGNAL_STRENGTH_NAMES = { + "none", "poor", "moderate", "good", "great" + }; + + public static String getNetworkType(Context context) { + + // ConnectionManager instance + ConnectivityManager connectivityManager = (ConnectivityManager) context.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 static boolean updateTime(Context context, long timeInMillis) { + boolean res = false; + try { + // Calendar c = Calendar.getInstance(); + // c.set(2010, 1, 1, 12, 00, 00); + AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + am.setTime(timeInMillis); + res = true; + } catch (Exception ex) { + int aa = 0; + } + return true; + } + +} diff --git a/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java b/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java index a383b47b..0bc9881a 100644 --- a/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java +++ b/app/src/main/java/com/xinyingpower/microphoto/MainActivity.java @@ -1,6 +1,7 @@ package com.xinyingpower.microphoto; import android.Manifest; +import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; @@ -9,6 +10,7 @@ import android.hardware.Camera; import android.os.Build; import android.os.Environment; import android.os.Handler; +import android.os.PowerManager; import android.os.SystemClock; import androidx.core.app.ActivityCompat; @@ -31,6 +33,8 @@ import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.Date; +import android.content.SharedPreferences; + public class MainActivity extends AppCompatActivity { @@ -45,12 +49,18 @@ public class MainActivity extends AppCompatActivity { private ActivityMainBinding binding; private int defaultDataSubId; + @Override + protected void onDestroy() { + super.onDestroy(); + } + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE); Display defaultDisplay = windowManager.getDefaultDisplay(); @@ -59,11 +69,17 @@ public class MainActivity extends AppCompatActivity { Log.d(TAG, "Screen Size: " + width + " x " + height); + SharedPreferences sp = MainActivity.this.getApplicationContext().getSharedPreferences("xymp", Context.MODE_PRIVATE); + binding.cmdid.setText(sp.getString("cmdid", "XY-ANDROIDSIM-001")); + binding.server.setText(sp.getString("server", "47.96.238.157")); + binding.port.setText(sp.getString("port", "6891")); + this.binding.startServBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { + String[] accessPermissions = new String[]{ Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE, @@ -93,8 +109,19 @@ public class MainActivity extends AppCompatActivity { String fileName = buildPhotoFileName(channel, 255); // MainActivity.this.takePhoto(channel, 255, path, fileName); + SharedPreferences sp = MainActivity.this.getApplicationContext().getSharedPreferences("xymp", Context.MODE_PRIVATE); + SharedPreferences.Editor editor = sp.edit(); + editor.putString("cmdid", MainActivity.this.binding.cmdid.getText().toString()); + editor.putString("server", MainActivity.this.binding.server.getText().toString()); + editor.putString("port", MainActivity.this.binding.port.getText().toString()); + editor.commit(); + Intent intent = new Intent(MainActivity.this, MicroPhotoService.class); intent.setAction(MicroPhotoService.ACTION_START); + intent.putExtra("cmdid", MainActivity.this.binding.cmdid.getText().toString()); + intent.putExtra("server", MainActivity.this.binding.server.getText().toString()); + String port = MainActivity.this.binding.port.getText().toString(); + intent.putExtra("port", Integer.parseInt(port)); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { MainActivity.this.startForegroundService(intent); @@ -187,7 +214,7 @@ public class MainActivity extends AppCompatActivity { Runnable runnable = new Runnable() { @Override public void run() { - binding.startServBtn.performClick(); + // binding.startServBtn.performClick(); } }; handler.postDelayed(runnable, 1000); diff --git a/app/src/main/java/com/xinyingpower/microphoto/MicroPhotoService.java b/app/src/main/java/com/xinyingpower/microphoto/MicroPhotoService.java index 1ecf2389..273420cc 100644 --- a/app/src/main/java/com/xinyingpower/microphoto/MicroPhotoService.java +++ b/app/src/main/java/com/xinyingpower/microphoto/MicroPhotoService.java @@ -16,6 +16,7 @@ import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Environment; import android.os.IBinder; +import android.os.PowerManager; import android.os.SystemClock; import androidx.core.app.ActivityCompat; @@ -35,8 +36,6 @@ import android.util.Log; import android.widget.RemoteViews; import android.widget.Toast; -import com.dowse.camera.client.DSCameraManager; - import java.io.File; import java.lang.reflect.Method; import java.time.LocalDateTime; @@ -44,6 +43,7 @@ import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -87,23 +87,6 @@ public class MicroPhotoService extends Service { private final static String FOREGROUND_CHANNEL_ID = "foreground_channel_id"; - public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; - - public static final int SIGNAL_STRENGTH_POOR = 1; - - public static final int SIGNAL_STRENGTH_MODERATE = 2; - - public static final int SIGNAL_STRENGTH_GOOD = 3; - - public static final int SIGNAL_STRENGTH_GREAT = 4; - - public static final int NUM_SIGNAL_STRENGTH_BINS = 5; - - //无 ,低劣的 ,适度的 ,好 ,优异的 - public static final String[] SIGNAL_STRENGTH_NAMES = { - "none", "poor", "moderate", "good", "great" - }; - public static class STATE_SERVICE { public static final int CONNECTED = 10; public static final int NOT_CONNECTED = 0; @@ -111,6 +94,10 @@ public class MicroPhotoService extends Service { private NotificationManager mNotificationManager; + private PowerManager.WakeLock wakeLock = null; + + private Map mWakeLocks = new HashMap<>(); + private int mHeartbeatDuration = 0; // 5m: 5 * 60 * 1000 private long mNextHeartbeatTime = 0; @@ -130,10 +117,15 @@ public class MicroPhotoService extends Service { public void onCreate() { super.onCreate(); + PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); + wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, + "MicroPhoto::MyWakelockTag"); + wakeLock.acquire(); + mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); stateService = STATE_SERVICE.NOT_CONNECTED; - getPhoneState(this.getApplicationContext()); + DeviceUtil.getPhoneState(this.getApplicationContext()); alarmReceiver = new AlarmReceiver(this); // 注册广播接受者 @@ -155,52 +147,15 @@ public class MicroPhotoService extends Service { // alarmManager.cancel(aci.getShowIntent()); } - } // alarmManager.cancel(); boolean res = false; - /* - res = DSCameraManager.getInstace().init(); - ChannelPicParam picParam = new ChannelPicParam(); - picParam.setColor(1); - picParam.setWidth(1920); - picParam.setHeight(1080); - picParam.setCompress_radio(40); - DSCameraManager.getInstace().setPicParam(1, picParam); - */ // Environment.getExternalStoragePublicDirectory(String) - File path = new File(Environment.getExternalStorageDirectory(), "com.xyp.mp/"); - if (!path.exists()) { - path.mkdirs(); - } - // File path = getApplicationContext().getFilesDir(); - String appPath = path.getAbsolutePath(); - Log.i(TAG, "AppPath=" + appPath); - // String ip = "180.166.218.222"; - String ip = "47.96.238.157"; - // int port = 40032; - // String ip = "192.168.50.50"; - int port = 6891; - String cmdid = "XY-ANDROIDSIM-003"; - mHandler = init(appPath, ip, port, cmdid); // registerHeartbeatTimer(getHeartbeatDuration()); - - Date date = new Date(); - long nowTs = date.getTime() / 1000; - date.setHours(0); - date.setMinutes(0); - date.setSeconds(0); - long startTime = date.getTime() / 1000; - long baseTime = nowTs - startTime; - - registerCaptureSchedule(startTime, baseTime); - - // registerPhotoTimer(); } - @Override public void onDestroy() { @@ -210,7 +165,17 @@ public class MicroPhotoService extends Service { mHandler = 0; unregisterReceiver(alarmReceiver); - DSCameraManager.getInstace().unInit(); + + if (wakeLock != null) { + wakeLock.release(); + wakeLock = null; + } + + for(Map.Entry entry : mWakeLocks.entrySet()) { + entry.getValue().release(); + } + mWakeLocks.clear(); + super.onDestroy(); } @@ -241,7 +206,7 @@ public class MicroPhotoService extends Service { int channel = (int) ((val & 0xFF0000L) >> 16); int preset = (int) ((val & 0xFF00L) >> 8); - mService.notifyToTakePhoto(mService.mHandler, channel, preset, ts, mService.buildPhotoDir(channel), mService.buildPhotoFileName(channel, preset, ts), true); + mService.notifyToTakePhoto(mService.mHandler, channel, preset, ts, mService.buildPhotoDir(mService.getApplicationContext(), channel), mService.buildPhotoFileName(channel, preset, ts), true); } } @@ -262,7 +227,8 @@ public class MicroPhotoService extends Service { boolean photoOrVideo = intent.getBooleanExtra(EXTRA_PARAM_PHOTO_OR_VIDEO, true); long ts = System.currentTimeMillis() / 1000; - mService.notifyToTakePhoto(mService.mHandler, channel, preset, ts, mService.buildPhotoDir(channel), mService.buildPhotoFileName(channel, preset, ts), photoOrVideo); + Log.i(TAG, "Take Photo CH=" + channel + " PR=" + preset); + mService.notifyToTakePhoto(mService.mHandler, channel, preset, ts, mService.buildPhotoDir(mService.getApplicationContext(), channel), mService.buildPhotoFileName(channel, preset, ts), photoOrVideo); } else if (TextUtils.equals(ACTION_TIMEOUT, action)) { long uid = intent.getLongExtra(EXTRA_PARAM_TIMER_UID, 0); Log.i(TAG, "Timeout:" + uid); @@ -431,9 +397,16 @@ public class MicroPhotoService extends Service { preset = (short) ((val & 0xFF00L) >> 8); schedules.add(Long.valueOf(val)); + + Log.i(TAG, "Reg Photo Timer: CH=" + channel + " PR=" + preset); } else if (ts > currentTs) { break; } else { + + channel = (short) ((val & 0xFF0000L) >> 16); + preset = (short) ((val & 0xFF00L) >> 8); + + Log.i(TAG, "Reg Photo Timer: CH=" + channel + " PR=" + preset); schedules.add(Long.valueOf(val)); } } @@ -478,11 +451,33 @@ public class MicroPhotoService extends Service { Log.d(TAG, "Received user starts foreground intent"); startForeground(NOTIFICATION_ID_FOREGROUND_SERVICE, prepareNotification()); + connect(); + + // File path = getApplicationContext().getFilesDir(); + String appPath = buildAppDir(this.getApplicationContext()); + + String ip = intent.getStringExtra("server"); + int port = intent.getIntExtra("port", 0); + String cmdid = intent.getStringExtra("cmdid"); + + Log.i(TAG, "AppPath=" + appPath + " Server=" + ip + ":" + port + " cmdid=" + cmdid); + mHandler = init(appPath, ip, port, cmdid); + // Start the locker receiver registerReceiver(screenactionreceiver, screenactionreceiver.getFilter()); - connect(); + Date date = new Date(); + long nowTs = date.getTime() / 1000; + date.setHours(0); + date.setMinutes(0); + date.setSeconds(0); + long startTime = date.getTime() / 1000; + long baseTime = nowTs - startTime; + + registerCaptureSchedule(startTime, baseTime); + + // registerPhotoTimer(); break; case ACTION_STOP: unregisterReceiver(screenactionreceiver); @@ -498,6 +493,31 @@ public class MicroPhotoService extends Service { return START_NOT_STICKY; } + public void requestWakelock(String name, long timeout) { + PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE); + PowerManager.WakeLock wl = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, name); + PowerManager.WakeLock wl2 = null; + synchronized (mWakeLocks) { + wl2 = mWakeLocks.replace(name, wl); + } + if (wl2 != null) { + wl2.release(); + } + if (timeout == 0) wl.acquire(); + else wl.acquire(timeout); + } + + public void releaseWakelock(String name) { + PowerManager.WakeLock wl = null; + synchronized (mWakeLocks) { + wl = mWakeLocks.get(name); + mWakeLocks.remove(name); + } + if (wl != null) { + wl.release(); + } + } + private void connect() { // after 10 seconds its connected new android.os.Handler().postDelayed( @@ -576,173 +596,36 @@ 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) { - - boolean res = DSCameraManager.getInstace().takePhoto(path, channel, 0, 0); + public String buildAppDir(Context contxt) { - if (!res) { + File[] paths = contxt.getExternalFilesDirs(null); - int idx = 0; - do { - res = DSCameraManager.getInstace().isCameraServiceOK(); - if (!res) - { - try { - Thread.sleep(1000L); - } catch (InterruptedException ex) { - // ex.printStackTrace(); - } - } - } while(idx < 6); - - if (DSCameraManager.getInstace().isCameraServiceOK()) { - res = DSCameraManager.getInstace().takePhoto(path, channel, 0, 0); - } + if (paths == null || paths.length == 0) { + return null; } - return res; + File path = paths[0]; + if (!path.exists() && !path.mkdirs()) { + return null; + } + String p = path.getAbsolutePath(); + if (!p.endsWith(File.separator)) { + p += File.separator; + } + return p; } - */ - + public String buildPhotoDir(Context contxt, int channel) { + // File path = new File(Environment.getExternalStorageDirectory(), "com.xinyingpower.mp/photos/"); - protected boolean updateTime(long timeInMillis) { - boolean res = false; - try { - // Calendar c = Calendar.getInstance(); - // c.set(2010, 1, 1, 12, 00, 00); - AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); - am.setTime(timeInMillis); - res = true; - } catch (Exception ex) { - int aa = 0; + String appDir = buildAppDir(contxt); + if (appDir == null) { + return null; } - return true; - } - public String buildPhotoDir(int channel) { - File path = new File(Environment.getExternalStorageDirectory(), "com.xyp.mp/photos/"); + File path = new File(appDir, "photos/"); if (!path.exists() && !path.mkdirs()) { return null; @@ -762,6 +645,20 @@ public class MicroPhotoService extends Service { } + public boolean updateTime(long timeInMillis) { + boolean res = false; + try { + // Calendar c = Calendar.getInstance(); + // c.set(2010, 1, 1, 12, 00, 00); + AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); + am.setTime(timeInMillis); + res = true; + } catch (Exception ex) { + int aa = 0; + } + return true; + } + /* TelephonyManager telephonyManager = (TelephonyManager)this.getSystemService(Context.TELEPHONY_SERVICE); // for example value of first element @@ -773,7 +670,7 @@ cellSignalStrengthGsm.getDbm(); protected native long init(String appPath, String ip, int port, String cmdid); protected native long getHeartbeatDuration(long handler); protected native long[] getPhotoTimeData(long handler); - protected native long[] getNextScheduleItem(long handler); + // protected native long[] getNextScheduleItem(long handler); protected native boolean notifyToTakePhoto(long handler, int channel, int preset, long scheduleTime, String path, String fileName, boolean sendToCma); protected native boolean sendHeartbeat(long handler); protected native boolean fireTimeout(long handler, long uid); diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 2fb2d483..93a913d9 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -4,133 +4,145 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:clickable="false" android:orientation="horizontal" tools:context=".MainActivity"> + app:layout_constraintTop_toTopOf="@+id/cmdid" /> + android:text="XY-ANDROIDSIM-001" + app:layout_constraintLeft_toRightOf="@+id/textViewCmdId" + app:layout_constraintTop_toTopOf="parent" /> + android:layout_marginTop="20dp" + android:text="Server" + app:layout_constraintBottom_toBottomOf="@+id/server" + app:layout_constraintStart_toStartOf="@id/textViewCmdId" + app:layout_constraintTop_toTopOf="@+id/server" /> + android:text="47.96.238.157" + app:layout_constraintStart_toStartOf="@+id/cmdid" + app:layout_constraintTop_toBottomOf="@+id/cmdid" /> + +