在我的项目中,我必须锁定活动的方向。 (我无法重新创建活动)
当用户更改设备的方向时,我想显示一条消息: “The View被锁定在这个位置......”
我可以使用以下代码轻松锁定方向:
if(version >= Build.VERSION_CODES.JELLY_BEAN_MR2){
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
}else{
int orientation = activity.getResources().getConfiguration().orientation;
if(orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}else{
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
}
使用此代码,视图已锁定,但我无法检测用户何时更改设备方向。
如果我使用以下代码:
@Override
public void onConfigurationChanged(Configuration newConfig) {
//Check if the orientation has change
if(newConfig.orientation != mOrientation){
Toast.makeText(this, "Message for user", Toast.LENGTH_SHORT).show();
}
//Try to lock the view but not working
newConfig.orientation = mOrientation;
//Obligatory line that reload the view and cannot be delete
//(is the biggest prolem of this code)
super.onConfigurationChanged(newConfig);
}
如果有人知道锁定视图并检测设备方向更改的方法,那将对我有所帮助。
全部谢谢
答案 0 :(得分:1)
也可以使用SensorManager
来解决。这是一个简单的演示,演示了如何将锁定活动的图像方向保持正确:
MainActivity:
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Surface;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
private ImageView img;
private SensorManager mSensorManager;
private Sensor mOrientation;
float value_0 = -10000;
float value_1 = -10000;
private SensorEventListener mOrientationSensorListener = new SensorEventListener() {
int orientation = -1;
@Override
public void onSensorChanged(SensorEvent event) {
int value ;
if(value_0 == event.values[0] && value_1==event.values[1]){
return;
}
// Log.d("values:", "values:" + event.values[0]+", "+event.values[1]);
if (event.values[1] > 0 && event.values[0] == 0) {
value = Surface.ROTATION_0;//portrait
if (orientation != value) {
updateImageRotation(value);
Log.d("orientation", "portrait + update");
}
orientation = value;
Log.d("orientation", "portrait ");
}
if (event.values[1] < 0 && event.values[0] == 0) {
value = Surface.ROTATION_180;//portrait reverse
if (orientation != value) {
updateImageRotation(value);
Log.d("orientation", "portrait reverse + update");
}
orientation = value;
Log.d("orientation", "portrait reverse");
}
if (event.values[0] > 0 && event.values[1] == 0) {
value = Surface.ROTATION_90;//portrait reverse
if (orientation != value) {
updateImageRotation(value);
Log.d("orientation", "landscape + update");
}
orientation = value;
Log.d("orientation", "landscape");
}
if (event.values[0] < 0 && event.values[1] == 0) {
value = Surface.ROTATION_270;//portrait reverse
if (orientation != value) {
updateImageRotation(value);
Log.d("orientation", "landscape + update");
}
orientation = value;
Log.d("orientation", "landscape reverse");
}
value_0=event.values[0];
value_1=event.values[1];
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
img = (ImageView) findViewById(R.id.img);
// Get sensor manager
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
// Get the default sensor of specified type
mOrientation = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
@Override
protected void onResume() {
super.onResume();
if (mOrientation != null) {
mSensorManager.registerListener(mOrientationSensorListener, mOrientation,
SensorManager.SENSOR_DELAY_GAME);
}
}
@Override
protected void onPause() {
super.onPause();
if (mOrientation != null) {
mSensorManager.unregisterListener(mOrientationSensorListener);
}
}
private void updateImageRotation(int degree) {
switch (degree) {
case Surface.ROTATION_0:
img.setRotation(0);
break;
case Surface.ROTATION_90:
img.setRotation(90);
break;
case Surface.ROTATION_180:
img.setRotation(180);
break;
case Surface.ROTATION_270:
img.setRotation(270);
break;
}
}
}
在清单中。方向锁定为portrait
,传感器需要作为功能
manifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest package="permissionsmngr.com.apipas.rotationmanage"
xmlns:android="http://schemas.android.com/apk/res/android">
<uses-feature
android:name="android.hardware.sensor.accelerometer"
android:required="true"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/activity_main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="permissionsmngr.com.apipas.rotationmanage.MainActivity">
<ImageView
android:layout_centerInParent="true"
android:id="@+id/img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"
/>
</RelativeLayout>
答案 1 :(得分:0)
下面的代码对我有用。
<强> MainActivity.java:强>
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startService( new Intent(this, Receiver.class) );
}
}
<强> BackgroundService.java 强>
public class Receiver extends Service {
private static final String BCAST_CONFIGCHANGED = "android.intent.action.CONFIGURATION_CHANGED";
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
IntentFilter filter = new IntentFilter();
filter.addAction(BCAST_CONFIGCHANGED);
this.registerReceiver(mBroadcastReceiver, filter);
}
@Override
public void onDestroy() {
}
@Override
public void onStart(Intent intent, int startid) {
}
public BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent myIntent) {
if ( myIntent.getAction().equals( BCAST_CONFIGCHANGED ) ) {
if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
}
else {
}
}
}
};
}
<强> Manifestfile.xml 强>
<service android:name=".Receiver">
<intent-filter>
<action android:name="android.intent.action.CONFIGURATION_CHANGED"/>
</intent-filter>
</service>
答案 2 :(得分:-1)
您只需使用OrientationEventListener
从传感器获取方向 (用Kotlin编写):
class MainActivity : AppCompatActivity() {
private var orientationEventListener: OrientationEventListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
orientationEventListener = object : OrientationEventListener(context) {
override fun onOrientationChanged(orientation: Int) {
// orientation is in degrees
// Show "The View is locked in this position ..." message if orientation is between 45° and 315°
viewModel.showViewIsLocked(orientation in 45..315)
}
}
}
override fun onResume() {
super.onResume()
orientationEventListener?.enable()
}
override fun onPause() {
orientationEventListener?.disable()
super.onPause()
}
}