#android #android-studio
#Android #android-studio
Вопрос:
Мое приложение выполняет вызов сервера, который может занять несколько секунд. Пользователь может свернуть приложение до получения ответа от сервера.
Итак, что я пытаюсь сделать, так это то, что если приложение будет свернуто при получении ответа от сервера, оно перейдет в режим PIP.
Когда я пытаюсь войти в режим Pip с минимизированным приложением, я получаю эту ошибку:
java.lang.IllegalStateException: Activity must be resumed to enter picture-in-picture
При выполнении этой строки возникает ошибка:
enterPictureInPictureMode();
Спасибо.
Комментарии:
1. Смогли ли вы это реализовать?
2. Вы могли бы выполнить вызов сервера, просмотреть результат и последовательно ввести pip с помощью
runBlocking
. Таким образом, вы убедитесь, что все происходит, и активность находится в состоянии возобновления. Однако сделайте функцию приостанавливаемой
Ответ №1:
Необходимо проверить, предоставлено ли специальное разрешение Picture-in-Picture
перед входом в режим.
AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
if (manager != null) {
int modeAllowed = manager.unsafeCheckOpNoThrow(OPSTR_PICTURE_IN_PICTURE, Process.myUid(),
context.getPackageName());
if (modeAllowed == AppOpsManager.MODE_ALLOWED) {
// Enter picture-in-picture
}
}
Ответ №2:
Если вы используете rn-android-библиотеку pip:
import android.app.AppOpsManager;
import android.content.Context;
import android.os.Process;
public void enterPictureInPictureMode() {
if (isPipSupported) {
AppOpsManager manager = (AppOpsManager) reactContext.getSystemService(Context.APP_OPS_SERVICE);
if (manager != null) {
int modeAllowed = manager.checkOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, Process.myUid(),
reactContext.getPackageName());
if (modeAllowed == AppOpsManager.MODE_ALLOWED) {
if (isCustomAspectRatioSupported) {
PictureInPictureParams params = new PictureInPictureParams.Builder()
.setAspectRatio(this.aspectRatio).build();
getCurrentActivity().enterPictureInPictureMode(params);
} else {
getCurrentActivity().enterPictureInPictureMode();
}
}
}
}
}
Ответ №3:
Согласно документу:
Также укажите, что ваше действие обрабатывает изменения конфигурации макета, чтобы ваше действие не перезапускалось, когда изменения макета происходят во время переходов в режим PiP.
Переключение в режим PiP вызывает изменения конфигурации, и это приводит к повторному запуску действия, говорит о переходе через остановлено -> уничтожено -> создано -> …
И мы можем узнать, как Activity решает, может ли она перейти в режим PiP или нет: https://cs.android.com/android/platform/superproject/ /master:frameworks/base/core/java/android/app/Activity.java
final void performStop(boolean preserveWindow, String reason) {
...
// Disallow entering picture-in-picture after the activity has been stopped
mCanEnterPictureInPicture = false;
...
}
public boolean enterPictureInPictureMode(@NonNull PictureInPictureParams params) {
...
if (!mCanEnterPictureInPicture) {
throw new IllegalStateException("Activity must be resumed to enter"
" picture-in-picture");
}
...
mIsInPictureInPictureMode = ActivityClient.getInstance().enterPictureInPictureMode(
mToken, params);
return mIsInPictureInPictureMode;
}
Поэтому вам может потребоваться еще раз проверить свой AndroidManifest, чтобы убедиться, что вы уже правильно обработали изменения конфигурации, чтобы избежать повторного использования:
<activity android:name="VideoActivity"
android:supportsPictureInPicture="true"
android:configChanges=
"screenSize|smallestScreenSize|screenLayout|orientation"
...