Loading app/build.gradle +1 −4 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ android { defaultConfig { applicationId "foundation.e.camera" minSdkVersion 26 minSdkVersion 25 targetSdkVersion 34 //compileSdkVersion 31 // needed to support appcompat:1.4.0 (which we need for emoji policy support, and not yet ready to target SDK 30) Loading Loading @@ -132,9 +132,6 @@ dependencies { implementation 'androidx.exifinterface:exifinterface:1.3.7' implementation 'androidx.camera:camera-core:1.2.3' implementation 'com.google.zxing:core:3.5.2' testImplementation 'junit:junit:4.13.2' // newer AndroidJUnit4 InstrumentedTest Loading app/src/main/AndroidManifest.xml +0 −12 Original line number Diff line number Diff line Loading @@ -100,18 +100,6 @@ android:exported="false" > </activity> <activity android:name="net.sourceforge.opencamera.qr.QrScannerActivity" android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize|keyboardHidden" android:exported="true" android:excludeFromRecents="true" android:launchMode="singleInstance" android:screenOrientation="nosensor" android:visibleToInstantApps="true" android:windowSoftInputMode="stateAlwaysHidden|adjustPan"> </activity> <!-- should not change the android:name, including moving to a subpackage - see http://android-developers.blogspot.co.uk/2011/06/things-that-cannot-change.html --> <receiver android:icon="@mipmap/ic_launcher" Loading app/src/main/java/net/sourceforge/opencamera/MainActivity.java +7 −69 Original line number Diff line number Diff line Loading @@ -9,7 +9,6 @@ import net.sourceforge.opencamera.camera2.model.CameraModel; import net.sourceforge.opencamera.camera2.model.CameraType; import net.sourceforge.opencamera.preview.Preview; import net.sourceforge.opencamera.preview.VideoProfile; import net.sourceforge.opencamera.qr.QrImageAnalyzer; import net.sourceforge.opencamera.remotecontrol.BluetoothRemoteControl; import net.sourceforge.opencamera.ui.CircleImageView; import net.sourceforge.opencamera.ui.DrawPreview; Loading Loading @@ -119,12 +118,6 @@ import android.widget.ZoomControls; import androidx.appcompat.app.AppCompatActivity; import kotlin.coroutines.CoroutineContext; import kotlinx.coroutines.CoroutineScope; import kotlinx.coroutines.Dispatchers; import kotlinx.coroutines.Job; import kotlinx.coroutines.JobKt; /** The main Activity for Open Camera. */ public class MainActivity extends AppCompatActivity implements PreferenceFragment.OnPreferenceStartFragmentCallback { Loading Loading @@ -257,11 +250,6 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen //public static final boolean lock_to_landscape = true; public static final boolean lock_to_landscape = false; // QRCode public QrImageAnalyzer qrImageAnalyzer; private Job job; private CoroutineScope coroutineScope; // handling for lock_to_landscape==false: public enum SystemOrientation { Loading Loading @@ -294,16 +282,6 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen Log.d(TAG, "activity_count: " + activity_count); super.onCreate(savedInstanceState); //QRCode job = JobKt.Job(null); coroutineScope = new CoroutineScope() { @Override public CoroutineContext getCoroutineContext() { return Dispatchers.getMain().plus(job); } }; qrImageAnalyzer = new QrImageAnalyzer(this, coroutineScope); setContentView(R.layout.activity_main); PreferenceManager.setDefaultValues(this, R.xml.preferences, false); // initialise any unset preferences to their default values if( MyDebug.LOG ) Loading Loading @@ -2824,44 +2802,6 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen showAlert(alertDialog.create()); } /* getBetterQRCodeCameraID() Returns the best camera ID, based on the fact that it's probably the first rear camera available. The user always has the option of selecting with the lens switcher in case the choice is wrong. Returns -1 if no camera available. In that case we do *NOT* trig any switch. */ public int getBetterQRCodeCameraID() { int best_qrcode_camera = -1; if( MyDebug.LOG ) Log.d(TAG, "getBetterQRCodeCameraID"); if( !isMultiCamEnabled() ) { Log.e(TAG, "getBetterQRCodeCameraID switch multi camera icon shouldn't have been visible"); return best_qrcode_camera; } if( preview.isOpeningCamera() ) { if( MyDebug.LOG ) Log.d(TAG, "getBetterQRCodeCameraID already opening camera in background thread"); return best_qrcode_camera; } if( this.preview.canSwitchCamera() ) { try { CameraManager _cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); for (String _cameraId : _cameraManager.getCameraIdList()) { CameraCharacteristics characteristics = _cameraManager.getCameraCharacteristics(_cameraId); Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING); if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) { best_qrcode_camera = Integer.parseInt(_cameraId); if( MyDebug.LOG ) Log.d(TAG, "best_qrcode_camera ="+best_qrcode_camera); break; } } } catch (Exception e) { e.printStackTrace(); } } return best_qrcode_camera; } private void updateMultiCameraIcon() { Button multiCameraButton = findViewById(R.id.switch_multi_camera); Loading Loading @@ -6621,7 +6561,7 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen simple = false; } } else { //Camera else { if( photo_mode == MyApplicationInterface.PhotoMode.Panorama ) { // don't show resolution in panorama mode toast_string = ""; Loading Loading @@ -6655,9 +6595,7 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen simple = false; } } if (preview.isQRCode()) { toast_string = "QRCode"; } else if( applicationInterface.getFaceDetectionPref() ) { //Camera || Video if( applicationInterface.getFaceDetectionPref() ) { // important so that the user realises why touching for focus/metering areas won't work - easy to forget that face detection has been turned on! toast_string += "\n" + getResources().getString(R.string.preference_face_detection); simple = false; Loading app/src/main/java/net/sourceforge/opencamera/ext/AddressBookParsedResult.ktdeleted 100644 → 0 +0 −130 Original line number Diff line number Diff line /* * SPDX-FileCopyrightText: 2024 The LineageOS Project * SPDX-License-Identifier: Apache-2.0 */ package net.sourceforge.opencamera.ext import android.app.RemoteAction import android.content.Context import android.content.Intent import android.os.Build import android.provider.ContactsContract import android.view.textclassifier.TextClassification import android.view.textclassifier.TextClassifier import com.google.zxing.client.result.AddressBookParsedResult import net.sourceforge.opencamera.R fun AddressBookParsedResult.createIntent() = Intent( Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI ).apply { names.firstOrNull()?.let { putExtra(ContactsContract.Intents.Insert.NAME, it) } pronunciation?.let { putExtra(ContactsContract.Intents.Insert.PHONETIC_NAME, it) } phoneNumbers?.let { phoneNumbers -> val phoneTypes = phoneTypes ?: arrayOf() for ((key, keys) in listOf( listOf( ContactsContract.Intents.Insert.PHONE, ContactsContract.Intents.Insert.PHONE_TYPE, ), listOf( ContactsContract.Intents.Insert.SECONDARY_PHONE, ContactsContract.Intents.Insert.SECONDARY_PHONE_TYPE, ), listOf( ContactsContract.Intents.Insert.TERTIARY_PHONE, ContactsContract.Intents.Insert.TERTIARY_PHONE_TYPE, ), ).withIndex()) { phoneNumbers.getOrNull(key)?.let { phone -> putExtra(keys.first(), phone) phoneTypes.getOrNull(key)?.let { putExtra(keys.last(), it) } } } } emails?.let { emails -> val emailTypes = emailTypes ?: arrayOf() for ((key, keys) in listOf( listOf( ContactsContract.Intents.Insert.EMAIL, ContactsContract.Intents.Insert.EMAIL_TYPE, ), listOf( ContactsContract.Intents.Insert.SECONDARY_EMAIL, ContactsContract.Intents.Insert.SECONDARY_EMAIL_TYPE, ), listOf( ContactsContract.Intents.Insert.TERTIARY_EMAIL, ContactsContract.Intents.Insert.TERTIARY_EMAIL_TYPE, ), ).withIndex()) { emails.getOrNull(key)?.let { phone -> putExtra(keys.first(), phone) emailTypes.getOrNull(key)?.let { putExtra(keys.last(), it) } } } } instantMessenger?.let { putExtra(ContactsContract.Intents.Insert.IM_HANDLE, it) } note?.let { putExtra(ContactsContract.Intents.Insert.NOTES, it) } addresses?.let { emails -> val addressTypes = addressTypes ?: arrayOf() for ((key, keys) in listOf( listOf( ContactsContract.Intents.Insert.POSTAL, ContactsContract.Intents.Insert.POSTAL_TYPE, ), ).withIndex()) { emails.getOrNull(key)?.let { phone -> putExtra(keys.first(), phone) addressTypes.getOrNull(key)?.let { putExtra(keys.last(), it) } } } } org?.let { putExtra(ContactsContract.Intents.Insert.COMPANY, it) } } fun AddressBookParsedResult.createTextClassification( context: Context ) = TextClassification.Builder() .setText(title ?: names.firstOrNull() ?: "") .setEntityType(TextClassifier.TYPE_OTHER, 1.0f) .apply { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { addAction( RemoteAction::class.build( context, R.drawable.ic_contact_phone, R.string.qr_address_title, R.string.qr_address_content_description, createIntent() ) ) } } .build() app/src/main/java/net/sourceforge/opencamera/ext/CalendarParsedResult.ktdeleted 100644 → 0 +0 −63 Original line number Diff line number Diff line /* * SPDX-FileCopyrightText: 2024 The LineageOS Project * SPDX-License-Identifier: Apache-2.0 */ package net.sourceforge.opencamera.ext import android.app.RemoteAction import android.content.Context import android.content.Intent import android.os.Build import android.provider.CalendarContract import android.view.textclassifier.TextClassification import android.view.textclassifier.TextClassifier import androidx.core.os.bundleOf import com.google.zxing.client.result.CalendarParsedResult import net.sourceforge.opencamera.R fun CalendarParsedResult.createIntent() = Intent( Intent.ACTION_INSERT, CalendarContract.Events.CONTENT_URI ).apply { summary?.let { putExtra(CalendarContract.Events.TITLE, it) } description?.let { putExtra(CalendarContract.Events.DESCRIPTION, it) } location?.let { putExtra(CalendarContract.Events.EVENT_LOCATION, it) } organizer?.let { putExtra(CalendarContract.Events.ORGANIZER, it) } attendees?.let { putExtra(Intent.EXTRA_EMAIL, it.joinToString(",")) } putExtras( bundleOf( CalendarContract.EXTRA_EVENT_BEGIN_TIME to startTimestamp, CalendarContract.EXTRA_EVENT_END_TIME to endTimestamp, CalendarContract.EXTRA_EVENT_ALL_DAY to (isStartAllDay && isEndAllDay), ) ) } fun CalendarParsedResult.createTextClassification(context: Context) = TextClassification.Builder() .setText(summary) .setEntityType(TextClassifier.TYPE_OTHER, 1.0f) .apply { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { addAction( RemoteAction::class.build( context, R.drawable.ic_calendar_add_on, R.string.qr_calendar_title, R.string.qr_calendar_content_description, createIntent() ) ) } } .build() Loading
app/build.gradle +1 −4 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ android { defaultConfig { applicationId "foundation.e.camera" minSdkVersion 26 minSdkVersion 25 targetSdkVersion 34 //compileSdkVersion 31 // needed to support appcompat:1.4.0 (which we need for emoji policy support, and not yet ready to target SDK 30) Loading Loading @@ -132,9 +132,6 @@ dependencies { implementation 'androidx.exifinterface:exifinterface:1.3.7' implementation 'androidx.camera:camera-core:1.2.3' implementation 'com.google.zxing:core:3.5.2' testImplementation 'junit:junit:4.13.2' // newer AndroidJUnit4 InstrumentedTest Loading
app/src/main/AndroidManifest.xml +0 −12 Original line number Diff line number Diff line Loading @@ -100,18 +100,6 @@ android:exported="false" > </activity> <activity android:name="net.sourceforge.opencamera.qr.QrScannerActivity" android:configChanges="orientation|screenLayout|screenSize|smallestScreenSize|keyboardHidden" android:exported="true" android:excludeFromRecents="true" android:launchMode="singleInstance" android:screenOrientation="nosensor" android:visibleToInstantApps="true" android:windowSoftInputMode="stateAlwaysHidden|adjustPan"> </activity> <!-- should not change the android:name, including moving to a subpackage - see http://android-developers.blogspot.co.uk/2011/06/things-that-cannot-change.html --> <receiver android:icon="@mipmap/ic_launcher" Loading
app/src/main/java/net/sourceforge/opencamera/MainActivity.java +7 −69 Original line number Diff line number Diff line Loading @@ -9,7 +9,6 @@ import net.sourceforge.opencamera.camera2.model.CameraModel; import net.sourceforge.opencamera.camera2.model.CameraType; import net.sourceforge.opencamera.preview.Preview; import net.sourceforge.opencamera.preview.VideoProfile; import net.sourceforge.opencamera.qr.QrImageAnalyzer; import net.sourceforge.opencamera.remotecontrol.BluetoothRemoteControl; import net.sourceforge.opencamera.ui.CircleImageView; import net.sourceforge.opencamera.ui.DrawPreview; Loading Loading @@ -119,12 +118,6 @@ import android.widget.ZoomControls; import androidx.appcompat.app.AppCompatActivity; import kotlin.coroutines.CoroutineContext; import kotlinx.coroutines.CoroutineScope; import kotlinx.coroutines.Dispatchers; import kotlinx.coroutines.Job; import kotlinx.coroutines.JobKt; /** The main Activity for Open Camera. */ public class MainActivity extends AppCompatActivity implements PreferenceFragment.OnPreferenceStartFragmentCallback { Loading Loading @@ -257,11 +250,6 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen //public static final boolean lock_to_landscape = true; public static final boolean lock_to_landscape = false; // QRCode public QrImageAnalyzer qrImageAnalyzer; private Job job; private CoroutineScope coroutineScope; // handling for lock_to_landscape==false: public enum SystemOrientation { Loading Loading @@ -294,16 +282,6 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen Log.d(TAG, "activity_count: " + activity_count); super.onCreate(savedInstanceState); //QRCode job = JobKt.Job(null); coroutineScope = new CoroutineScope() { @Override public CoroutineContext getCoroutineContext() { return Dispatchers.getMain().plus(job); } }; qrImageAnalyzer = new QrImageAnalyzer(this, coroutineScope); setContentView(R.layout.activity_main); PreferenceManager.setDefaultValues(this, R.xml.preferences, false); // initialise any unset preferences to their default values if( MyDebug.LOG ) Loading Loading @@ -2824,44 +2802,6 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen showAlert(alertDialog.create()); } /* getBetterQRCodeCameraID() Returns the best camera ID, based on the fact that it's probably the first rear camera available. The user always has the option of selecting with the lens switcher in case the choice is wrong. Returns -1 if no camera available. In that case we do *NOT* trig any switch. */ public int getBetterQRCodeCameraID() { int best_qrcode_camera = -1; if( MyDebug.LOG ) Log.d(TAG, "getBetterQRCodeCameraID"); if( !isMultiCamEnabled() ) { Log.e(TAG, "getBetterQRCodeCameraID switch multi camera icon shouldn't have been visible"); return best_qrcode_camera; } if( preview.isOpeningCamera() ) { if( MyDebug.LOG ) Log.d(TAG, "getBetterQRCodeCameraID already opening camera in background thread"); return best_qrcode_camera; } if( this.preview.canSwitchCamera() ) { try { CameraManager _cameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE); for (String _cameraId : _cameraManager.getCameraIdList()) { CameraCharacteristics characteristics = _cameraManager.getCameraCharacteristics(_cameraId); Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING); if (facing != null && facing == CameraCharacteristics.LENS_FACING_BACK) { best_qrcode_camera = Integer.parseInt(_cameraId); if( MyDebug.LOG ) Log.d(TAG, "best_qrcode_camera ="+best_qrcode_camera); break; } } } catch (Exception e) { e.printStackTrace(); } } return best_qrcode_camera; } private void updateMultiCameraIcon() { Button multiCameraButton = findViewById(R.id.switch_multi_camera); Loading Loading @@ -6621,7 +6561,7 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen simple = false; } } else { //Camera else { if( photo_mode == MyApplicationInterface.PhotoMode.Panorama ) { // don't show resolution in panorama mode toast_string = ""; Loading Loading @@ -6655,9 +6595,7 @@ public class MainActivity extends AppCompatActivity implements PreferenceFragmen simple = false; } } if (preview.isQRCode()) { toast_string = "QRCode"; } else if( applicationInterface.getFaceDetectionPref() ) { //Camera || Video if( applicationInterface.getFaceDetectionPref() ) { // important so that the user realises why touching for focus/metering areas won't work - easy to forget that face detection has been turned on! toast_string += "\n" + getResources().getString(R.string.preference_face_detection); simple = false; Loading
app/src/main/java/net/sourceforge/opencamera/ext/AddressBookParsedResult.ktdeleted 100644 → 0 +0 −130 Original line number Diff line number Diff line /* * SPDX-FileCopyrightText: 2024 The LineageOS Project * SPDX-License-Identifier: Apache-2.0 */ package net.sourceforge.opencamera.ext import android.app.RemoteAction import android.content.Context import android.content.Intent import android.os.Build import android.provider.ContactsContract import android.view.textclassifier.TextClassification import android.view.textclassifier.TextClassifier import com.google.zxing.client.result.AddressBookParsedResult import net.sourceforge.opencamera.R fun AddressBookParsedResult.createIntent() = Intent( Intent.ACTION_INSERT, ContactsContract.Contacts.CONTENT_URI ).apply { names.firstOrNull()?.let { putExtra(ContactsContract.Intents.Insert.NAME, it) } pronunciation?.let { putExtra(ContactsContract.Intents.Insert.PHONETIC_NAME, it) } phoneNumbers?.let { phoneNumbers -> val phoneTypes = phoneTypes ?: arrayOf() for ((key, keys) in listOf( listOf( ContactsContract.Intents.Insert.PHONE, ContactsContract.Intents.Insert.PHONE_TYPE, ), listOf( ContactsContract.Intents.Insert.SECONDARY_PHONE, ContactsContract.Intents.Insert.SECONDARY_PHONE_TYPE, ), listOf( ContactsContract.Intents.Insert.TERTIARY_PHONE, ContactsContract.Intents.Insert.TERTIARY_PHONE_TYPE, ), ).withIndex()) { phoneNumbers.getOrNull(key)?.let { phone -> putExtra(keys.first(), phone) phoneTypes.getOrNull(key)?.let { putExtra(keys.last(), it) } } } } emails?.let { emails -> val emailTypes = emailTypes ?: arrayOf() for ((key, keys) in listOf( listOf( ContactsContract.Intents.Insert.EMAIL, ContactsContract.Intents.Insert.EMAIL_TYPE, ), listOf( ContactsContract.Intents.Insert.SECONDARY_EMAIL, ContactsContract.Intents.Insert.SECONDARY_EMAIL_TYPE, ), listOf( ContactsContract.Intents.Insert.TERTIARY_EMAIL, ContactsContract.Intents.Insert.TERTIARY_EMAIL_TYPE, ), ).withIndex()) { emails.getOrNull(key)?.let { phone -> putExtra(keys.first(), phone) emailTypes.getOrNull(key)?.let { putExtra(keys.last(), it) } } } } instantMessenger?.let { putExtra(ContactsContract.Intents.Insert.IM_HANDLE, it) } note?.let { putExtra(ContactsContract.Intents.Insert.NOTES, it) } addresses?.let { emails -> val addressTypes = addressTypes ?: arrayOf() for ((key, keys) in listOf( listOf( ContactsContract.Intents.Insert.POSTAL, ContactsContract.Intents.Insert.POSTAL_TYPE, ), ).withIndex()) { emails.getOrNull(key)?.let { phone -> putExtra(keys.first(), phone) addressTypes.getOrNull(key)?.let { putExtra(keys.last(), it) } } } } org?.let { putExtra(ContactsContract.Intents.Insert.COMPANY, it) } } fun AddressBookParsedResult.createTextClassification( context: Context ) = TextClassification.Builder() .setText(title ?: names.firstOrNull() ?: "") .setEntityType(TextClassifier.TYPE_OTHER, 1.0f) .apply { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { addAction( RemoteAction::class.build( context, R.drawable.ic_contact_phone, R.string.qr_address_title, R.string.qr_address_content_description, createIntent() ) ) } } .build()
app/src/main/java/net/sourceforge/opencamera/ext/CalendarParsedResult.ktdeleted 100644 → 0 +0 −63 Original line number Diff line number Diff line /* * SPDX-FileCopyrightText: 2024 The LineageOS Project * SPDX-License-Identifier: Apache-2.0 */ package net.sourceforge.opencamera.ext import android.app.RemoteAction import android.content.Context import android.content.Intent import android.os.Build import android.provider.CalendarContract import android.view.textclassifier.TextClassification import android.view.textclassifier.TextClassifier import androidx.core.os.bundleOf import com.google.zxing.client.result.CalendarParsedResult import net.sourceforge.opencamera.R fun CalendarParsedResult.createIntent() = Intent( Intent.ACTION_INSERT, CalendarContract.Events.CONTENT_URI ).apply { summary?.let { putExtra(CalendarContract.Events.TITLE, it) } description?.let { putExtra(CalendarContract.Events.DESCRIPTION, it) } location?.let { putExtra(CalendarContract.Events.EVENT_LOCATION, it) } organizer?.let { putExtra(CalendarContract.Events.ORGANIZER, it) } attendees?.let { putExtra(Intent.EXTRA_EMAIL, it.joinToString(",")) } putExtras( bundleOf( CalendarContract.EXTRA_EVENT_BEGIN_TIME to startTimestamp, CalendarContract.EXTRA_EVENT_END_TIME to endTimestamp, CalendarContract.EXTRA_EVENT_ALL_DAY to (isStartAllDay && isEndAllDay), ) ) } fun CalendarParsedResult.createTextClassification(context: Context) = TextClassification.Builder() .setText(summary) .setEntityType(TextClassifier.TYPE_OTHER, 1.0f) .apply { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { addAction( RemoteAction::class.build( context, R.drawable.ic_calendar_add_on, R.string.qr_calendar_title, R.string.qr_calendar_content_description, createIntent() ) ) } } .build()