-
-
\ No newline at end of file
diff --git a/README.md b/README.md
index a6bdc99dd..d09c0f65d 100644
--- a/README.md
+++ b/README.md
@@ -44,7 +44,7 @@ If you want to use Android Studio(unfortunately NDK supporting on Android Studio
5. Android Studio raise some errors but just ignore now. Android Studio generate `local.properties` file. Please open `local.properties` and add `ndk.dir` key to the end of the file. The contents of the file looks like this.
```
sdk.dir={path to Android SDK on your storage}
-ndk.dir={path to Android SDK on your storage}
+ndk.dir={path to Android NDK on your storage}
```
Please replace actual path to SDK and NDK on your storage.
Of course you can make `local.properties` by manually instead of using automatically generated ones by Android Studio.
diff --git a/UVCCamera.iml b/UVCCamera.iml
index e9836a27d..757acfb3b 100644
--- a/UVCCamera.iml
+++ b/UVCCamera.iml
@@ -1,19 +1,12 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
-
+
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 3287a8720..6b881ebec 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,22 +1,20 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- repositories {
-// google()
- maven { url 'https://maven.google.com' }
- jcenter()
- }
- dependencies {
- classpath 'com.android.tools.build:gradle:3.1.4'
- }
+ repositories {
+ jcenter()
+ google()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:7.2.1'
+ }
}
allprojects {
- repositories {
-// google()
- maven { url 'https://maven.google.com' }
+ repositories {
+ maven { url 'https://raw.github.com/saki4510t/libcommon/master/repository/' }
jcenter()
- maven { url 'http://raw.github.com/saki4510t/libcommon/master/repository/' }
- }
+ google()
+ }
}
task clean(type: Delete) {
@@ -26,9 +24,9 @@ task clean(type: Delete) {
ext {
supportLibVersion = '27.1.1' // variable that can be referenced to keep support libs consistent
commonLibVersion= '2.12.4'
- versionBuildTool = '27.0.3'
- versionCompiler = 27
- versionTarget = 27
+ versionCompiler = 34
+ versionTarget = 34
+ minTargetVersion = 30
versionNameString = '1.0.0'
javaSourceCompatibility = JavaVersion.VERSION_1_8
javaTargetCompatibility = JavaVersion.VERSION_1_8
diff --git a/gradle.properties b/gradle.properties
index 2c1f15099..f30eb8d10 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -10,7 +10,7 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
-org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+org.gradle.jvmargs=-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 000000000..13372aef5
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 17daf5c34..aa991fcea 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Tue Oct 02 16:16:11 JST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
diff --git a/gradlew b/gradlew
index 91a7e269e..9d82f7891 100755
--- a/gradlew
+++ b/gradlew
@@ -42,11 +42,6 @@ case "`uname`" in
;;
esac
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -61,9 +56,9 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
+cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
+cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -114,6 +109,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
diff --git a/libuvccamera/build.gradle b/libuvccamera/build.gradle
index 6025fe8c2..d95f9e811 100644
--- a/libuvccamera/build.gradle
+++ b/libuvccamera/build.gradle
@@ -25,8 +25,7 @@ apply plugin: 'com.android.library'
import org.apache.tools.ant.taskdefs.condition.Os
android {
- compileSdkVersion versionCompiler
- buildToolsVersion versionBuildTool
+ compileSdk versionCompiler
compileOptions {
sourceCompatibility javaSourceCompatibility
@@ -34,7 +33,7 @@ android {
}
defaultConfig {
- minSdkVersion 14
+ minSdkVersion minTargetVersion
targetSdkVersion versionTarget
}
@@ -58,13 +57,16 @@ tasks.withType(JavaCompile) {
String getNdkBuildPath() {
Properties properties = new Properties()
- properties.load(project.rootProject.file('local.properties').newDataInputStream())
- def ndkBuildingDir = properties.getProperty("ndk.dir")
- def ndkBuildPath = ndkBuildingDir
+ def ndkBuildPath = "";
+ def ndkBuildingDir = "";
+ if (project.rootProject.file("local.properties").exists()) {
+ properties.load(project.rootProject.file('local.properties').newDataInputStream())
+ ndkBuildingDir = properties.getProperty("ndk.dir") + '/'
+ }
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
- ndkBuildPath = ndkBuildingDir + '/ndk-build.cmd'
+ ndkBuildPath = ndkBuildingDir + 'ndk-build.cmd'
} else {
- ndkBuildPath = ndkBuildingDir + '/ndk-build'
+ ndkBuildPath = ndkBuildingDir + 'ndk-build'
}
return ndkBuildPath
}
@@ -86,7 +88,6 @@ clean.dependsOn 'ndkClean'
dependencies {
implementation fileTree(dir: new File(buildDir, 'libs'), include: '*.jar')
- implementation "com.android.support:support-v4:${supportLibVersion}"
implementation "com.android.support:support-annotations:${supportLibVersion}"
implementation("com.serenegiant:common:${commonLibVersion}") {
diff --git a/libuvccamera/src/main/AndroidManifest.xml b/libuvccamera/src/main/AndroidManifest.xml
index 8a2f33f49..730106ed7 100644
--- a/libuvccamera/src/main/AndroidManifest.xml
+++ b/libuvccamera/src/main/AndroidManifest.xml
@@ -26,8 +26,4 @@
android:versionCode="2"
android:versionName="1.1" >
-
-
diff --git a/libuvccamera/src/main/java/com/serenegiant/common/BaseActivity.java b/libuvccamera/src/main/java/com/serenegiant/common/BaseActivity.java
index 89262ca26..96783e699 100644
--- a/libuvccamera/src/main/java/com/serenegiant/common/BaseActivity.java
+++ b/libuvccamera/src/main/java/com/serenegiant/common/BaseActivity.java
@@ -26,15 +26,18 @@
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
-import android.support.v7.app.AppCompatActivity;
+import android.app.Activity;
import android.util.Log;
import android.widget.Toast;
+import com.serenegiant.dialog.MessageDialogFragment;
import com.serenegiant.dialog.MessageDialogFragmentV4;
import com.serenegiant.utils.BuildCheck;
import com.serenegiant.utils.HandlerThreadHandler;
@@ -44,7 +47,7 @@
* Created by saki on 2016/11/18.
*
*/
-public class BaseActivity extends AppCompatActivity
+public class BaseActivity extends Activity
implements MessageDialogFragmentV4.MessageDialogListener {
private static boolean DEBUG = false; // FIXME 実働時はfalseにセットすること
@@ -277,11 +280,15 @@ protected void checkPermissionResult(final int requestCode, final String permiss
* @return true 外部ストレージへの書き込みパーミッションが有る
*/
protected boolean checkPermissionWriteExternalStorage() {
- if (!PermissionCheck.hasWriteExternalStorage(this)) {
- MessageDialogFragmentV4.showDialog(this, REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE,
- R.string.permission_title, R.string.permission_ext_storage_request,
- new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE});
- return false;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S_V2) {
+ return Environment.isExternalStorageManager() || Environment.isExternalStorageEmulated();
+ } else {
+ if (!PermissionCheck.hasWriteExternalStorage(this)) {
+ MessageDialogFragment.showDialog(this, REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE,
+ R.string.permission_title, R.string.permission_ext_storage_request,
+ new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE});
+ return false;
+ }
}
return true;
}
@@ -293,7 +300,7 @@ protected boolean checkPermissionWriteExternalStorage() {
*/
protected boolean checkPermissionAudio() {
if (!PermissionCheck.hasAudio(this)) {
- MessageDialogFragmentV4.showDialog(this, REQUEST_PERMISSION_AUDIO_RECORDING,
+ MessageDialogFragment.showDialog(this, REQUEST_PERMISSION_AUDIO_RECORDING,
R.string.permission_title, R.string.permission_audio_recording_request,
new String[]{Manifest.permission.RECORD_AUDIO});
return false;
@@ -308,7 +315,7 @@ protected boolean checkPermissionAudio() {
*/
protected boolean checkPermissionNetwork() {
if (!PermissionCheck.hasNetwork(this)) {
- MessageDialogFragmentV4.showDialog(this, REQUEST_PERMISSION_NETWORK,
+ MessageDialogFragment.showDialog(this, REQUEST_PERMISSION_NETWORK,
R.string.permission_title, R.string.permission_network_request,
new String[]{Manifest.permission.INTERNET});
return false;
@@ -323,7 +330,7 @@ protected boolean checkPermissionNetwork() {
*/
protected boolean checkPermissionCamera() {
if (!PermissionCheck.hasCamera(this)) {
- MessageDialogFragmentV4.showDialog(this, REQUEST_PERMISSION_CAMERA,
+ MessageDialogFragment.showDialog(this, REQUEST_PERMISSION_CAMERA,
R.string.permission_title, R.string.permission_camera_request,
new String[]{Manifest.permission.CAMERA});
return false;
diff --git a/libuvccamera/src/main/java/com/serenegiant/common/BaseFragment.java b/libuvccamera/src/main/java/com/serenegiant/common/BaseFragment.java
index cdb07fe4c..4318bda8b 100644
--- a/libuvccamera/src/main/java/com/serenegiant/common/BaseFragment.java
+++ b/libuvccamera/src/main/java/com/serenegiant/common/BaseFragment.java
@@ -27,7 +27,9 @@
import android.annotation.SuppressLint;
import android.app.Fragment;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.os.Bundle;
+import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
@@ -285,11 +287,15 @@ protected void checkPermissionResult(final int requestCode, final String permiss
* @return true 外部ストレージへの書き込みパーミッションが有る
*/
protected boolean checkPermissionWriteExternalStorage() {
- if (!PermissionCheck.hasWriteExternalStorage(getActivity())) {
- MessageDialogFragment.showDialog(this, REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE,
- com.serenegiant.common.R.string.permission_title, com.serenegiant.common.R.string.permission_ext_storage_request,
- new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE});
- return false;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S_V2) {
+ return Environment.isExternalStorageManager() || Environment.isExternalStorageEmulated();
+ } else {
+ if (!PermissionCheck.hasWriteExternalStorage(getActivity())) {
+ MessageDialogFragment.showDialog(this, REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE,
+ R.string.permission_title, R.string.permission_ext_storage_request,
+ new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE});
+ return false;
+ }
}
return true;
}
diff --git a/libuvccamera/src/main/java/com/serenegiant/usb/USBMonitor.java b/libuvccamera/src/main/java/com/serenegiant/usb/USBMonitor.java
index 722dd3613..abfd37a70 100644
--- a/libuvccamera/src/main/java/com/serenegiant/usb/USBMonitor.java
+++ b/libuvccamera/src/main/java/com/serenegiant/usb/USBMonitor.java
@@ -43,6 +43,7 @@
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
+import android.os.Build;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
@@ -167,11 +168,21 @@ public synchronized void register() throws IllegalStateException {
if (DEBUG) Log.i(TAG, "register:");
final Context context = mWeakContext.get();
if (context != null) {
- mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), 0);
+ mPermissionIntent = PendingIntent.getBroadcast(context, 0, new Intent(ACTION_USB_PERMISSION), PendingIntent.FLAG_IMMUTABLE);
final IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
// ACTION_USB_DEVICE_ATTACHED never comes on some devices so it should not be added here
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
- context.registerReceiver(mUsbReceiver, filter);
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ // For Android 13 (API level 33) and above, use receiver flags
+ context.registerReceiver(mUsbReceiver, filter, Context.RECEIVER_NOT_EXPORTED);
+ } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ // For Android 12 (API level 31) and above
+ context.registerReceiver(mUsbReceiver, filter);
+ } else {
+ // For older versions of Android
+ context.registerReceiver(mUsbReceiver, filter);
+ }
}
// start connection check
mDeviceCounts = 0;
@@ -660,7 +671,11 @@ public static final String getDeviceKeyName(final UsbDevice device, final String
if (useNewAPI && BuildCheck.isAndroid5()) {
sb.append("#");
if (TextUtils.isEmpty(serial)) {
- sb.append(device.getSerialNumber()); sb.append("#"); // API >= 21
+ try {
+ sb.append(device.getSerialNumber());
+ sb.append("#");
+ } // API >= 21 & targetSdkVersion has to be <= 28
+ catch(SecurityException ignore) {}
}
sb.append(device.getManufacturerName()); sb.append("#"); // API >= 21
sb.append(device.getConfigurationCount()); sb.append("#"); // API >= 21
diff --git a/libuvccamera/src/main/jni/Application.mk b/libuvccamera/src/main/jni/Application.mk
index c6f7c2e1b..01b07c4b4 100644
--- a/libuvccamera/src/main/jni/Application.mk
+++ b/libuvccamera/src/main/jni/Application.mk
@@ -26,7 +26,7 @@
# Note: Supporting GCC on NDK is already deprecated and GCC will be removed from NDK soon.
#NDK_TOOLCHAIN_VERSION := 4.9
-APP_PLATFORM := android-14
-APP_ABI := armeabi armeabi-v7a x86 mips
+APP_PLATFORM := android-21
+APP_ABI := armeabi-v7a arm64-v8a
#APP_OPTIM := debug
APP_OPTIM := release
diff --git a/libuvccamera/src/main/jni/UVCCamera/UVCPreview.cpp b/libuvccamera/src/main/jni/UVCCamera/UVCPreview.cpp
index 02c1a60b8..391d82f45 100644
--- a/libuvccamera/src/main/jni/UVCCamera/UVCPreview.cpp
+++ b/libuvccamera/src/main/jni/UVCCamera/UVCPreview.cpp
@@ -845,7 +845,7 @@ void UVCPreview::do_capture_surface(JNIEnv *env) {
*/
void UVCPreview::do_capture_callback(JNIEnv *env, uvc_frame_t *frame) {
ENTER();
-
+ pthread_mutex_lock(&capture_mutex);
if (LIKELY(frame)) {
uvc_frame_t *callback_frame = frame;
if (mFrameCallbackObj) {
@@ -872,5 +872,6 @@ void UVCPreview::do_capture_callback(JNIEnv *env, uvc_frame_t *frame) {
SKIP:
recycle_frame(callback_frame);
}
+ pthread_mutex_unlock(&capture_mutex);
EXIT();
}
diff --git a/libuvccamera/src/main/jni/libusb/libusb/os/android_usbfs.c b/libuvccamera/src/main/jni/libusb/libusb/os/android_usbfs.c
index 86265959e..0d52e7384 100644
--- a/libuvccamera/src/main/jni/libusb/libusb/os/android_usbfs.c
+++ b/libuvccamera/src/main/jni/libusb/libusb/os/android_usbfs.c
@@ -1311,10 +1311,10 @@ static int android_initialize_device(struct libusb_device *dev,
priv->descriptors_len = 0;
priv->fd = 0;
memset(desc, 0, sizeof(desc));
- if (!lseek(fd, 0, SEEK_SET)) {
- // ディスクリプタを読み込んでローカルキャッシュする
- int length = read(fd, desc, sizeof(desc));
- LOGD("Device::init read returned %d errno %d\n", length, errno);
+ if (!lseek(fd, 0, SEEK_SET)) {
+ // ディスクリプタを読み込んでローカルキャッシュする
+ int length = read(fd, desc, sizeof(desc));
+ LOGD("Device::init read returned %d errno %d\n", length, errno);
if (length > 0) {
priv->fd = fd;
priv->descriptors = usbi_reallocf(priv->descriptors, length);
@@ -1383,36 +1383,36 @@ int android_generate_device(struct libusb_context *ctx, struct libusb_device **d
int r = 0;
*dev = NULL;
- /* FIXME: session ID is not guaranteed unique as addresses can wrap and
- * will be reused. instead we should add a simple sysfs attribute with
- * a session ID. */
+ /* FIXME: session ID is not guaranteed unique as addresses can wrap and
+ * will be reused. instead we should add a simple sysfs attribute with
+ * a session ID. */
session_id = busnum << 8 | devaddr;
- LOGD("allocating new device for %d/%d (session %ld)", busnum, devaddr, session_id);
- *dev = usbi_alloc_device(ctx, session_id); // この時点で参照カウンタ=1
- if (UNLIKELY(!dev)) {
- RETURN(LIBUSB_ERROR_NO_MEM, int);
- }
-
- r = android_initialize_device(*dev, busnum, devaddr, fd);
- if (UNLIKELY(r < 0)) {
- LOGE("initialize_device failed: ret=%d", r);
- goto out;
- }
- r = usbi_sanitize_device(*dev);
- if (UNLIKELY(r < 0)) {
- LOGE("usbi_sanitize_device failed: ret=%d", r);
- goto out;
- }
+ LOGD("allocating new device for %d/%d (session %ld)", busnum, devaddr, session_id);
+ *dev = usbi_alloc_device(ctx, session_id); // この時点で参照カウンタ=1
+ if (UNLIKELY(!dev)) {
+ RETURN(LIBUSB_ERROR_NO_MEM, int);
+ }
+
+ r = android_initialize_device(*dev, busnum, devaddr, fd);
+ if (UNLIKELY(r < 0)) {
+ LOGE("initialize_device failed: ret=%d", r);
+ goto out;
+ }
+ r = usbi_sanitize_device(*dev);
+ if (UNLIKELY(r < 0)) {
+ LOGE("usbi_sanitize_device failed: ret=%d", r);
+ goto out;
+ }
out:
- if (UNLIKELY(r < 0)) {
- libusb_unref_device(*dev); // ここで参照カウンタが0になって破棄される
- *dev = NULL;
- } else {
- usbi_connect_device(*dev);
- }
+ if (UNLIKELY(r < 0)) {
+ libusb_unref_device(*dev); // ここで参照カウンタが0になって破棄される
+ *dev = NULL;
+ } else {
+ usbi_connect_device(*dev);
+ }
- RETURN(r, int);
+ RETURN(r, int);
}
@@ -2726,6 +2726,9 @@ static int handle_iso_completion(struct libusb_device_handle *handle, // XXX add
usbi_mutex_lock(&itransfer->lock);
for (i = 0; i < num_urbs; i++) {
+ if(tpriv->iso_urbs == NULL){
+ return LIBUSB_TRANSFER_ERROR;
+ }
if (urb == tpriv->iso_urbs[i]) {
urb_idx = i + 1;
break;
@@ -2926,7 +2929,13 @@ static int reap_for_handle(struct libusb_device_handle *handle) {
usbi_dbg("urb type=%d status=%d transferred=%d",
urb->type, urb->status, urb->actual_length);
-
+
+ // if not check status, will crash when target > 27
+ // current error status is -108
+ if(urb->status == -108){
+ return LIBUSB_ERROR_OTHER;
+ }
+
switch (transfer->type) {
case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
return handle_iso_completion(handle, itransfer, urb);
diff --git a/usbCameraCommon/build.gradle b/usbCameraCommon/build.gradle
index 92ed5a9d9..243d56c74 100644
--- a/usbCameraCommon/build.gradle
+++ b/usbCameraCommon/build.gradle
@@ -24,8 +24,7 @@
apply plugin: 'com.android.library'
android {
- compileSdkVersion versionCompiler
- buildToolsVersion versionBuildTool
+ compileSdk versionCompiler
compileOptions {
sourceCompatibility javaSourceCompatibility
@@ -33,7 +32,7 @@ android {
}
defaultConfig {
- minSdkVersion 18
+ minSdkVersion minTargetVersion
targetSdkVersion versionTarget
}
@@ -48,7 +47,6 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- implementation "com.android.support:support-v4:${supportLibVersion}"
implementation "com.android.support:support-annotations:${supportLibVersion}"
implementation("com.serenegiant:common:${commonLibVersion}") {
diff --git a/usbCameraCommon/src/main/AndroidManifest.xml b/usbCameraCommon/src/main/AndroidManifest.xml
index 67c59eab7..95180b680 100644
--- a/usbCameraCommon/src/main/AndroidManifest.xml
+++ b/usbCameraCommon/src/main/AndroidManifest.xml
@@ -21,4 +21,5 @@
~ may have a different license, see the respective files.
-->
-
+
+
diff --git a/usbCameraCommon/src/main/java/com/serenegiant/encoder/MediaAudioEncoder.java b/usbCameraCommon/src/main/java/com/serenegiant/encoder/MediaAudioEncoder.java
index a6a9010f6..ba6d07fba 100644
--- a/usbCameraCommon/src/main/java/com/serenegiant/encoder/MediaAudioEncoder.java
+++ b/usbCameraCommon/src/main/java/com/serenegiant/encoder/MediaAudioEncoder.java
@@ -27,6 +27,7 @@
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
+import android.annotation.SuppressLint;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaCodec;
@@ -37,16 +38,16 @@
import android.util.Log;
public class MediaAudioEncoder extends MediaEncoder implements IAudioEncoder {
- private static final boolean DEBUG = true; // TODO set false on release
+ private static final boolean DEBUG = true; // TODO set false on release
private static final String TAG = "MediaAudioEncoder";
private static final String MIME_TYPE = "audio/mp4a-latm";
- private static final int SAMPLE_RATE = 44100; // 44.1[KHz] is only setting guaranteed to be available on all devices.
- private static final int BIT_RATE = 64000;
- public static final int SAMPLES_PER_FRAME = 1024; // AAC, bytes/frame/channel
- public static final int FRAMES_PER_BUFFER = 25; // AAC, frame/buffer/sec
+ private static final int SAMPLE_RATE = 44100; // 44.1[KHz] is only setting guaranteed to be available on all devices.
+ private static final int BIT_RATE = 64000;
+ public static final int SAMPLES_PER_FRAME = 1024; // AAC, bytes/frame/channel
+ public static final int FRAMES_PER_BUFFER = 25; // AAC, frame/buffer/sec
- private AudioThread mAudioThread = null;
+ private AudioThread mAudioThread = null;
public MediaAudioEncoder(final MediaMuxerWrapper muxer, final MediaEncoderListener listener) {
super(muxer, listener);
@@ -55,52 +56,52 @@ public MediaAudioEncoder(final MediaMuxerWrapper muxer, final MediaEncoderListen
@Override
protected void prepare() throws IOException {
if (DEBUG) Log.v(TAG, "prepare:");
- mTrackIndex = -1;
- mMuxerStarted = mIsEOS = false;
- // prepare MediaCodec for AAC encoding of audio data from inernal mic.
- final MediaCodecInfo audioCodecInfo = selectAudioCodec(MIME_TYPE);
- if (audioCodecInfo == null) {
- Log.e(TAG, "Unable to find an appropriate codec for " + MIME_TYPE);
- return;
- }
+ mTrackIndex = -1;
+ mMuxerStarted = mIsEOS = false;
+ // prepare MediaCodec for AAC encoding of audio data from inernal mic.
+ final MediaCodecInfo audioCodecInfo = selectAudioCodec(MIME_TYPE);
+ if (audioCodecInfo == null) {
+ Log.e(TAG, "Unable to find an appropriate codec for " + MIME_TYPE);
+ return;
+ }
if (DEBUG) Log.i(TAG, "selected codec: " + audioCodecInfo.getName());
- final MediaFormat audioFormat = MediaFormat.createAudioFormat(MIME_TYPE, SAMPLE_RATE, 1);
+ final MediaFormat audioFormat = MediaFormat.createAudioFormat(MIME_TYPE, SAMPLE_RATE, 1);
audioFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC);
audioFormat.setInteger(MediaFormat.KEY_CHANNEL_MASK, AudioFormat.CHANNEL_IN_MONO);
audioFormat.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE);
audioFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
-// audioFormat.setLong(MediaFormat.KEY_MAX_INPUT_SIZE, inputFile.length());
+// audioFormat.setLong(MediaFormat.KEY_MAX_INPUT_SIZE, inputFile.length());
// audioFormat.setLong(MediaFormat.KEY_DURATION, (long)durationInMs );
if (DEBUG) Log.i(TAG, "format: " + audioFormat);
- mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE);
- mMediaCodec.configure(audioFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
- mMediaCodec.start();
- if (DEBUG) Log.i(TAG, "prepare finishing");
- if (mListener != null) {
- try {
- mListener.onPrepared(this);
- } catch (final Exception e) {
- Log.e(TAG, "prepare:", e);
- }
- }
+ mMediaCodec = MediaCodec.createEncoderByType(MIME_TYPE);
+ mMediaCodec.configure(audioFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
+ mMediaCodec.start();
+ if (DEBUG) Log.i(TAG, "prepare finishing");
+ if (mListener != null) {
+ try {
+ mListener.onPrepared(this);
+ } catch (final Exception e) {
+ Log.e(TAG, "prepare:", e);
+ }
+ }
}
- @Override
+ @Override
protected void startRecording() {
super.startRecording();
// create and execute audio capturing thread using internal mic
if (mAudioThread == null) {
- mAudioThread = new AudioThread();
+ mAudioThread = new AudioThread();
mAudioThread.start();
}
}
@Override
- protected void release() {
+ protected void release() {
mAudioThread = null;
super.release();
- }
+ }
private static final int[] AUDIO_SOURCES = new int[] {
MediaRecorder.AudioSource.DEFAULT,
@@ -112,9 +113,10 @@ protected void release() {
* Thread to capture audio data from internal mic as uncompressed 16bit PCM data
* and write them to the MediaCodec encoder
*/
- private class AudioThread extends Thread {
- @Override
- public void run() {
+ private class AudioThread extends Thread {
+ @Override
+ @SuppressLint("MissingPermission")
+ public void run() {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO); // THREAD_PRIORITY_URGENT_AUDIO
int cnt = 0;
final int min_buffer_size = AudioRecord.getMinBufferSize(
@@ -132,7 +134,7 @@ public void run() {
if (audioRecord.getState() != AudioRecord.STATE_INITIALIZED) {
audioRecord.release();
audioRecord = null;
- }
+ }
}
} catch (final Exception e) {
audioRecord = null;
@@ -197,37 +199,37 @@ public void run() {
}
}
if (DEBUG) Log.v(TAG, "AudioThread:finished");
- }
- }
-
- /**
- * select the first codec that match a specific MIME type
- * @param mimeType
- * @return
- */
- private static final MediaCodecInfo selectAudioCodec(final String mimeType) {
- if (DEBUG) Log.v(TAG, "selectAudioCodec:");
-
- MediaCodecInfo result = null;
- // get the list of available codecs
- final int numCodecs = MediaCodecList.getCodecCount();
-LOOP: for (int i = 0; i < numCodecs; i++) {
- final MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
- if (!codecInfo.isEncoder()) { // skipp decoder
- continue;
- }
- final String[] types = codecInfo.getSupportedTypes();
- for (int j = 0; j < types.length; j++) {
- if (DEBUG) Log.i(TAG, "supportedType:" + codecInfo.getName() + ",MIME=" + types[j]);
- if (types[j].equalsIgnoreCase(mimeType)) {
- if (result == null) {
- result = codecInfo;
- break LOOP;
- }
- }
- }
- }
- return result;
- }
+ }
+ }
+
+ /**
+ * select the first codec that match a specific MIME type
+ * @param mimeType
+ * @return
+ */
+ private static final MediaCodecInfo selectAudioCodec(final String mimeType) {
+ if (DEBUG) Log.v(TAG, "selectAudioCodec:");
+
+ MediaCodecInfo result = null;
+ // get the list of available codecs
+ final int numCodecs = MediaCodecList.getCodecCount();
+LOOP: for (int i = 0; i < numCodecs; i++) {
+ final MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
+ if (!codecInfo.isEncoder()) { // skipp decoder
+ continue;
+ }
+ final String[] types = codecInfo.getSupportedTypes();
+ for (int j = 0; j < types.length; j++) {
+ if (DEBUG) Log.i(TAG, "supportedType:" + codecInfo.getName() + ",MIME=" + types[j]);
+ if (types[j].equalsIgnoreCase(mimeType)) {
+ if (result == null) {
+ result = codecInfo;
+ break LOOP;
+ }
+ }
+ }
+ }
+ return result;
+ }
}
diff --git a/usbCameraCommon/src/main/java/com/serenegiant/usbcameracommon/AbstractUVCCameraHandler.java b/usbCameraCommon/src/main/java/com/serenegiant/usbcameracommon/AbstractUVCCameraHandler.java
index b368a1cfc..22ba3da78 100644
--- a/usbCameraCommon/src/main/java/com/serenegiant/usbcameracommon/AbstractUVCCameraHandler.java
+++ b/usbCameraCommon/src/main/java/com/serenegiant/usbcameracommon/AbstractUVCCameraHandler.java
@@ -23,6 +23,7 @@
package com.serenegiant.usbcameracommon;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
@@ -31,6 +32,7 @@
import android.media.AudioManager;
import android.media.MediaScannerConnection;
import android.media.SoundPool;
+import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
@@ -65,7 +67,7 @@
import java.util.concurrent.CopyOnWriteArraySet;
abstract class AbstractUVCCameraHandler extends Handler {
- private static final boolean DEBUG = true; // TODO set false on release
+ private static final boolean DEBUG = true; // TODO set false on release
private static final String TAG = "AbsUVCCameraHandler";
public interface CameraCallback {
@@ -515,7 +517,7 @@ public void handleCaptureStill(final String path) {
if (DEBUG) Log.v(TAG_THREAD, "handleCaptureStill:");
final Activity parent = mWeakParent.get();
if (parent == null) return;
- mSoundPool.play(mSoundId, 0.2f, 0.2f, 0, 0, 1.0f); // play shutter sound
+ mSoundPool.play(mSoundId, 0.2f, 0.2f, 0, 0, 1.0f); // play shutter sound
try {
final Bitmap bitmap = mWeakCameraView.get().captureStillImage();
// get buffered output stream for saving a captured still image as a file on external storage.
@@ -544,16 +546,16 @@ public void handleStartRecording() {
if (DEBUG) Log.v(TAG_THREAD, "handleStartRecording:");
try {
if ((mUVCCamera == null) || (mMuxer != null)) return;
- final MediaMuxerWrapper muxer = new MediaMuxerWrapper(".mp4"); // if you record audio only, ".m4a" is also OK.
+ final MediaMuxerWrapper muxer = new MediaMuxerWrapper(".mp4"); // if you record audio only, ".m4a" is also OK.
MediaVideoBufferEncoder videoEncoder = null;
switch (mEncoderType) {
- case 1: // for video capturing using MediaVideoEncoder
+ case 1: // for video capturing using MediaVideoEncoder
new MediaVideoEncoder(muxer, getWidth(), getHeight(), mMediaEncoderListener);
break;
- case 2: // for video capturing using MediaVideoBufferEncoder
+ case 2: // for video capturing using MediaVideoBufferEncoder
videoEncoder = new MediaVideoBufferEncoder(muxer, getWidth(), getHeight(), mMediaEncoderListener);
break;
- // case 0: // for video capturing using MediaSurfaceEncoder
+ // case 0: // for video capturing using MediaSurfaceEncoder
default:
new MediaSurfaceEncoder(muxer, getWidth(), getHeight(), mMediaEncoderListener);
break;
@@ -700,27 +702,37 @@ public void onStopped(final MediaEncoder encoder) {
/**
* prepare and load shutter sound for still image capturing
*/
- @SuppressWarnings("deprecation")
- private void loadShutterSound(final Context context) {
- // get system stream type using reflection
- int streamType;
- try {
- final Class> audioSystemClass = Class.forName("android.media.AudioSystem");
- final Field sseField = audioSystemClass.getDeclaredField("STREAM_SYSTEM_ENFORCED");
- streamType = sseField.getInt(null);
- } catch (final Exception e) {
- streamType = AudioManager.STREAM_SYSTEM; // set appropriate according to your app policy
- }
- if (mSoundPool != null) {
- try {
- mSoundPool.release();
- } catch (final Exception e) {
- }
- mSoundPool = null;
- }
- // load shutter sound from resource
- mSoundPool = new SoundPool(2, streamType, 0);
- mSoundId = mSoundPool.load(context, R.raw.camera_click, 1);
+ @SuppressLint("SoonBlockedPrivateApi")
+ protected void loadShutterSound(final Context context) {
+ // Define a default stream type
+ int streamType = AudioManager.STREAM_SYSTEM;
+
+ // Conditionally handle reflection based on the Android version
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S_V2) { // API 32 is Android 12L
+ try {
+ // Use reflection only for older versions
+ final Class> audioSystemClass = Class.forName("android.media.AudioSystem");
+ final Field sseField = audioSystemClass.getDeclaredField("STREAM_SYSTEM_ENFORCED");
+ streamType = sseField.getInt(null);
+ } catch (final Exception e) {
+ // If reflection fails, fall back to STREAM_SYSTEM
+ streamType = AudioManager.STREAM_SYSTEM;
+ }
+ }
+
+ // Clean up existing SoundPool instance if necessary
+ if (mSoundPool != null) {
+ try {
+ mSoundPool.release();
+ } catch (final Exception e) {
+ // Handle the exception (optional)
+ }
+ mSoundPool = null;
+ }
+
+ // Initialize the SoundPool and load the shutter sound
+ mSoundPool = new SoundPool(2, streamType, 0);
+ mSoundId = mSoundPool.load(context, R.raw.camera_click, 1);
}
@Override
diff --git a/usbCameraTest/build.gradle b/usbCameraTest/build.gradle
index da5a1c139..55d8e8008 100644
--- a/usbCameraTest/build.gradle
+++ b/usbCameraTest/build.gradle
@@ -25,7 +25,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion versionCompiler
- buildToolsVersion versionBuildTool
compileOptions {
sourceCompatibility javaSourceCompatibility
@@ -34,7 +33,7 @@ android {
defaultConfig {
applicationId "com.serenegiant.usbcameratest"
- minSdkVersion 14
+ minSdkVersion minTargetVersion
targetSdkVersion versionTarget
versionCode 8
versionName "3.00"
@@ -51,7 +50,6 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- implementation "com.android.support:support-v4:${supportLibVersion}"
implementation "com.android.support:support-annotations:${supportLibVersion}"
implementation("com.serenegiant:common:${commonLibVersion}") {
diff --git a/usbCameraTest/src/main/AndroidManifest.xml b/usbCameraTest/src/main/AndroidManifest.xml
index a2abf49a9..dcc18c307 100644
--- a/usbCameraTest/src/main/AndroidManifest.xml
+++ b/usbCameraTest/src/main/AndroidManifest.xml
@@ -31,7 +31,8 @@
android:theme="@style/AppTheme" >
+ android:label="@string/app_name"
+ android:exported="true">
diff --git a/usbCameraTest/src/main/res/layout/activity_main.xml b/usbCameraTest/src/main/res/layout/activity_main.xml
index 5ca52e562..cde370285 100644
--- a/usbCameraTest/src/main/res/layout/activity_main.xml
+++ b/usbCameraTest/src/main/res/layout/activity_main.xml
@@ -34,7 +34,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
- android:background="#ff000000" />
+ android:background="@null" />
+ 24sp16dp16dp48dp
diff --git a/usbCameraTest0/build.gradle b/usbCameraTest0/build.gradle
index cc233b045..ee17236c9 100644
--- a/usbCameraTest0/build.gradle
+++ b/usbCameraTest0/build.gradle
@@ -25,7 +25,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion versionCompiler
- buildToolsVersion versionBuildTool
compileOptions {
sourceCompatibility javaSourceCompatibility
@@ -34,7 +33,7 @@ android {
defaultConfig {
applicationId "com.serenegiant.usbcameratest0"
- minSdkVersion 14
+ minSdkVersion minTargetVersion
targetSdkVersion versionTarget
versionCode 8
versionName "3.00"
@@ -51,7 +50,6 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- implementation "com.android.support:support-v4:${supportLibVersion}"
implementation "com.android.support:support-annotations:${supportLibVersion}"
implementation("com.serenegiant:common:${commonLibVersion}") {
diff --git a/usbCameraTest0/src/main/AndroidManifest.xml b/usbCameraTest0/src/main/AndroidManifest.xml
index 015e549fc..ab263c4dc 100644
--- a/usbCameraTest0/src/main/AndroidManifest.xml
+++ b/usbCameraTest0/src/main/AndroidManifest.xml
@@ -31,7 +31,8 @@
android:theme="@style/AppTheme" >
+ android:label="@string/app_name"
+ android:exported="true">
diff --git a/usbCameraTest0/src/main/res/values/dimens.xml b/usbCameraTest0/src/main/res/values/dimens.xml
index 9c8e51ac3..68161865d 100644
--- a/usbCameraTest0/src/main/res/values/dimens.xml
+++ b/usbCameraTest0/src/main/res/values/dimens.xml
@@ -23,6 +23,7 @@
-->
+ 24sp16dp16dp48dp
diff --git a/usbCameraTest2/build.gradle b/usbCameraTest2/build.gradle
index 6d7160fa7..a75390083 100644
--- a/usbCameraTest2/build.gradle
+++ b/usbCameraTest2/build.gradle
@@ -25,7 +25,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion versionCompiler
- buildToolsVersion versionBuildTool
compileOptions {
sourceCompatibility javaSourceCompatibility
@@ -34,7 +33,7 @@ android {
defaultConfig {
applicationId "com.serenegiant.usbcameratest2"
- minSdkVersion 18
+ minSdkVersion minTargetVersion
targetSdkVersion versionTarget
versionCode 8
versionName "3.00"
@@ -51,7 +50,6 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- implementation "com.android.support:support-v4:${supportLibVersion}"
implementation "com.android.support:support-annotations:${supportLibVersion}"
implementation("com.serenegiant:common:${commonLibVersion}") {
diff --git a/usbCameraTest2/src/main/AndroidManifest.xml b/usbCameraTest2/src/main/AndroidManifest.xml
index 34e65a862..13d8b9bab 100644
--- a/usbCameraTest2/src/main/AndroidManifest.xml
+++ b/usbCameraTest2/src/main/AndroidManifest.xml
@@ -33,7 +33,8 @@
android:theme="@style/AppTheme" >
+ android:label="@string/app_name"
+ android:exported="true">
diff --git a/usbCameraTest2/src/main/res/layout/activity_main.xml b/usbCameraTest2/src/main/res/layout/activity_main.xml
index ae26b4037..131bb9ca4 100644
--- a/usbCameraTest2/src/main/res/layout/activity_main.xml
+++ b/usbCameraTest2/src/main/res/layout/activity_main.xml
@@ -27,7 +27,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff000000"
- tools:context="com.serenegiant.usbcameratest.MainActivity"
+ tools:context="com.serenegiant.usbcameratest2.MainActivity"
tools:ignore="MergeRootFrame" >
+ android:background="@null" />
-
+
+ 24sp16dp16dp48dp
diff --git a/usbCameraTest3/build.gradle b/usbCameraTest3/build.gradle
index 71d65ef70..34f1e9ad0 100644
--- a/usbCameraTest3/build.gradle
+++ b/usbCameraTest3/build.gradle
@@ -25,7 +25,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion versionCompiler
- buildToolsVersion versionBuildTool
compileOptions {
sourceCompatibility javaSourceCompatibility
@@ -34,7 +33,7 @@ android {
defaultConfig {
applicationId "com.serenegiant.usbcameratest3"
- minSdkVersion 18
+ minSdkVersion minTargetVersion
targetSdkVersion versionTarget
versionCode 8
versionName "3.00"
@@ -51,7 +50,6 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- implementation "com.android.support:support-v4:${supportLibVersion}"
implementation "com.android.support:support-annotations:${supportLibVersion}"
implementation("com.serenegiant:common:${commonLibVersion}") {
diff --git a/usbCameraTest3/src/main/AndroidManifest.xml b/usbCameraTest3/src/main/AndroidManifest.xml
index 7b60fda08..c93c69464 100644
--- a/usbCameraTest3/src/main/AndroidManifest.xml
+++ b/usbCameraTest3/src/main/AndroidManifest.xml
@@ -37,7 +37,8 @@
+ android:label="@string/app_name"
+ android:exported="true">
diff --git a/usbCameraTest3/src/main/res/values/dimens.xml b/usbCameraTest3/src/main/res/values/dimens.xml
index 790540d2d..522af662f 100644
--- a/usbCameraTest3/src/main/res/values/dimens.xml
+++ b/usbCameraTest3/src/main/res/values/dimens.xml
@@ -24,6 +24,7 @@
+ 24sp16dp16dp48dp
diff --git a/usbCameraTest4/build.gradle b/usbCameraTest4/build.gradle
index 8b9f98b7f..aedb6d838 100644
--- a/usbCameraTest4/build.gradle
+++ b/usbCameraTest4/build.gradle
@@ -25,7 +25,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion versionCompiler
- buildToolsVersion versionBuildTool
compileOptions {
sourceCompatibility javaSourceCompatibility
@@ -34,7 +33,7 @@ android {
defaultConfig {
applicationId "com.serenegiant.usbcameratest4"
- minSdkVersion 18
+ minSdkVersion minTargetVersion
targetSdkVersion versionTarget
versionCode 9
versionName "3.00"
@@ -51,12 +50,9 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- implementation "com.android.support:support-v4:${supportLibVersion}"
implementation "com.android.support:support-annotations:${supportLibVersion}"
- implementation("com.serenegiant:common:${commonLibVersion}") {
- exclude module: 'support-v4'
- }
+ implementation("com.serenegiant:common:${commonLibVersion}")
implementation project(':libuvccamera')
implementation project(':usbCameraCommon')
}
diff --git a/usbCameraTest4/src/main/AndroidManifest.xml b/usbCameraTest4/src/main/AndroidManifest.xml
index 9fc8b5aa3..76ba38790 100644
--- a/usbCameraTest4/src/main/AndroidManifest.xml
+++ b/usbCameraTest4/src/main/AndroidManifest.xml
@@ -39,7 +39,8 @@
+ android:launchMode="singleTask"
+ android:exported="true">
@@ -57,7 +58,8 @@
+ android:process=":uvcservice"
+ android:exported="true">
diff --git a/usbCameraTest4/src/main/java/com/serenegiant/service/CameraServer.java b/usbCameraTest4/src/main/java/com/serenegiant/service/CameraServer.java
index 21f6a3c5b..f57bad958 100644
--- a/usbCameraTest4/src/main/java/com/serenegiant/service/CameraServer.java
+++ b/usbCameraTest4/src/main/java/com/serenegiant/service/CameraServer.java
@@ -27,10 +27,12 @@
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
+import android.annotation.SuppressLint;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaScannerConnection;
import android.media.SoundPool;
+import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -61,13 +63,13 @@ public final class CameraServer extends Handler {
private int mFrameWidth = DEFAULT_WIDTH, mFrameHeight = DEFAULT_HEIGHT;
- private static class CallbackCookie {
+ private static class CallbackCookie {
boolean isConnected;
}
- private final RemoteCallbackList mCallbacks
+ private final RemoteCallbackList mCallbacks
= new RemoteCallbackList();
- private int mRegisteredCallbackCount;
+ private int mRegisteredCallbackCount;
private RendererHolder mRendererHolder;
private final WeakReference mWeakThread;
@@ -317,7 +319,7 @@ private static final class CameraThread extends Thread {
private static final String TAG_THREAD = "CameraThread";
private final Object mSync = new Object();
private boolean mIsRecording;
- private final WeakReference mWeakContext;
+ private final WeakReference mWeakContext;
private int mEncoderSurfaceId;
private int mFrameWidth, mFrameHeight;
/**
@@ -594,31 +596,42 @@ public void onStopped(final MediaEncoder encoder) {
}
};
+
+
/**
* prepare and load shutter sound for still image capturing
*/
- @SuppressWarnings("deprecation")
- private void loadShutterSound(final Context context) {
- if (DEBUG) Log.d(TAG_THREAD, "loadShutterSound:");
- // get system stream type using refrection
- int streamType;
- try {
- final Class> audioSystemClass = Class.forName("android.media.AudioSystem");
- final Field sseField = audioSystemClass.getDeclaredField("STREAM_SYSTEM_ENFORCED");
- streamType = sseField.getInt(null);
- } catch (final Exception e) {
- streamType = AudioManager.STREAM_SYSTEM; // set appropriate according to your app policy
- }
- if (mSoundPool != null) {
- try {
- mSoundPool.release();
- } catch (final Exception e) {
- }
- mSoundPool = null;
- }
- // load sutter sound from resource
- mSoundPool = new SoundPool(2, streamType, 0);
- mSoundId = mSoundPool.load(context, R.raw.camera_click, 1);
+ @SuppressLint("SoonBlockedPrivateApi")
+ protected void loadShutterSound(final Context context) {
+ // Define a default stream type
+ int streamType = AudioManager.STREAM_SYSTEM;
+
+ // Conditionally handle reflection based on the Android version
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S_V2) { // API 32 is Android 12L
+ try {
+ // Use reflection only for older versions
+ final Class> audioSystemClass = Class.forName("android.media.AudioSystem");
+ final Field sseField = audioSystemClass.getDeclaredField("STREAM_SYSTEM_ENFORCED");
+ streamType = sseField.getInt(null);
+ } catch (final Exception e) {
+ // If reflection fails, fall back to STREAM_SYSTEM
+ streamType = AudioManager.STREAM_SYSTEM;
+ }
+ }
+
+ // Clean up existing SoundPool instance if necessary
+ if (mSoundPool != null) {
+ try {
+ mSoundPool.release();
+ } catch (final Exception e) {
+ // Handle the exception (optional)
+ }
+ mSoundPool = null;
+ }
+
+ // Initialize the SoundPool and load the shutter sound
+ mSoundPool = new SoundPool(2, streamType, 0);
+ mSoundId = mSoundPool.load(context, R.raw.camera_click, 1);
}
@Override
diff --git a/usbCameraTest5/build.gradle b/usbCameraTest5/build.gradle
index b51c7260e..fc51fef58 100644
--- a/usbCameraTest5/build.gradle
+++ b/usbCameraTest5/build.gradle
@@ -25,7 +25,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion versionCompiler
- buildToolsVersion versionBuildTool
compileOptions {
sourceCompatibility javaSourceCompatibility
@@ -34,7 +33,7 @@ android {
defaultConfig {
applicationId "com.serenegiant.usbcameratest5"
- minSdkVersion 18
+ minSdkVersion minTargetVersion
targetSdkVersion versionTarget
versionCode 8
versionName "3.00"
@@ -51,7 +50,6 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- implementation "com.android.support:support-v4:${supportLibVersion}"
implementation "com.android.support:support-annotations:${supportLibVersion}"
implementation("com.serenegiant:common:${commonLibVersion}") {
diff --git a/usbCameraTest5/src/main/AndroidManifest.xml b/usbCameraTest5/src/main/AndroidManifest.xml
index 9d8ca8dc9..60087082f 100644
--- a/usbCameraTest5/src/main/AndroidManifest.xml
+++ b/usbCameraTest5/src/main/AndroidManifest.xml
@@ -36,7 +36,8 @@
android:theme="@style/AppTheme" >
+ android:label="@string/app_name"
+ android:exported="true">
diff --git a/usbCameraTest5/src/main/res/values/dimens.xml b/usbCameraTest5/src/main/res/values/dimens.xml
index 790540d2d..522af662f 100644
--- a/usbCameraTest5/src/main/res/values/dimens.xml
+++ b/usbCameraTest5/src/main/res/values/dimens.xml
@@ -24,6 +24,7 @@
+ 24sp16dp16dp48dp
diff --git a/usbCameraTest6/build.gradle b/usbCameraTest6/build.gradle
index d24f32692..630bfaeb2 100644
--- a/usbCameraTest6/build.gradle
+++ b/usbCameraTest6/build.gradle
@@ -25,7 +25,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion versionCompiler
- buildToolsVersion versionBuildTool
compileOptions {
sourceCompatibility javaSourceCompatibility
@@ -34,7 +33,7 @@ android {
defaultConfig {
applicationId "com.serenegiant.usbcameratest6"
- minSdkVersion 18
+ minSdkVersion minTargetVersion
targetSdkVersion versionTarget
versionCode 8
versionName "3.00"
@@ -51,7 +50,6 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- implementation "com.android.support:support-v4:${supportLibVersion}"
implementation "com.android.support:support-annotations:${supportLibVersion}"
implementation("com.serenegiant:common:${commonLibVersion}") {
diff --git a/usbCameraTest6/src/main/AndroidManifest.xml b/usbCameraTest6/src/main/AndroidManifest.xml
index 7bdc7d8aa..d6ee4b1da 100644
--- a/usbCameraTest6/src/main/AndroidManifest.xml
+++ b/usbCameraTest6/src/main/AndroidManifest.xml
@@ -37,7 +37,8 @@
+ android:screenOrientation="sensorLandscape"
+ android:exported="true">
diff --git a/usbCameraTest6/src/main/res/values/dimens.xml b/usbCameraTest6/src/main/res/values/dimens.xml
index 790540d2d..522af662f 100644
--- a/usbCameraTest6/src/main/res/values/dimens.xml
+++ b/usbCameraTest6/src/main/res/values/dimens.xml
@@ -24,6 +24,7 @@
+ 24sp16dp16dp48dp
diff --git a/usbCameraTest7/build.gradle b/usbCameraTest7/build.gradle
index eba53a822..acde75357 100644
--- a/usbCameraTest7/build.gradle
+++ b/usbCameraTest7/build.gradle
@@ -25,7 +25,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion versionCompiler
- buildToolsVersion versionBuildTool
compileOptions {
sourceCompatibility javaSourceCompatibility
@@ -34,7 +33,7 @@ android {
defaultConfig {
applicationId "com.serenegiant.usbcameratest7"
- minSdkVersion 18
+ minSdkVersion minTargetVersion
targetSdkVersion versionTarget
versionCode 9
versionName "3.00"
@@ -53,7 +52,6 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- implementation "com.android.support:support-v4:${supportLibVersion}"
implementation "com.android.support:support-annotations:${supportLibVersion}"
implementation("com.serenegiant:common:${commonLibVersion}") {
diff --git a/usbCameraTest7/src/main/AndroidManifest.xml b/usbCameraTest7/src/main/AndroidManifest.xml
index 4047ece96..71cf5600d 100644
--- a/usbCameraTest7/src/main/AndroidManifest.xml
+++ b/usbCameraTest7/src/main/AndroidManifest.xml
@@ -37,7 +37,8 @@
+ android:screenOrientation="sensorLandscape"
+ android:exported="true">
diff --git a/usbCameraTest7/src/main/res/values/dimens.xml b/usbCameraTest7/src/main/res/values/dimens.xml
index 790540d2d..522af662f 100644
--- a/usbCameraTest7/src/main/res/values/dimens.xml
+++ b/usbCameraTest7/src/main/res/values/dimens.xml
@@ -24,6 +24,7 @@
+ 24sp16dp16dp48dp
diff --git a/usbCameraTest8/build.gradle b/usbCameraTest8/build.gradle
index 94d049ff5..b2bdedcdf 100644
--- a/usbCameraTest8/build.gradle
+++ b/usbCameraTest8/build.gradle
@@ -25,7 +25,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion versionCompiler
- buildToolsVersion versionBuildTool
compileOptions {
sourceCompatibility javaSourceCompatibility
@@ -34,7 +33,7 @@ android {
defaultConfig {
applicationId "com.serenegiant.usbcameratest8"
- minSdkVersion 18
+ minSdkVersion minTargetVersion
targetSdkVersion versionTarget
versionCode 1
versionName "1.0"
@@ -53,7 +52,6 @@ android {
dependencies {
api fileTree(dir: 'libs', include: ['*.jar'])
- implementation "com.android.support:support-v4:${supportLibVersion}"
implementation "com.android.support:support-annotations:${supportLibVersion}"
androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
@@ -61,9 +59,7 @@ dependencies {
})
testImplementation 'junit:junit:4.12'
- implementation("com.serenegiant:common:${commonLibVersion}") {
- exclude module: 'support-v4'
- }
+ implementation("com.serenegiant:common:${commonLibVersion}")
implementation project(':libuvccamera')
implementation project(':usbCameraCommon')
}
diff --git a/usbCameraTest8/src/main/AndroidManifest.xml b/usbCameraTest8/src/main/AndroidManifest.xml
index 99bca5aa2..62aef2222 100644
--- a/usbCameraTest8/src/main/AndroidManifest.xml
+++ b/usbCameraTest8/src/main/AndroidManifest.xml
@@ -1,28 +1,29 @@
+ ~ UVCCamera
+ ~ library and sample to access to UVC web camera on non-rooted Android device
+ ~
+ ~ Copyright (c) 2014-2017 saki t_saki@serenegiant.com
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ ~ All files in the folder are under this Apache License, Version 2.0.
+ ~ Files in the libjpeg-turbo, libusb, libuvc, rapidjson folder
+ ~ may have a different license, see the respective files.
+ -->
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.serenegiant.usbcameratest8">
@@ -38,7 +39,9 @@
+ android:label="@string/app_name"
+ android:exported="true"
+ tools:ignore="DiscouragedApi">
diff --git a/usbCameraTest8/src/main/res/values/dimens.xml b/usbCameraTest8/src/main/res/values/dimens.xml
index f353c0d9d..e0619e297 100644
--- a/usbCameraTest8/src/main/res/values/dimens.xml
+++ b/usbCameraTest8/src/main/res/values/dimens.xml
@@ -23,6 +23,7 @@
+ 24sp16dp16dp