}
android {
- compileSdk 33
+ compileSdk 34
defaultConfig {
minSdk 24
- targetSdk 33
+ //noinspection EditedTargetSdkVersion
+ targetSdk 34
versionCode 71
versionName "3.15.1"
resourceConfigurations += ['en', 'de', 'es', 'fr', 'it', 'pt-rBR', 'ru', 'tr', 'zh-rCN']
}
// Gradle requires a `flavorDimension`, but it isn't used for anything in Privacy Browser.
- flavorDimensions "basic"
+ flavorDimensions = ['basic']
productFlavors {
standard {
dependencies {
// Include the following AndroidX libraries.
- implementation "androidx.activity:activity-ktx:1.7.0-alpha04"
+ implementation "androidx.activity:activity-ktx:1.8.0"
implementation 'androidx.arch.core:core-common:2.2.0'
implementation 'androidx.arch.core:core-runtime:2.2.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.coordinatorlayout:coordinatorlayout:1.2.0'
- implementation 'androidx.core:core-ktx:1.10.1'
+ implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.drawerlayout:drawerlayout:1.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2'
implementation 'androidx.preference:preference-ktx:1.2.1'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'androidx.viewpager:viewpager:1.0.0'
- implementation 'androidx.webkit:webkit:1.7.0'
+ implementation 'androidx.webkit:webkit:1.8.0'
// Include the Kotlin standard library. This should be the same version number listed in project build.gradle.
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.8.22'
// Include the Google material library.
- implementation 'com.google.android.material:material:1.9.0'
+ implementation 'com.google.android.material:material:1.10.0'
}
// Find out if OpenKeychain is installed.
openKeychainInstalled = try {
- // The newer method can be used once the minimum API >= 33.
- @Suppress("DEPRECATION")
packageManager.getPackageInfo("org.sufficientlysecure.keychain", 0).versionName.isNotEmpty()
} catch (exception: PackageManager.NameNotFoundException) {
false
import androidx.appcompat.content.res.AppCompatResources
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
+import androidx.core.content.ContextCompat
import androidx.core.view.GravityCompat
import androidx.cursoradapter.widget.CursorAdapter
import androidx.drawerlayout.widget.DrawerLayout
// Get the package manager.
val packageManager = packageManager
- // Check to see if Orbot is in the list. This will throw an error and drop to the catch section if it isn't installed. The deprecated method must be used until the minimum API >= 33.
- @Suppress("DEPRECATION")
+ // Check to see if Orbot is in the list. This will throw an error and drop to the catch section if it isn't installed.
packageManager.getPackageInfo("org.torproject.android", 0)
// Check to see if the proxy is ready.
// Check to see if I2P is installed.
try {
// Check to see if the F-Droid flavor is installed. This will throw an error and drop to the catch section if it isn't installed.
- // The deprecated method must be used until the minimum API >= 33.
- @Suppress("DEPRECATION")
packageManager.getPackageInfo("net.i2p.android.router", 0)
} catch (fdroidException: PackageManager.NameNotFoundException) { // The F-Droid flavor is not installed.
try {
// Check to see if the Google Play flavor is installed. This will throw an error and drop to the catch section if it isn't installed.
- // The deprecated method must be used until the minimum API >= 33.
- @Suppress("DEPRECATION")
packageManager.getPackageInfo("net.i2p.android", 0)
} catch (googlePlayException: PackageManager.NameNotFoundException) { // The Google Play flavor is not installed.
// Sow the I2P not installed dialog if it is not already displayed.
}
}
- // Register the Orbot status broadcast receiver.
- registerReceiver(orbotStatusBroadcastReceiver, IntentFilter("org.torproject.android.intent.action.STATUS"))
+ // Register the Orbot status broadcast receiver. `ContextCompat` must be used until the minimum API >= 34.
+ ContextCompat.registerReceiver(this, orbotStatusBroadcastReceiver, IntentFilter("org.torproject.android.intent.action.STATUS"), ContextCompat.RECEIVER_EXPORTED)
// Get handles for views that need to be modified.
val bookmarksHeaderLinearLayout = findViewById<LinearLayout>(R.id.bookmarks_header_linearlayout)
}
}
- override fun onFling(motionEvent1: MotionEvent, motionEvent2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
+ override fun onFling(motionEvent1: MotionEvent?, motionEvent2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {
// Scroll the bottom app bar if enabled.
- if (bottomAppBar && scrollAppBar && !objectAnimator.isRunning) {
+ if (bottomAppBar && scrollAppBar && !objectAnimator.isRunning && (motionEvent1 != null)) {
// Calculate the Y change.
val motionY = motionEvent2.y - motionEvent1.y
import android.app.Dialog
import android.content.Context
import android.content.DialogInterface
-import android.graphics.drawable.BitmapDrawable
-import android.graphics.drawable.Drawable
import android.os.Bundle
import android.view.WindowManager
import androidx.appcompat.app.AlertDialog
-import androidx.core.content.ContextCompat
import androidx.fragment.app.DialogFragment
import androidx.preference.PreferenceManager
import androidx.viewpager.widget.ViewPager
// Use an alert dialog builder to create the alert dialog.
val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.PrivacyBrowserAlertDialog)
- // Get the favorite icon.
- val favoriteIconBitmap = nestedScrollWebView.getFavoriteIcon()
-
- // Get the default favorite icon drawable. `ContextCompat` must be used until API >= 21.
- val defaultFavoriteIconDrawable = ContextCompat.getDrawable(requireContext(), R.drawable.world)
-
- // Cast the favorite icon drawable to a bitmap drawable.
- val defaultFavoriteIconBitmapDrawable = (defaultFavoriteIconDrawable as BitmapDrawable)
-
- // Store the default icon bitmap.
- val defaultFavoriteIconBitmap = defaultFavoriteIconBitmapDrawable.bitmap
-
- // Set the favorite icon as the dialog icon if it exists.
- if (favoriteIconBitmap.sameAs(defaultFavoriteIconBitmap)) { // There is no website favorite icon.
- // Set the icon.
- dialogBuilder.setIcon(R.drawable.ssl_certificate)
- } else { // There is a favorite icon.
- // Create a drawable version of the favorite icon.
- val favoriteIconDrawable: Drawable = BitmapDrawable(resources, favoriteIconBitmap)
-
- // Set the icon.
- dialogBuilder.setIcon(favoriteIconDrawable)
- }
+ // Set the icon.
+ dialogBuilder.setIcon(R.drawable.ssl_certificate)
// Set the title.
dialogBuilder.setTitle(R.string.pinned_mismatch)
// Get the Orbot version name if Orbot is installed.
val orbot: String = try {
- // Store the version name. The newer `getPackageInfo()` may be used once the minimum API >= 33.
- @Suppress("DEPRECATION")
+ // Store the version name.
requireContext().packageManager.getPackageInfo("org.torproject.android", 0).versionName
} catch (exception: PackageManager.NameNotFoundException) { // Orbot is not installed.
// Store an empty string.
// Get the I2P version name if I2P is installed.
val i2p: String = try {
- // Check to see if the F-Droid flavor is installed. The newer `getPackageInfo()` may be used once the minimum API >= 33.
- @Suppress("DEPRECATION")
+ // Check to see if the F-Droid flavor is installed.
requireContext().getString(R.string.fdroid_flavor, requireContext().packageManager.getPackageInfo("net.i2p.android.router", 0).versionName)
} catch (exception: PackageManager.NameNotFoundException) { // The F-Droid flavor is not installed.
try {
- // Check to see if the F-Droid flavor is installed. The newer `getPackageInfo()` may be used once the minimum API >= 33.
- @Suppress("DEPRECATION")
+ // Check to see if the F-Droid flavor is installed.
requireContext().getString(R.string.google_play_flavor, requireContext().packageManager.getPackageInfo("net.i2p.android", 0).versionName)
} catch (exception: PackageManager.NameNotFoundException) { // The Google Play flavor is not installed either.
// Store an empty string.
// Get the OpenKeychain version name if it is installed.
val openKeychain: String = try {
- // Store the version name. The newer `getPackageInfo()` may be used once the minimum API >= 33.
- @Suppress("DEPRECATION")
+ // Store the version name.
requireContext().packageManager.getPackageInfo("org.sufficientlysecure.keychain", 0).versionName
} catch (exception: PackageManager.NameNotFoundException) { // OpenKeychain is not installed.
// Store an empty string.
private const val ACCEPT_COOKIES = "A"
private const val BLOCK_ALL_THIRD_PARTY_REQUESTS = "B"
private const val CURRENT_DOMAIN_NAME = "C"
-private const val CURRENT_URl = "D"
+private const val CURRENT_URL = "D"
private const val DOM_STORAGE_ENABLED = "E"
private const val DOMAIN_SETTINGS_APPLIED = "F"
private const val DOMAIN_SETTINGS_DATABASE_ID = "G"
savedState.putBoolean(ACCEPT_COOKIES, acceptCookies)
savedState.putBoolean(BLOCK_ALL_THIRD_PARTY_REQUESTS, blockAllThirdPartyRequests)
savedState.putString(CURRENT_DOMAIN_NAME, currentDomainName)
- savedState.putString(CURRENT_URl, currentUrl)
+ savedState.putString(CURRENT_URL, currentUrl)
savedState.putBoolean(DOM_STORAGE_ENABLED, this.settings.domStorageEnabled)
savedState.putBoolean(DOMAIN_SETTINGS_APPLIED, domainSettingsApplied)
savedState.putInt(DOMAIN_SETTINGS_DATABASE_ID, domainSettingsDatabaseId)
acceptCookies = savedState.getBoolean(ACCEPT_COOKIES)
blockAllThirdPartyRequests = savedState.getBoolean(BLOCK_ALL_THIRD_PARTY_REQUESTS)
currentDomainName = savedState.getString(CURRENT_DOMAIN_NAME)!!
- currentUrl = savedState.getString(CURRENT_URl)!!
+ currentUrl = savedState.getString(CURRENT_URL)!!
this.settings.domStorageEnabled = savedState.getBoolean(DOM_STORAGE_ENABLED)
domainSettingsApplied = savedState.getBoolean(DOMAIN_SETTINGS_APPLIED)
domainSettingsDatabaseId = savedState.getInt(DOMAIN_SETTINGS_DATABASE_ID)
}
dependencies {
- classpath 'com.android.tools.build:gradle:8.0.2'
+ classpath 'com.android.tools.build:gradle:8.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.22"
// NOTE: Do not place your application dependencies here; they belong