Android with minSdkVersion=15
をベースにしたモバイルアプリケーションを開発しています。タブレットの場合は縦向き、スマートフォンの場合は縦向きのみをサポートしたいと思います。すべてが魅力のように機能しますが、私はスマートフォンがランドスケープモードになっていて、新しいアクティビティをトリガーしようとすると、しばらくランドスケープモードで開き、ポートレートに自動回転します。私のアクティビティはそれぞれ、GeneralActivityクラスを拡張します。
public class GeneralActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// If smartphone lock orientation to portrait
if (!Helper.isTablet(this.getApplicationContext())){
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
}
私はこの機能でタブレットを検出します:
public class Helper {
public static boolean isTablet(Context context){
Configuration config = context.getResources().getConfiguration()
return config.smallestScreenWidthDp >= 600;
}
}
Manifest.xml内でAndroid:screenOrientation
を指定しないことを選択します。これにより、タブレットのすべてのインターフェイスの向きをサポートできるようになります。私は何かが足りないのですか?
[〜#〜]編集[〜#〜]
ジョナサンの回答で提案されたベストプラクティスを適用することにしましたが、私が説明した問題はまだここにあります。 githubの私のリポジトリは次のとおりです: https://github.com/giacmarangoni/Android-Orientation-Test
Android N&Oでも同じ問題が発生し、解決策が見つかりました。
私はまだonCreateメソッドでsetRequestedOrientationを使用していますが、マニフェストのすべてのアクティビティにこれを追加しました。
Android:screenOrientation="behind"
これにより、アクティビティが前のアクティビティと同じ方向で起動するようになります。その後、setRequestedOrientationはそれをオーバーライドしますが、前のアクティビティと同じである場合、ユーザーとして何も変更されません。
次を使用して、この問題を解決する正しい方法を見つけました。
_Android:screenOrientation="locked"
_
この問題でマニフェストで宣言されたすべてのアクティビティで。
そして、プログラムでsetRequestedOrientation()
を使用して、onCreate()メソッド内で横向きか縦向きかを定義します。
ところで、あなたのGitHubプロジェクトでは、マニフェストを次のようにlocked
方向に追加したところ、ついに機能しました。
_<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.giacomomarangoni.orientationtest">
<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="locked">
<intent-filter>
<action Android:name="Android.intent.action.MAIN" />
<category Android:name="Android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity Android:name=".OtherActivity"
Android:screenOrientation="locked">
</activity>
</application>
</manifest>
_
それがあなたにも役立つことを願っています:)
Android Nデバイスでも同じ問題に直面しました。タブレットの向きと電話の縦向きの両方をサポートするために、次のトリックを実行しました。
マニフェストの各アクティビティにポートレートを設定します。見た目は悪いですが、この場合、画面は自動回転しません:Android:screenOrientation="portrait"
BaseActivityセット内:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (isTablet(){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
}
protected boolean isTablet() {
return getResources().getBoolean(R.bool.tablet);
}
私はこのソリューションを利用しています。マニフェストで画面の向きを縦向きに宣言します
<activity Android:name=".activities.MainActivity"
Android:screenOrientation="portrait">
<intent-filter>
<action Android:name="Android.intent.action.MAIN"/>
<category Android:name="Android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
次に、super.onCreateを呼び出す前に、onCreate
の基本アクティビティで、デバイスがタブレットの場合、向きを未指定に設定します。
@Override
protected void onCreate(Bundle savedInstanceState) {
if (!getResources().getBoolean(R.bool.portrait_only)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
super.onCreate(savedInstanceState);
}
ドキュメントから:
指定なし:設定なし:システムに最適な方向を決定させます。これは、以下のアクティビティで選択された方向、またはこのアクティビティがタスクの最下部である場合はユーザーの優先方向のいずれかになります。ユーザーが設定を通じてセンサーベースの向きを明示的にオフにした場合、センサーベースのデバイスの回転は無視されます。デフォルトでない場合、センサーベースの向きが考慮され、ユーザーがデバイスを回転させる方法に基づいて向きが変更されます。
これは私にとってはうまくいきましたが、これまでのところ欠点は見つかりませんでした。私はこれをエミュレーターでテストしただけで、アプリが縦向きで始まり、電話の他のソリューションで起こったように回転しているようには見えません。とにかく、私は電話がより多く使用されているという理由だけでタブレットよりもうまく機能することを望んでいます。
このソリューションで機能しないものを見つけた場合は、私を襲ってください!
リソースとサイズ修飾子を使用する良い方法は次のとおりです。
このboolリソースをres/valuesにbools.xmlなどとして配置します(ファイル名はここでは関係ありません)。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
これをres/values-sw600dpとres/values-xlargeに入れます:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">false</bool>
</resources>
Android Studioにこれらのディレクトリとファイルを追加する方法については、この補足回答を参照してください。
次に、アクティビティのonCreateメソッドで次の操作を実行できます。
if(getResources().getBoolean(R.bool.portrait_only)){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
最小幅方向に600dpを超えるデバイス、またはAndroid 3.2より前のデバイス(基本的にタブレット)でx-largeのデバイスは、センサーやユーザーがロックした回転などに基づいて、通常のように動作します。その他すべて(電話、かなり多く)はポートレートのみになります。
出典: 元の回答
基本アクティビティには、次のようなものを入れることができます。
/* Device types. */
static int MOBILE_DEVICE = 0;
static int SEVEN_INCH_TABLET = 1;
static int TEN_INCH_TABLET = 2;
private static int deviceType = MOBILE_DEVICE;
private boolean deviceTypeDetermined = false;
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
@Override
protected void onCreate(Bundle savedInstanceState) {
if ( ! deviceTypeDetermined) setDeviceType();
/* Screen rotation only for tablets. */
if (getDeviceType() < SEVEN_INCH_TABLET) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
lockScreenOrientation();
......
}
// ---------------------------------------------------------------------------------------------
static int getDeviceType() {
return deviceType;
}
// ---------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
private void setDeviceTypeDetermined() {
this.deviceTypeDetermined = true;
}
// ---------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
private void setDeviceType() {
/*
Let's invest on what kind of screen our APP is invited...
We only make a difference in 10", 7" tablets and the rest...
*/
Display mDisplay = getWindowManager().getDefaultDisplay();
Point mScreenResolution = new Point();
mDisplay.getRealSize(mScreenResolution);
int mWidthPixels = mScreenResolution.x;
int mHeightPixels = mScreenResolution.y;
DisplayMetrics mMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(mMetrics);
float mWidthDpi = mMetrics.xdpi;
float mHeightDpi = mMetrics.ydpi;
float mWidthInches = mWidthPixels / mWidthDpi;
float mHeightInches = mHeightPixels / mHeightDpi;
double mDiagonalInches = Math.sqrt(
(mWidthInches * mWidthInches)
+ (mHeightInches * mHeightInches));
if (mDiagonalInches >= 9) {
/*
A tablet with 8" x 5" is called a 10", but it is in fact
9.43398". Interesting that this kind of things happens in
the world of informatics.... ;)
*/
MyBaseAppCompatActivity.deviceType = TEN_INCH_TABLET;
}
else if (mDiagonalInches >= 7) {
MyBaseAppCompatActivity.deviceType = SEVEN_INCH_TABLET;
}
else
{
MyBaseAppCompatActivity.deviceType = MOBILE_DEVICE;
}
setDeviceTypeDetermined();
}
// ---------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
void lockScreenOrientation() {
/* Screen rotation only for tablets. */
if (deviceType < SEVEN_INCH_TABLET ) return;
setRequestedOrientation(getResources().getConfiguration().orientation);
}
// ---------------------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------------------
void unlockScreenOrientation() {
/* Screen rotation only for tablets. */
if (deviceType < SEVEN_INCH_TABLET ) return;
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
// ---------------------------------------------------------------------------------------------
そして、onCreateでのアクティビティでは:
// ---------------------------------------------------------------------------------------------
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
protected void onCreate(Bundle savedInstanceState) {
// -----------------------------------------------------------------------------------------
super.onCreate(savedInstanceState);
if (getDeviceType() >= SEVEN_INCH_TABLET) unlockScreenOrientation();
setContentView(R.layout.main_activity);
.........
// ---------------------------------------------------------------------------------------------