Android Activity屏幕旋转方向完全控制

我们知道,系统提供了android:configChanges="orientation" 清单文件属性以监听屏幕旋转,进而触发onConfigurationChanged方法。

但这有时不能完全满足我们的需求。比如典型的应用场景:视频播放器的屏幕方向锁功能。

下面贡献屏幕旋转完全控制类ActivityRotationController,解决一切屏幕旋转问题。

import android.app.Activity;
import android.content.ContentResolver;
import android.content.pm.ActivityInfo;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.view.OrientationEventListener;


/**
 * 该类可以对Activity旋转和方向进行更加灵活的控制。
 * 注意,使用该类进行方向控制的Activity不要在清单文件中添加:
 * android:configChanges="orientation" 
 * 
 * 典型的应用场景:
 * 视频播放器的屏幕方向锁功能。
 * 当锁住屏幕方向后,Activity就不会随着手机方向的旋转而改变方向。一旦打开锁,Activity将会立即随着屏幕的方向而改变。
 * 
 * 一般调用代码:
 * 
 * 默认打开锁
 * ActivityRotationController controller=new ActivityRotationController(this);
 * 
 * 打开锁
 * controller.openActivityRotation();
 * 
 * 关闭锁
 * controller.closeActivityRotation();
 * 
 * 关闭监听,恢复到系统之前旋转设定
 * controller.disable()
 * 
 * 要求的权限
 * @permission android.permission.WRITE_SETTINGS
 */

public class ActivityRotationController extends OrientationEventListener {
	private int systemRotation;
	private boolean activityRotation;
	private int activityOrientation;
	private Activity activity;

	public ActivityRotationController(Activity activity) {
		super(activity);
		this.activity = activity;
		activityOrientation = activity.getResources().getConfiguration().orientation;
		try {
			systemRotation = getScreenRotation(activity.getContentResolver());
		} catch (SettingNotFoundException e) {
			e.printStackTrace();
			systemRotation = -1;
		}
		
		openActivityRotation();
		enable();
	}

	/**
	 * 打开Activity旋转。
	 * 如果打开了屏幕旋转,Activity将接收屏幕旋转事件并执行onConfigurationChanged方法。
	 */
	public void openActivityRotation() {
		activityRotation = true;
	}

	/**
	 * 关闭Activity旋转。
	 * 无论是否打开屏幕旋转,Activity都不能接收到屏幕旋转事件。
	 */
	public void closeActivityRotation() {
		activityRotation = false;
	}

	/**
	 * 检查Activity能否旋转
	 */
	public boolean isActivityRotationEnabled() {
		return activityRotation;
	}

	/**
	 * 获取Activity当前方向。
	 * 注意,Activity方向不是屏幕方向。只有打开Activity旋转,Activity方向才和屏幕方向保持一致。
	 */
	public int getActivityOrientation() {
		return activityOrientation;
	}

	/**
	 * 打开对屏幕旋转的监听,并设置屏幕为可旋转。
	 */
	@Override
	public void enable() {
		super.enable();
		setScreenRotation(activity.getContentResolver(), 0);
	}

	/**
	 * 关闭对屏幕旋转的监听,并恢复到系统之前旋转设定。
	 */
	@Override
	public void disable() {
		super.disable();
		if (systemRotation == -1) {
			return;
		}
		setScreenRotation(activity.getContentResolver(), systemRotation);
	}

	@Override
	public void onOrientationChanged(int orientation) {
		if (orientation < 0) {
			return;
		}
		
		int newOrientation= ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
		if (orientation >= 0 && orientation <= 60) {
			newOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
		}else if (orientation >60 && orientation <120) {
			newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
		}else if (orientation >=120 && orientation <=240) {
			newOrientation = ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT;
		}else if (orientation >240 && orientation <300) {
			newOrientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
		}else if (orientation >=300 && orientation <=360) {
			newOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
		}else{
			return;
		}
		
		if ((newOrientation != orientation) && activityRotation) {
			activity.setRequestedOrientation(newOrientation);
			activityOrientation = newOrientation;
		}
	}

	private void setScreenRotation(ContentResolver cr, int rotation) {
		Settings.System.putInt(cr, Settings.System.ACCELEROMETER_ROTATION,
				rotation);
	}

	private int getScreenRotation(ContentResolver cr)
			throws SettingNotFoundException {
		return Settings.System.getInt(cr,
				Settings.System.ACCELEROMETER_ROTATION);
	}

}

国际惯例

————————————————————————————————————————————————————————

作者:薄荷记账  (转载请注明原作者)

简洁   稳定   优雅   无限可能


你可能感兴趣的:(Android Activity屏幕旋转方向完全控制)