Принятый ответ и все, что предполагает setRequestedOrientation
, далеко не идеален, потому что, , как указано в документации , вызов setRequestedOrientation
во время выполнения, может привести к перезапуску действия, что кроме всего прочего, влияет на анимацию между экранами.
Если возможно, лучше всего установить желаемую ориентацию в AndroidManifest.xml
.
Но поскольку каждый разработчик склонен к ошибкам, чтобы не забыть изменить манифест при добавлении нового действия, это можно сделать во время сборки, отредактировав файл AndroidManifest во время сборки.
Существуют некоторые предостережения относительно редактирования AndroidManifest таким способом, о котором вам необходимо знать:
- Если в выходном манифесте есть несколько записей
<activity-alias>
, вы должны сопоставить <activity(?!-)
вместо <activity
, чтобы избежать их изменения (и использовать replaceAll
, который соответствует регулярному выражению, вместо replace
, который соответствует струна)
- Будьте осторожны, чтобы не соответствовать действиям, которые находятся вне вашего контроля. См. facebook + android: только полноэкранные непрозрачные действия могут запрашивать ориентацию
Моим требованием было обновить все действия, чтобы они имели фиксированную ориентацию, но только в выпусках сборки . Я добился этого с помощью небольшого кода в build.gradle
, который выполняет простую замену строк в AndroidManifest (при условии, что нет действий уже имеет указанную ориентацию):
Пример решения, совместимого с Android Studio 3.0 (касается только действий, соответствующих com.mycompany.*
):
android.applicationVariants.all { variant ->
variant.outputs.all { output ->
if (output.name == "release") {
output.processManifest.doLast {
String manifestPath = "$manifestOutputDirectory/AndroidManifest.xml"
def manifestContent = file(manifestPath).getText('UTF-8')
// replacing whitespaces and newlines between `<activity>` and `android:name`, to facilitate the next step
manifestContent = manifestContent.replaceAll("<activity\\s+\\R\\s+", "<activity ")
// we leverage here that all activities have android:name as the first property in the XML
manifestContent = manifestContent.replace(
"<activity android:name=\"com.mycompany.",
"<activity android:screenOrientation=\"userPortrait\" android:name=\"com.mycompany.")
file(manifestPath).write(manifestContent, 'UTF-8')
}
}
}
}
Пример решения, совместимого с Android Studio 2.3 (соответствует всем действиям, но не соответствует <activity-alias>
записям):
android.applicationVariants.all { variant ->
variant.outputs.each { output ->
if (output.name == "release") {
output.processManifest.doLast {
def manifestOutFile = output.processManifest.manifestOutputFile
def newFileContents = manifestOutFile.getText('UTF-8')
.replaceAll(/<activity(?!-)/, "<activity android:screenOrientation=\"userPortrait\" ")
manifestOutFile.write(newFileContents, 'UTF-8')
}
}
}
}
Я использовал userPortrait
вместо portrait
, так как я предпочитаю предоставить пользователю больше гибкости.
Вышеуказанное работает из коробки, если у вас есть только варианты (отладка, выпуск). Если у вас есть дополнительные вкусы, вам, возможно, придется немного их настроить.
Вы можете удалить if (output.name == "release")
в зависимости от ваших потребностей.