Added in [API level 21](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels) Summary: [Methods](https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#pubmethods) \| [Inherited Methods](https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#inhmethods)

# PackageInstaller.Session

*** ** * ** ***

` public static class PackageInstaller.Session `   
` extends https://developer.android.com/reference/java/lang/Object ` ` implements https://developer.android.com/reference/java/io/Closeable `

|---|---|
| [java.lang.Object](https://developer.android.com/reference/java/lang/Object) ||
| ↳ | android.content.pm.PackageInstaller.Session |

<br />

*** ** * ** ***

An installation that is being actively staged. For an install to succeed, all existing and new packages must have identical package names, version codes, and signing certificates.

A session may contain any number of split packages. If the application does not yet exist, this session must include a base package.

If an APK included in this session is already defined by the existing installation (for example, the same split name), the APK in this session will replace the existing APK.

In such a case that multiple packages need to be committed simultaneously, multiple sessions can be referenced by a single multi-package session. This session is created with no package name and calling `https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setMultiPackage()`. The individual session IDs can be added with `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#addChildSessionId(int)` and commit of the multi-package session will result in all child sessions being committed atomically.

## Summary

| ### Public methods ||
|---|---|
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#abandon()() ` Completely abandon this session, destroying all staged data and rendering it invalid. |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#addChildSessionId(int)(int sessionId) ` Adds a session ID to the set of sessions that will be committed atomically when this session is committed. |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#close()() ` Release this session object. |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#commit(android.content.IntentSender)(https://developer.android.com/reference/android/content/IntentSender statusReceiver) ` Attempt to commit everything staged in this session. |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#fsync(java.io.OutputStream)(https://developer.android.com/reference/java/io/OutputStream out) ` Ensure that any outstanding data for given stream has been committed to disk. |
| ` https://developer.android.com/reference/android/os/PersistableBundle` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#getAppMetadata()() ` |
| ` int[]` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#getChildSessionIds()() ` |
| ` https://developer.android.com/reference/java/lang/String` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#getNames()() ` Return all APK names contained in this session. |
| ` int` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#getParentSessionId()() ` |
| ` boolean` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#isApplicationEnabledSettingPersistent()() ` |
| ` boolean` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#isMultiPackage()() ` |
| ` boolean` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#isRequestUpdateOwnership()() ` |
| ` boolean` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#isStaged()() ` |
| ` https://developer.android.com/reference/java/io/InputStream` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#openRead(java.lang.String)(https://developer.android.com/reference/java/lang/String name) ` Open a stream to read an APK file from the session. |
| ` https://developer.android.com/reference/java/io/OutputStream` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#openWrite(java.lang.String,%20long,%20long)(https://developer.android.com/reference/java/lang/String name, long offsetBytes, long lengthBytes) ` Open a stream to write an APK file into the session. |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#removeChildSessionId(int)(int sessionId) ` Removes a session ID from the set of sessions that will be committed atomically when this session is committed. |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#removeSplit(java.lang.String)(https://developer.android.com/reference/java/lang/String splitName) ` Removes a split. |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#requestChecksums(java.lang.String,%20int,%20java.util.List<java.security.cert.Certificate>,%20java.util.concurrent.Executor,%20android.content.pm.PackageManager.OnChecksumsReadyListener)(https://developer.android.com/reference/java/lang/String name, int required, https://developer.android.com/reference/java/util/List<https://developer.android.com/reference/java/security/cert/Certificate> trustedInstallers, https://developer.android.com/reference/java/util/concurrent/Executor executor, https://developer.android.com/reference/android/content/pm/PackageManager.OnChecksumsReadyListener onChecksumsReadyListener) ` Requests checksums for the APK file in session. |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#requestUserPreapproval(android.content.pm.PackageInstaller.PreapprovalDetails,%20android.content.IntentSender)(https://developer.android.com/reference/android/content/pm/PackageInstaller.PreapprovalDetails details, https://developer.android.com/reference/android/content/IntentSender statusReceiver) ` Attempt to request the approval before committing this session. |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#setAppMetadata(android.os.PersistableBundle)(https://developer.android.com/reference/android/os/PersistableBundle data) ` Optionally set the app metadata. |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#setChecksums(java.lang.String,%20java.util.List<android.content.pm.Checksum>,%20byte[])(https://developer.android.com/reference/java/lang/String name, https://developer.android.com/reference/java/util/List<https://developer.android.com/reference/android/content/pm/Checksum> checksums, byte[] signature) ` *This method was deprecated in API level 31. do not use installer-provided checksums, use platform-enforced checksums e.g. `https://developer.android.com/reference/android/content/pm/Checksum#TYPE_WHOLE_MERKLE_ROOT_4K_SHA256` in `https://developer.android.com/reference/android/content/pm/PackageManager#requestChecksums(java.lang.String,%20boolean,%20int,%20java.util.List<java.security.cert.Certificate>,%20android.content.pm.PackageManager.OnChecksumsReadyListener)`.* |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#setStagingProgress(float)(float progress) ` Set current progress of staging this session. |
| ` void` | ` https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#transfer(java.lang.String)(https://developer.android.com/reference/java/lang/String packageName) ` Transfer the session to a new owner. |

### Inherited methods

From class ` https://developer.android.com/reference/java/lang/Object ` ` https://developer.android.com/reference/java/lang/Object` ` https://developer.android.com/reference/java/lang/Object#clone()() `

Creates and returns a copy of this object.
` boolean` ` https://developer.android.com/reference/java/lang/Object#equals(java.lang.Object)(https://developer.android.com/reference/java/lang/Object obj) `

Indicates whether some other object is "equal to" this one.
` void` ` https://developer.android.com/reference/java/lang/Object#finalize()() `

Called by the garbage collector on an object when garbage collection determines that there are no more references to the object.
` final https://developer.android.com/reference/java/lang/Class<?>` ` https://developer.android.com/reference/java/lang/Object#getClass()() `

Returns the runtime class of this `Object`.
` int` ` https://developer.android.com/reference/java/lang/Object#hashCode()() `

Returns a hash code value for the object.
` final void` ` https://developer.android.com/reference/java/lang/Object#notify()() `

Wakes up a single thread that is waiting on this object's monitor.
` final void` ` https://developer.android.com/reference/java/lang/Object#notifyAll()() `

Wakes up all threads that are waiting on this object's monitor.
` https://developer.android.com/reference/java/lang/String` ` https://developer.android.com/reference/java/lang/Object#toString()() `

Returns a string representation of the object.
` final void` ` https://developer.android.com/reference/java/lang/Object#wait(long,%20int)(long timeoutMillis, int nanos) `

Causes the current thread to wait until it is awakened, typically by being *notified* or *interrupted*, or until a certain amount of real time has elapsed.
` final void` ` https://developer.android.com/reference/java/lang/Object#wait(long)(long timeoutMillis) `

Causes the current thread to wait until it is awakened, typically by being *notified* or *interrupted*, or until a certain amount of real time has elapsed.
` final void` ` https://developer.android.com/reference/java/lang/Object#wait()() `

Causes the current thread to wait until it is awakened, typically by being *notified* or *interrupted*.
From interface ` https://developer.android.com/reference/java/io/Closeable ` ` abstract void` ` https://developer.android.com/reference/java/io/Closeable#close()() `

Closes this stream and releases any system resources associated with it.
From interface ` https://developer.android.com/reference/java/lang/AutoCloseable ` ` abstract void` ` https://developer.android.com/reference/java/lang/AutoCloseable#close()() `

Closes this resource, relinquishing any underlying resources.

## Public methods

### abandon

Added in [API level 21](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void abandon ()
```

Completely abandon this session, destroying all staged data and rendering it invalid. Abandoned sessions will be reported to `https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionCallback` listeners as failures. This is equivalent to `https://developer.android.com/reference/android/content/pm/PackageInstaller#abandonSession(int)`.

If the parent is abandoned, all children will also be abandoned. Any written data would be destroyed and the created `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session` information will be discarded.

<br />

<br />

### addChildSessionId

Added in [API level 29](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void addChildSessionId (int sessionId)
```

Adds a session ID to the set of sessions that will be committed atomically when this session is committed.

If the parent is staged or has rollback enabled, all children must have the same properties.

If the parent is abandoned, all children will also be abandoned.

<br />

<br />

| Parameters ||
|---|---|
| `sessionId` | `int`: the session ID to add to this multi-package session. <br /> |

### close

Added in [API level 21](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void close ()
```

Release this session object. You can open the session again if it hasn't been finalized.

<br />

### commit

Added in [API level 21](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void commit (IntentSender statusReceiver)
```

Attempt to commit everything staged in this session. This may require user intervention, and so it may not happen immediately. The final result of the commit will be reported through the given callback.

Once this method is called, the session is sealed and no additional mutations may be performed on the session. In case of device reboot or data loader transient failure before the session has been finalized, you may commit the session again.

If the installer is the device owner, the affiliated profile owner, or has received user pre-approval of this session, there will be no user intervention.

<br />

| Parameters ||
|---|---|
| `statusReceiver` | `IntentSender`: Called when the state of the session changes. Intents sent to this receiver contain `https://developer.android.com/reference/android/content/pm/PackageInstaller#EXTRA_STATUS`. Refer to the individual status codes on how to handle them. This value cannot be `null`. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | if the `statusReceiver` from an immutable `https://developer.android.com/reference/android/app/PendingIntent` when caller has a target SDK of API version 35 or above. |
| `https://developer.android.com/reference/java/lang/SecurityException` | if streams opened through `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#openWrite(java.lang.String,%20long,%20long)` are still open. |

**See also:**

- `https://developer.android.com/reference/android/app/admin/DevicePolicyManager`
- `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#requestUserPreapproval(android.content.pm.PackageInstaller.PreapprovalDetails,%20android.content.IntentSender)`

### fsync

Added in [API level 21](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void fsync (OutputStream out)
```

Ensure that any outstanding data for given stream has been committed to disk. This is only valid for streams returned from `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#openWrite(java.lang.String,%20long,%20long)`.

<br />

| Parameters ||
|---|---|
| `out` | `OutputStream`: This value cannot be `null`. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/io/IOException` |   |

### getAppMetadata

Added in [API level 34](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public PersistableBundle getAppMetadata ()
```

<br />

<br />

| Returns ||
|---|---|
| `https://developer.android.com/reference/android/os/PersistableBundle` | A PersistableBundle containing the app metadata set with `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#setAppMetadata(android.os.PersistableBundle)`. In the case where this data does not exist, an empty PersistableBundle is returned. This value cannot be `null`. <br /> |

### getChildSessionIds

Added in [API level 29](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public int[] getChildSessionIds ()
```

<br />

<br />

| Returns ||
|---|---|
| `int[]` | the set of session IDs that will be committed atomically when this session is committed if this is a multi-package session or null if none exist. <br /> |

### getNames

Added in [API level 21](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public String[] getNames ()
```

Return all APK names contained in this session.

This returns all names which have been previously written through `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#openWrite(java.lang.String,%20long,%20long)` as part of this session.

<br />

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/lang/String` | This value cannot be `null`. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/SecurityException` | if called after the session has been abandoned. |
| `https://developer.android.com/reference/java/io/IOException` |   |

### getParentSessionId

Added in [API level 29](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public int getParentSessionId ()
```

<br />

<br />

| Returns ||
|---|---|
| `int` | the session ID of the multi-package session that this belongs to or `https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionInfo#INVALID_ID` if it does not belong to a multi-package session. <br /> |

### isApplicationEnabledSettingPersistent

Added in [API level 34](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public boolean isApplicationEnabledSettingPersistent ()
```

<br />

<br />

| Returns ||
|---|---|
| `boolean` | `true` if this session will keep the existing application enabled setting after installation. <br /> |

### isMultiPackage

Added in [API level 29](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public boolean isMultiPackage ()
```

<br />

<br />

| Returns ||
|---|---|
| `boolean` | `true` if this session will commit more than one package when it is committed. <br /> |

### isRequestUpdateOwnership

Added in [API level 34](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public boolean isRequestUpdateOwnership ()
```

<br />

<br />

| Returns ||
|---|---|
| `boolean` | `true` if the installer requested the update ownership enforcement for the packages in this session. <br /> |

**See also:**

- `https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionParams#setRequestUpdateOwnership(boolean)`

### isStaged

Added in [API level 29](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public boolean isStaged ()
```

<br />

<br />

| Returns ||
|---|---|
| `boolean` | `true` if this session will be staged and applied at next reboot. <br /> |

### openRead

Added in [API level 21](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public InputStream openRead (String name)
```

Open a stream to read an APK file from the session.

This is only valid for names which have been previously written through `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#openWrite(java.lang.String,%20long,%20long)` as part of this session. For example, this stream may be used to calculate a `https://developer.android.com/reference/java/security/MessageDigest` of a written APK before committing.

<br />

| Parameters ||
|---|---|
| `name` | `String`: This value cannot be `null`. <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/io/InputStream` | This value cannot be `null`. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/SecurityException` | if called after the session has been committed or abandoned. |
| `https://developer.android.com/reference/java/io/IOException` |   |

### openWrite

Added in [API level 21](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public OutputStream openWrite (String name, 
                long offsetBytes, 
                long lengthBytes)
```

Open a stream to write an APK file into the session.

The returned stream will start writing data at the requested offset in the underlying file, which can be used to resume a partially written file. If a valid file length is specified, the system will preallocate the underlying disk space to optimize placement on disk. It's strongly recommended to provide a valid file length when known.

You can write data into the returned stream, optionally call `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#fsync(java.io.OutputStream)` as needed to ensure bytes have been persisted to disk, and then close when finished. All streams must be closed before calling `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#commit(android.content.IntentSender)`.

<br />

| Parameters ||
|---|---|
| `name` | `String`: arbitrary, unique name of your choosing to identify the APK being written. You can open a file again for additional writes (such as after a reboot) by using the same name. This name is only meaningful within the context of a single install session. This value cannot be `null`. <br /> |
| `offsetBytes` | `long`: offset into the file to begin writing at, or 0 to start at the beginning of the file. <br /> |
| `lengthBytes` | `long`: total size of the file being written, used to preallocate the underlying disk space, or -1 if unknown. The system may clear various caches as needed to allocate this space. <br /> |

| Returns ||
|---|---|
| `https://developer.android.com/reference/java/io/OutputStream` | This value cannot be `null`. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/io/IOException` | if trouble opening the file for writing, such as lack of disk space or unavailable media. |
| `https://developer.android.com/reference/java/lang/SecurityException` | if called after the session has been sealed or abandoned |

### removeChildSessionId

Added in [API level 29](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void removeChildSessionId (int sessionId)
```

Removes a session ID from the set of sessions that will be committed atomically when this session is committed.

<br />

| Parameters ||
|---|---|
| `sessionId` | `int`: the session ID to remove from this multi-package session. <br /> |

### removeSplit

Added in [API level 24](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void removeSplit (String splitName)
```

Removes a split.

Split removals occur prior to adding new APKs. If upgrading a feature split, it is not expected nor desirable to remove the split prior to upgrading.

When split removal is bundled with new APKs, the packageName must be identical.

<br />

| Parameters ||
|---|---|
| `splitName` | `String`: This value cannot be `null`. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/io/IOException` |   |

### requestChecksums

Added in [API level 33](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void requestChecksums (String name, 
                int required, 
                List<Certificate> trustedInstallers, 
                Executor executor, 
                PackageManager.OnChecksumsReadyListener onChecksumsReadyListener)
```

Requests checksums for the APK file in session.

A possible use case is replying to `https://developer.android.com/reference/android/content/Intent#ACTION_PACKAGE_NEEDS_VERIFICATION` broadcast. The checksums will be returned asynchronously via onChecksumsReadyListener.

By default returns all readily available checksums:

- enforced by platform,
- enforced by the installer.

If the caller needs a specific checksum type, they can specify it as required.

**Caution: Android can not verify installer-provided checksums. Make sure you specify trusted installers.**

<br />

<br />

| Parameters ||
|---|---|
| `name` | `String`: previously written as part of this session. `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#openWrite(java.lang.String,%20long,%20long)` This value cannot be `null`. <br /> |
| `required` | `int`: to explicitly request the checksum types. Will incur significant CPU/memory/disk usage. Value is either `0` or a combination of the following: - `https://developer.android.com/reference/android/content/pm/Checksum#TYPE_WHOLE_MERKLE_ROOT_4K_SHA256` - `https://developer.android.com/reference/android/content/pm/Checksum#TYPE_WHOLE_MD5` - `https://developer.android.com/reference/android/content/pm/Checksum#TYPE_WHOLE_SHA1` - `https://developer.android.com/reference/android/content/pm/Checksum#TYPE_WHOLE_SHA256` - `https://developer.android.com/reference/android/content/pm/Checksum#TYPE_WHOLE_SHA512` - `https://developer.android.com/reference/android/content/pm/Checksum#TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256` - `https://developer.android.com/reference/android/content/pm/Checksum#TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512` |
| `trustedInstallers` | `List`: for checksums enforced by installer, which installers are to be trusted. `https://developer.android.com/reference/android/content/pm/PackageManager#TRUST_ALL` will return checksums from any installer, `https://developer.android.com/reference/android/content/pm/PackageManager#TRUST_NONE` disables optimized installer-enforced checksums, otherwise the list has to be a non-empty list of certificates. This value cannot be `null`. <br /> |
| `executor` | `Executor`: the `https://developer.android.com/reference/java/util/concurrent/Executor` on which to invoke the callback. This value cannot be `null`. Callback and listener events are dispatched through this `https://developer.android.com/reference/java/util/concurrent/Executor`, providing an easy way to control which thread is used. To dispatch events through the main thread of your application, you can use `https://developer.android.com/reference/android/content/Context#getMainExecutor()`. Otherwise, provide an `https://developer.android.com/reference/java/util/concurrent/Executor` that dispatches to an appropriate thread. <br /> |
| `onChecksumsReadyListener` | `PackageManager.OnChecksumsReadyListener`: called once when the results are available. This value cannot be `null`. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/io/FileNotFoundException` | if the file does not exist. |
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | if the list of trusted installer certificates is empty. |
| `https://developer.android.com/reference/java/security/cert/CertificateEncodingException` | if an encoding error occurs for trustedInstallers. |

### requestUserPreapproval

Added in [API level 34](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void requestUserPreapproval (PackageInstaller.PreapprovalDetails details, 
                IntentSender statusReceiver)
```

Attempt to request the approval before committing this session. For installers that have been granted the `https://developer.android.com/reference/android/Manifest.permission#REQUEST_INSTALL_PACKAGES` permission, they can request the approval from users before `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#commit(android.content.IntentSender)` is called. This may require user intervention as well. When user intervention is required, installers will receive a `https://developer.android.com/reference/android/content/pm/PackageInstaller#STATUS_PENDING_USER_ACTION` callback, and `https://developer.android.com/reference/android/content/pm/PackageInstaller#STATUS_SUCCESS` otherwise. In case that requesting user pre-approval is not available, installers will receive `https://developer.android.com/reference/android/content/pm/PackageInstaller#STATUS_FAILURE_BLOCKED` instead. Note that if the users decline the request, this session will be abandoned. If user intervention is required but never resolved, or requesting user pre-approval is not available, you may still call `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#commit(android.content.IntentSender)` as the typical installation.

<br />

| Parameters ||
|---|---|
| `details` | `PackageInstaller.PreapprovalDetails`: the adequate context to this session for requesting the approval from users prior to commit. This value cannot be `null`. <br /> |
| `statusReceiver` | `IntentSender`: called when the state of the session changes. Intents sent to this receiver contain `https://developer.android.com/reference/android/content/pm/PackageInstaller#EXTRA_STATUS` and the `https://developer.android.com/reference/android/content/pm/PackageInstaller#EXTRA_PRE_APPROVAL` would be `true`. Refer to the individual status codes on how to handle them. This value cannot be `null`. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | when `https://developer.android.com/reference/android/content/pm/PackageInstaller.PreapprovalDetails` is `null`. |
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | if `https://developer.android.com/reference/android/content/IntentSender` is `null`. |
| `https://developer.android.com/reference/java/lang/IllegalStateException` | if called on a multi-package session (no matter the parent session or any of the children sessions). |
| `https://developer.android.com/reference/java/lang/IllegalStateException` | if called again after this method has been called on this session. |
| `https://developer.android.com/reference/java/lang/SecurityException` | when the caller does not own this session. |
| `https://developer.android.com/reference/java/lang/SecurityException` | if called after the session has been committed or abandoned. |

### setAppMetadata

Added in [API level 34](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void setAppMetadata (PersistableBundle data)
```

Optionally set the app metadata. The size of this data cannot exceed the maximum allowed. Any existing data from the previous install will not be retained even if no data is set for the current install session. Setting data to null or an empty PersistableBundle will remove any metadata that has previously been set in the same session.

<br />

| Parameters ||
|---|---|
| `data` | `PersistableBundle`: a PersistableBundle containing the app metadata. This value may be `null`. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/io/IOException` | if writing the data fails. |

### setChecksums

Added in [API level 31](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)   
Deprecated in [API level 31](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void setChecksums (String name, 
                List<Checksum> checksums, 
                byte[] signature)
```

<br />

**This method was deprecated in API level 31.**   

do not use installer-provided checksums, use platform-enforced checksums e.g. `https://developer.android.com/reference/android/content/pm/Checksum#TYPE_WHOLE_MERKLE_ROOT_4K_SHA256` in `https://developer.android.com/reference/android/content/pm/PackageManager#requestChecksums(java.lang.String,%20boolean,%20int,%20java.util.List<java.security.cert.Certificate>,%20android.content.pm.PackageManager.OnChecksumsReadyListener)`.

Sets installer-provided checksums for the APK file in session.

<br />

| Parameters ||
|---|---|
| `name` | `String`: previously written as part of this session. `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#openWrite(java.lang.String,%20long,%20long)` This value cannot be `null`. <br /> |
| `checksums` | `List`: installer intends to make available via `https://developer.android.com/reference/android/content/pm/PackageManager#requestChecksums(java.lang.String,%20boolean,%20int,%20java.util.List<java.security.cert.Certificate>,%20android.content.pm.PackageManager.OnChecksumsReadyListener)` or `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#requestChecksums(java.lang.String,%20int,%20java.util.List<java.security.cert.Certificate>,%20java.util.concurrent.Executor,%20android.content.pm.PackageManager.OnChecksumsReadyListener)`. This value cannot be `null`. <br /> |
| `signature` | `byte`: DER PKCS#7 detached signature bytes over binary serialized checksums to enable integrity checking for the checksums or null for no integrity checking. `https://developer.android.com/reference/android/content/pm/PackageManager#requestChecksums(java.lang.String,%20boolean,%20int,%20java.util.List<java.security.cert.Certificate>,%20android.content.pm.PackageManager.OnChecksumsReadyListener)` will return the certificate used to create signature. Binary format for checksums: DataOutputStream dos; dos.writeInt(checksum.getType()); dos.writeInt(checksum.getValue().length); dos.write(checksum.getValue()); If using **openssl cms** , make sure to specify -binary -nosmimecap. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/java/lang/IllegalStateException` | if checksums for this file have already been added. |
| `https://developer.android.com/reference/java/lang/SecurityException` | if called after the session has been committed or abandoned. |
| `https://developer.android.com/reference/java/io/IOException` |   |

**See also:**

- [openssl cms](https://www.openssl.org/docs/man1.0.2/man1/cms.html)

### setStagingProgress

Added in [API level 21](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void setStagingProgress (float progress)
```

Set current progress of staging this session. Valid values are anywhere between 0 and 1.

Note that this progress may not directly correspond to the value reported by `https://developer.android.com/reference/android/content/pm/PackageInstaller.SessionCallback#onProgressChanged(int,%20float)`, as the system may carve out a portion of the overall progress to represent its own internal installation work.

<br />

| Parameters ||
|---|---|
| `progress` | `float` <br /> |

### transfer

Added in [API level 27](https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels)

```
public void transfer (String packageName)
```

Transfer the session to a new owner.

Only sessions that update the installing app can be transferred.

After the transfer to a package with a different uid all method calls on the session will cause `https://developer.android.com/reference/java/lang/SecurityException`s.

Once this method is called, the session is sealed and no additional mutations beside committing it may be performed on the session.

<br />

| Parameters ||
|---|---|
| `packageName` | `String`: The package of the new owner. Needs to hold the INSTALL_PACKAGES permission. This value cannot be `null`. <br /> |

| Throws ||
|---|---|
| `https://developer.android.com/reference/android/content/pm/PackageManager.NameNotFoundException` | if the new owner could not be found. |
| `https://developer.android.com/reference/java/lang/IllegalArgumentException` | if `packageName` is invalid. |
| `https://developer.android.com/reference/java/lang/IllegalStateException` | if streams opened through `https://developer.android.com/reference/android/content/pm/PackageInstaller.Session#openWrite(java.lang.String,%20long,%20long)` are still open. |
| `https://developer.android.com/reference/java/lang/SecurityException` | if called after the session has been committed or abandoned. |