내 주요 활동에는 중단해서는 안되는 일부 데이터베이스를 변경하는 코드가 있습니다. 다른 스레드에서 무거운 작업을 수행하고 취소 불가능으로 설정 한 진행 대화 상자를 사용하고 있습니다. 그러나 전화기를 회전하면 실행중인 프로세스에 대해 정말 나쁜 활동이 다시 시작되고 강제 종료가 발생한다는 것을 알았습니다.
내가 원하는 것은 방향 변경이 활성화되는 프로세스가 완료 될 때까지 화면 방향 변경을 프로그래밍 방식으로 비활성화하는 것입니다.
내 주요 활동에는 중단해서는 안되는 일부 데이터베이스를 변경하는 코드가 있습니다. 다른 스레드에서 무거운 작업을 수행하고 취소 불가능으로 설정 한 진행 대화 상자를 사용하고 있습니다. 그러나 전화기를 회전하면 실행중인 프로세스에 대해 정말 나쁜 활동이 다시 시작되고 강제 종료가 발생한다는 것을 알았습니다.
내가 원하는 것은 방향 변경이 활성화되는 프로세스가 완료 될 때까지 화면 방향 변경을 프로그래밍 방식으로 비활성화하는 것입니다.
답변:
로 자신의 크리스에 의해 설명 자동 응답 전화,
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
그리고
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
정말 매력처럼 작동합니다 ... 실제 장치에서!
에뮬레이터에서 테스트 할 때 손상되었다고 생각하지 마세요. ctrl + F11 단축키는 센서 이동을 에뮬레이션하지 않고 항상 화면 방향을 변경합니다.
편집 : 이것은 최선의 대답이 아니 었습니다. 의견에서 설명했듯이이 방법에는 문제가 있습니다. 진짜 답은 여기에 있습니다 .
ActivityInfo.SCREEN_ORIENTATION_SENSOR
Android의 기본 방향 잠금을 존중하지 않습니다. 방향을로 재설정합니다 ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
.
다른 답변 중 어느 것도 나를 위해 완벽하게 트릭을 만들지 못했지만 여기에 내가 찾은 것이 있습니다.
현재 방향 잠금 ...
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
방향 변경을 다시 허용해야하는 경우 기본값으로 다시 설정하십시오.
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
Configuration.ORIENTATION_PORTRAIT
는 두 가로 모드 (즉, '보통'과 반전)에서 반환 된다는 것입니다. 따라서 전화기가 가로 방향이 반전되어 있고 설정하면 ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE
거꾸로 뒤집 힙니다. API 9에서 ActivityInfo는 SCREEN_ORIENTATION_REVERSE_LANDSCAPE
상수를 도입 했지만 Configuration
클래스를 통해 이러한 방향을 감지하는 방법을 찾지 못했습니다 .
다음은 API 8 이상에서 작동하고 역 세로 및 가로에서 작동하며 "자연"방향이 가로 인 Galaxy 탭에서 작동하는보다 완전하고 최신 솔루션입니다 ( activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)
방향을 잠금 해제하려면 호출 ).
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
public static void lockActivityOrientation(Activity activity) {
Display display = activity.getWindowManager().getDefaultDisplay();
int rotation = display.getRotation();
int height;
int width;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2) {
height = display.getHeight();
width = display.getWidth();
} else {
Point size = new Point();
display.getSize(size);
height = size.y;
width = size.x;
}
switch (rotation) {
case Surface.ROTATION_90:
if (width > height)
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
else
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
break;
case Surface.ROTATION_180:
if (height > width)
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
else
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
break;
case Surface.ROTATION_270:
if (width > height)
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
else
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
default :
if (height > width)
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
else
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
static
를 만들고 Activity activity
매개 변수로 추가 할 수 있습니다 .
역방향 모드도 관리하기 위해 해당 코드를 사용하여 활동 방향을 수정했습니다.
int rotation = getWindowManager().getDefaultDisplay().getRotation();
switch(rotation) {
case Surface.ROTATION_180:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
break;
case Surface.ROTATION_270:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
break;
case Surface.ROTATION_0:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
case Surface.ROTATION_90:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
break;
}
그리고 다시 방향을 허용하려면 :
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
현재 방향을 가로 또는 세로로 고정하는 데 사용 합니다.
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
잠금 해제 방향에 사용 합니다.
답을 찾았습니다. 이를 위해 활동에서 http://developer.android.com/reference/android/R.attr.html#screenOrientation에setRequestedOrientation(int)
지정된 값 중 하나로 호출 할 수 있습니다.
스레드를 시작하기 전에 나는 setRequestedOrientation(OFF)
(OFF = nosensor)라고 불렀고 스레드가 끝나면 setRequestedOrientation(ON)
(ON = 센서)를 불렀습니다 . 매력처럼 작동합니다.
모두 감사합니다. 이전 상태로 복원되었는지 확인하기 위해 Pilot_51의 솔루션을 수정했습니다. 또한 비가로 및 비세로 화면을 지원하기 위해 변경 사항을 적용했습니다 (그러나 이러한 화면에서 테스트하지는 않았습니다).
prevOrientation = getRequestedOrientation();
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
}
그런 다음 복원하려면
setRequestedOrientation(prevOrientation);
protected void setLockScreenOrientation(boolean lock) {
if (Build.VERSION.SDK_INT >= 18) {
setRequestedOrientation(lock?ActivityInfo.SCREEN_ORIENTATION_LOCKED:ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
return;
}
if (lock) {
switch (getWindowManager().getDefaultDisplay().getRotation()) {
case 0: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); break; // value 1
case 2: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); break; // value 9
case 1: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); break; // value 0
case 3: setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); break; // value 8
}
} else
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR); // value 10
}
다음은 매번 작동하고 현재 방향을 유지하는 솔루션입니다 ( Activity.Info.SCREEN_ORIENTATION_PORTRAIT
예를 들어 0 °로 설정을 사용 하지만 사용자는 현재 방향으로 180 ° 방향을 가질 수 있음).
// Scope: Activity
private void _lockOrientation() {
if (super.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT);
} else {
super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE);
}
}
private void _unlockOrientation() {
super.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
사용 ActivityInfo.SCREEN_ORIENTATION_USER
당신은이 장치에서 활성화 한 경우에만 화면 회전하십시오.
이것은 나를 위해 완벽하게 작동합니다. 태블릿 / 휴대 전화의 "자연스러운 방향"이 다른 문제를 해결합니다.)
int rotation = getWindowManager().getDefaultDisplay().getRotation();
Configuration config = getResources().getConfiguration();
int naturalOrientation;
if (((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) &&
config.orientation == Configuration.ORIENTATION_LANDSCAPE)
|| ((rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270) &&
config.orientation == Configuration.ORIENTATION_PORTRAIT)) {
naturalOrientation = Configuration.ORIENTATION_LANDSCAPE;
} else {
naturalOrientation = Configuration.ORIENTATION_PORTRAIT;
}
// because getRotation() gives "rotation from natural orientation" of device (different on phone and tablet)
// we need to update rotation variable if natural orienation isn't 0 (mainly tablets)
if (naturalOrientation == Configuration.ORIENTATION_LANDSCAPE)
rotation = ++rotation % 4;
switch (rotation) {
case Surface.ROTATION_0: //0
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
case Surface.ROTATION_90: //1
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
break;
case Surface.ROTATION_180: //2
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
break;
case Surface.ROTATION_270: //3
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
break;
}
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
디스플레이 회전에 따라 장치의 방향을 결정하는 솔루션을 찾았습니다. 방향을 알면 방향을 잠그고 필요할 때 나중에 해제 할 수 있습니다. 이 솔루션은 장치가 역 가로 모드 인지 여부도 확인할 수 있습니다 .
private void lockOrientation(){
switch (((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation()) {
// Portrait
case Surface.ROTATION_0:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
//Landscape
case Surface.ROTATION_90:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
break;
// Reversed landscape
case Surface.ROTATION_270:
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
break;
}
}
나중에 방향을 해제해야하는 경우이 메서드를 호출 할 수 있습니다.
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
이 코드는 읽기가 더 쉽다고 생각합니다.
private void keepOrientation() {
int orientation = getResources().getConfiguration().orientation;
int rotation = getWindowManager().getDefaultDisplay().getRotation();
switch (rotation) {
case Surface.ROTATION_0:
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
break;
case Surface.ROTATION_90:
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
break;
case Surface.ROTATION_180:
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
break;
default:
if (orientation == Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
}
}
}
네 가지 가능성을 다루기 위해 기존의 회전 / 방향 값 조합이 필요하다는 사실을 발견했습니다. 세로 / 가로 값과 장치의 자연스러운 방향이 있습니다. 화면이 "자연"세로 또는 가로 방향 일 때 장치의 자연 방향이 0 도의 회전 값을 갖는다 고 가정 해 보겠습니다. 마찬가지로 가로 또는 세로 일 때 90 도의 회전 값이 있습니다 (방향 @ 0 도의 반대 임). 따라서 0도 또는 90 도가 아닌 회전 값은 "역방향"방향을 의미합니다. 좋아, 다음은 몇 가지 코드입니다.
public enum eScreenOrientation
{
PORTRAIT (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT),
LANDSCAPE (ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE),
PORTRAIT_REVERSE (ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT),
LANDSCAPE_REVERSE (ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE),
UNSPECIFIED_ORIENTATION (ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
public final int activityInfoValue;
eScreenOrientation ( int orientation )
{
activityInfoValue = orientation;
}
}
public eScreenOrientation currentScreenOrientation ( )
{
final int rotation = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
final int orientation = getResources().getConfiguration().orientation;
switch ( orientation )
{
case Configuration.ORIENTATION_PORTRAIT:
if ( rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90 )
return eScreenOrientation.PORTRAIT;
else
return eScreenOrientation.PORTRAIT_REVERSE;
case Configuration.ORIENTATION_LANDSCAPE:
if ( rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_90 )
return eScreenOrientation.LANDSCAPE;
else
return eScreenOrientation.LANDSCAPE_REVERSE;
default:
return eScreenOrientation.UNSPECIFIED_ORIENTATION;
}
}
public void lockScreenOrientation ( )
throws UnsupportedDisplayException
{
eScreenOrientation currentOrientation = currentScreenOrientation( );
if ( currentOrientation == eScreenOrientation.UNSPECIFIED_ORIENTATION )
throw new UnsupportedDisplayException("Unable to lock screen - unspecified orientation");
else
setRequestedOrientation( currentOrientation.activityInfoValue );
}
public void unlockScreenOrientation ( )
{
setRequestedOrientation( ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED );
}
잠금 해제에서 이전 상태와 반대로 UNSPECIFIED로 설정했기 때문에 여기에있는 대부분의 답변이 마음에 들지 않았습니다. ProjectJourneyman은이를 고려하여 훌륭했지만 저는 Roy의 잠금 코드를 선호했습니다. 따라서 내 권장 사항은 두 가지를 혼합하는 것입니다.
private int prevOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
private void unlockOrientation() {
setRequestedOrientation(prevOrientation);
}
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
private void lockOrientation() {
prevOrientation = getRequestedOrientation();
Display display = getWindowManager().getDefaultDisplay();
int rotation = display.getRotation();
int height;
int width;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB_MR2) {
height = display.getHeight();
width = display.getWidth();
} else {
Point size = new Point();
display.getSize(size);
height = size.y;
width = size.x;
}
switch (rotation) {
case Surface.ROTATION_90:
if (width > height)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
else
setRequestedOrientation(9/* reversePortait */);
break;
case Surface.ROTATION_180:
if (height > width)
setRequestedOrientation(9/* reversePortait */);
else
setRequestedOrientation(8/* reverseLandscape */);
break;
case Surface.ROTATION_270:
if (width > height)
setRequestedOrientation(8/* reverseLandscape */);
else
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
break;
default :
if (height > width)
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
else
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
당신이 사용할 수있는
public void swapOrientaionLockState(){
try{
if (Settings.System.getInt(mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION) == 1) {
Display defaultDisplay = ((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Settings.System.putInt(mContext.getContentResolver(), Settings.System.USER_ROTATION, defaultDisplay.getRotation());
Settings.System.putInt(mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0);
} else {
Settings.System.putInt(mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 1);
}
Settings.System.putInt(mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, !orientationIsLocked() ? 1 : 0);
} catch (Settings.SettingNotFoundException e){
e.printStackTrace();
}
}
public boolean orientationIsLocked(){
if(canModifiSetting(mContext)){
try {
return Settings.System.getInt(mContext.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION) == 0;
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
}
return false;
}
public static boolean canModifiSetting(Context context){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return Settings.System.canWrite(context);
} else {
return true;
}
}