Rabindra Khadka
Rabindra Khadka

Reputation: 1782

The getParcelableExtra method is deprecated

I am passing Parcelable data into an Intent and getting it out on the other end using the getParcelableExtra(name:) method. However, getParcelableExtra(name:) seems to be deprecated. How do I fix the deprecation warning? Alternatively, are there any other options for doing this? I am using a compileSdkVersion value of 33.

Code snippet

var data = intent.getParcelableExtra("data")

Upvotes: 99

Views: 88245

Answers (6)

Dante
Dante

Reputation: 1

    val movie: Movie? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        intent?.getParcelableExtra(DownloadExtras.MOVIE, Movie::class.java)
    } else {
        @Suppress("DEPRECATION")
        intent?.getParcelableExtra(DownloadExtras.MOVIE)
    }

Upvotes: 0

Martin Zeitler
Martin Zeitler

Reputation: 76769

For example UsbDevice.class:

UsbDevice device;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) { // TIRAMISU onwards
    device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE, UsbDevice.class);
} else {
    device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
}

Also NFC Tag.class:

Tag tag;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S_V2) { // TIRAMISU onwards
    tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG, Tag.class);
} else {
    tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
}

This still requires @SuppressWarnings({"deprecation", "RedundantSuppression"}).

Upvotes: 7

Marek Macko
Marek Macko

Reputation: 927

androidx.core:core-ktx:1.10.0 provides two classes IntentCompat and BundleCompat with few helpful static methods

androidx.core.os.BundleCompat:

BundleCompat.getParcelable(Bundle, String, Class<T>)
BundleCompat.getParcelableArray(Bundle, String, Class<? extends Parcelable>): Parcelable[] 
BundleCompat.getParcelableArrayList(Bundle, String, Class<? extends T> clazz): ArrayList<T>
BundleCompat.getSparseParcelableArray(Bundle, String, Class<? extends T>): SparseArray<T>

androidx.core.content.IntentCompat

IntentCompat.getParcelableExtra(Intent, String, Class<T>)
IntentCompat.getParcelableArrayExtra(Intent, String, Class<? extends Parcelable>): Parcelable[]
IntentCompat.getParcelableArrayListExtra(Intent, String, Class<? extends T>): ArrayList<T>

Example for retrieving an object of android.bluetooth.BluetoothDevice:

IntentCompat.getParcelableExtra(intent, BluetoothDevice.EXTRA_DEVICE, BluetoothDevice::class.java) 

Simplified version of extensions proposed by @Niklas:

inline fun <reified T : Parcelable> Bundle.parcelable(key: String): T? =
    BundleCompat.getParcelable(this, key, T::class.java)

inline fun <reified T : Parcelable> Intent.parcelable(key: String): T? =
    IntentCompat.getParcelableExtra(this, key, T::class.java)

For ArrayList:

inline fun <reified T : Parcelable> Bundle.parcelableList(key: String): List<T>? =
    BundleCompat.getParcelableArrayList(this, key, T::class.java)

inline fun <reified T : Parcelable> Intent.parcelableList(key: String): List<T>? =
    IntentCompat.getParcelableArrayListExtra(this, key, T::class.java)

Upvotes: 66

Niklas
Niklas

Reputation: 25413

Here are two extension methods that I use for Bundle & Intent:

inline fun <reified T : Parcelable> Intent.parcelable(key: String): T? = when {
  SDK_INT >= 33 -> getParcelableExtra(key, T::class.java)
  else -> @Suppress("DEPRECATION") getParcelableExtra(key) as? T
}

inline fun <reified T : Parcelable> Bundle.parcelable(key: String): T? = when {
  SDK_INT >= 33 -> getParcelable(key, T::class.java)
  else -> @Suppress("DEPRECATION") getParcelable(key) as? T
}

I also requested this to be added to the support library

And if you need the ArrayList support there is:

inline fun <reified T : Parcelable> Bundle.parcelableArrayList(key: String): ArrayList<T>? = when {
  SDK_INT >= 33 -> getParcelableArrayList(key, T::class.java)
  else -> @Suppress("DEPRECATION") getParcelableArrayList(key)
}

inline fun <reified T : Parcelable> Intent.parcelableArrayList(key: String): ArrayList<T>? = when {
  SDK_INT >= 33 -> getParcelableArrayListExtra(key, T::class.java)
  else -> @Suppress("DEPRECATION") getParcelableArrayListExtra(key)
}

Note: There are some issues on SDK 33 with the new methods, so you might only want to use it starting from SDK 34.

Upvotes: 212

Gedeon Mutshipayi
Gedeon Mutshipayi

Reputation: 4083

As described in the official documentation, getParcelableExtra was deprecated in API level 33.

So check if the API LEVEL is >= 33 or change the method,

...

if (Build.VERSION.SDK_INT >= 33) { // TIRAMISU
    data = intent.getParcelableExtra (String name, Class<T> clazz)
}else{
    data = intent.getParcelableExtra("")
}

Here is an example using android.bluetooth.BluetoothDevice

...
val device = if (Build.VERSION.SDK_INT >= 33){ // TIRAMISU
    intent.getParcelableArrayExtra(
        BluetoothDevice.EXTRA_NAME,
        BluetoothDevice::class.java
    )
}else{
    intent.getParcelableExtra(BluetoothDevice.EXTRA_NAME)
}

Upvotes: 7

AskNilesh
AskNilesh

Reputation: 69709

Now we need to use getParcelableExtra() with the type-safer class added to API 33

SAMPLE CODE For kotlin

val userData = if (VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
  intent.getParcelableExtra("DATA", User::class.java)
} else {
  intent.getParcelableExtra<User>("DATA")
}

SAMPLE CODE For JAVA

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
  user = getIntent().getParcelableExtra("data", User.class);
} else {
  user = getIntent().getParcelableExtra("data");
}

Upvotes: 50

Related Questions