Existe-t-il un moyen de vérifier si l'utilisateur utilise une tablette ou un téléphone? J'ai des problèmes avec ma fonction d'inclinaison et ma nouvelle tablette (Transformer)
Existe-t-il un moyen de vérifier si l'utilisateur utilise une tablette ou un téléphone? J'ai des problèmes avec ma fonction d'inclinaison et ma nouvelle tablette (Transformer)
Réponses:
Comme cela a été mentionné précédemment, vous ne souhaitez pas vérifier si l'appareil est une tablette ou un téléphone mais vous souhaitez connaître les fonctionnalités de l'appareil,
La plupart du temps, la différence entre une tablette et un téléphone réside dans la taille de l'écran, c'est pourquoi vous souhaitez utiliser des fichiers de mise en page différents. Ces fichiers sont stockés dans les res/layout-<qualifiers>
répertoires. Vous pouvez créer un fichier XML dans le directoy res/values-<same qualifiers>
pour chacune de vos mises en page et y placer une ressource int / bool / string pour distinguer les mises en page que vous utilisez.
Fichier res/values/screen.xml
(en supposant qu'il res/layout/
contient vos fichiers de mise en page pour les combinés)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">phone</string>
</resources>
Fichier res/values-sw600dp/screen.xml
(en supposant qu'il res/layout-sw600dp/
contient vos fichiers de mise en page pour les petites tablettes comme la Nexus 7)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">7-inch-tablet</string>
</resources>
Fichier res/values-sw720dp/screen.xml
(en supposant qu'il res/layout-sw720dp/
contient vos fichiers de mise en page pour les grandes tablettes comme le Nexus 10):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">10-inch-tablet</string>
</resources>
Désormais, le type d'écran est accessible via la R.string.screen_type
constante.
Pour détecter si l'appareil est une tablette ou non, utilisez le code suivant:
public boolean isTablet(Context context) {
boolean xlarge = ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE);
boolean large = ((context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE);
return (xlarge || large);
}
Les tailles d'écran LARGE et XLARGE sont déterminées par le fabricant en fonction de la distance de l'œil à laquelle elles doivent être utilisées (d'où l'idée d'une tablette).
En savoir plus: http://groups.google.com/group/android-developers/browse_thread/thread/d6323d81f226f93f
Configuration.SCREENLAYOUT_SIZE_XLARGE
, donc vous n'avez pas besoin d'utiliser une constante, et vous pouvez l'utiliser >= LARGE
.
Ce post m'a beaucoup aidé,
Malheureusement, je n'ai pas la réputation nécessaire pour évaluer toutes les réponses qui m'ont aidé.
J'avais besoin d'identifier si mon appareil était une tablette ou un téléphone, avec cela je pourrais implémenter la logique de l'écran. Et dans mon analyse, la tablette doit mesurer plus de 7 pouces (Xlarge) à partir de MDPI.
Voici le code ci-dessous, qui a été créé à partir de cet article.
/**
* Checks if the device is a tablet or a phone
*
* @param activityContext
* The Activity Context.
* @return Returns true if the device is a Tablet
*/
public static boolean isTabletDevice(Context activityContext) {
// Verifies if the Generalized Size of the device is XLARGE to be
// considered a Tablet
boolean xlarge = ((activityContext.getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK) ==
Configuration.SCREENLAYOUT_SIZE_XLARGE);
// If XLarge, checks if the Generalized Density is at least MDPI
// (160dpi)
if (xlarge) {
DisplayMetrics metrics = new DisplayMetrics();
Activity activity = (Activity) activityContext;
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
// MDPI=160, DEFAULT=160, DENSITY_HIGH=240, DENSITY_MEDIUM=160,
// DENSITY_TV=213, DENSITY_XHIGH=320
if (metrics.densityDpi == DisplayMetrics.DENSITY_DEFAULT
|| metrics.densityDpi == DisplayMetrics.DENSITY_HIGH
|| metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM
|| metrics.densityDpi == DisplayMetrics.DENSITY_TV
|| metrics.densityDpi == DisplayMetrics.DENSITY_XHIGH) {
// Yes, this is a tablet!
return true;
}
}
// No, this is not a tablet!
return false;
}
Pourquoi ne pas calculer la taille de la diagonale de l'écran et l'utiliser pour décider si l'appareil est un téléphone ou une tablette?
private boolean isTablet()
{
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
display.getMetrics(displayMetrics);
int width = displayMetrics.widthPixels / displayMetrics.densityDpi;
int height = displayMetrics.heightPixels / displayMetrics.densityDpi;
double screenDiagonal = Math.sqrt( width * width + height * height );
return (screenDiagonal >= 9.0 );
}
Bien sûr, on peut se demander si le seuil doit être de 9 pouces ou moins.
il n'y a pas de différence. Vous devez définir ce que vous pensez être la différence et vérifier cela. Un onglet Galaxy est-il un téléphone? ou une tablette? et pourquoi?
Vous devez définir les fonctionnalités spécifiques que vous recherchez et coder pour cela.
Il semble que vous recherchez «inclinaison». Je pense que c'est la même chose que l'accéléromètre (est-ce un mot?). Vous pouvez simplement vérifier si l'appareil le prend en charge, en utilisant:
public class Accel extends Activity implements SensorListener {
...
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
boolean accelSupported = sensorMgr.registerListener(this,
SENSOR_ACCELEROMETER,
SENSOR_DELAY_UI);
...
}
(de http://stuffthathappens.com/blog/2009/03/15/android-accelerometer/ . Je ne l'ai pas testé)
Je suppose que lorsque vous définissez «Mobile / Téléphone», vous souhaitez savoir si vous pouvez passer un appel téléphonique sur l'appareil, ce qui ne peut pas être fait sur quelque chose qui serait défini comme une «tablette». La façon de vérifier cela est ci-dessous. Si vous souhaitez savoir quelque chose en fonction des capteurs, de la taille de l'écran, etc., c'est vraiment une question différente.
En outre, tout en utilisant la résolution d'écran, ou la gestion des ressources large par rapport à xlarge, peut avoir été une approche valide dans le passé, de nouveaux appareils `` mobiles '' sont maintenant livrés avec des écrans si grands et des résolutions élevées qu'ils brouillent cette ligne si vous le souhaitez vraiment pour connaître les appels téléphoniques par rapport à aucune capacité d'appel téléphonique, ce qui suit est «meilleur».
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
return "Tablet";
}else{
return "Mobile";
}
Basé sur Robert Dale Johnson III et Helton Isac, j'ai trouvé ce code J'espère que c'est utile
public static boolean isTablet(Context context) {
TelephonyManager manager =
(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if (manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) {
//Tablet
return true;
} else {
//Mobile
return false;
}
}
public static boolean isTabletDevice(Context activityContext) {
// Verifies if the Generalized Size of the device is XLARGE to be
// considered a Tablet
boolean xlarge =
((activityContext.getResources().getConfiguration().screenLayout &
Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE);
// If XLarge, checks if the Generalized Density is at least MDPI (160dpi)
if (xlarge) {
DisplayMetrics metrics = new DisplayMetrics();
Activity activity = (Activity) activityContext;
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
// MDPI=160, DEFAULT=160, DENSITY_HIGH=240, DENSITY_MEDIUM=160,
// DENSITY_TV=213, DENSITY_XHIGH=320
if (metrics.densityDpi == DisplayMetrics.DENSITY_DEFAULT
|| metrics.densityDpi == DisplayMetrics.DENSITY_HIGH
|| metrics.densityDpi == DisplayMetrics.DENSITY_MEDIUM
|| metrics.densityDpi == DisplayMetrics.DENSITY_XHIGH) {
// Yes, this is a tablet!
return true;
}
}
// No, this is not a tablet!
return false;
}
Donc, dans votre code, créez un filtre comme
if(isTabletDevice(Utilities.this) && isTablet(Utilities.this)){
//Tablet
} else {
//Phone
}
Dans le code source de l' application Google IOSched 2017 , la méthode suivante est utilisée:
public static boolean isTablet(Context context) {
return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
Pour ceux qui souhaitent se référer au code de Google pour décider quels appareils utiliseront une interface utilisateur pour tablette, vous pouvez vous référer ci-dessous:
// SystemUI (status bar) layout policy
int shortSizeDp = shortSize
* DisplayMetrics.DENSITY_DEFAULT
/ DisplayMetrics.DENSITY_DEVICE;
if (shortSizeDp < 600) {
// 0-599dp: "phone" UI with a separate status & navigation bar
mHasSystemNavBar = false;
mNavigationBarCanMove = true;
} else if (shortSizeDp < 720) {
// 600-719dp: "phone" UI with modifications for larger screens
mHasSystemNavBar = false;
mNavigationBarCanMove = false;
} else {
// 720dp: "tablet" UI with a single combined status & navigation bar
mHasSystemNavBar = true;
mNavigationBarCanMove = false;
}
}
shortSize
?
Cette méthode est une recommandation de Google. Je vois ce code dans l'application Android officielle Googleiosched
public static boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
public static bool isTablet (Context context) { return (context.Resources.Configuration.ScreenLayout & Android.Content.Res.ScreenLayout.SizeMask) >= Android.Content.Res.ScreenLayout.SizeLarge; }
Les autres réponses répertorient de nombreuses façons de déterminer par programme si l'appareil est un téléphone ou une tablette. Cependant, si vous lisez la documentation , ce n'est pas la méthode recommandée pour prendre en charge différentes tailles d'écran.
Au lieu de cela, déclarez différentes ressources pour les tablettes ou les téléphones. Pour ce faire , mes dossiers en ajoutant des ressources supplémentaires pour layout
, values
etc.
Pour Android 3.2 (niveau d'API 13) activé, ajoutez un sw600dp
dossier. Cela signifie que le s mallest w idth est au moins 600dp, qui est approximativement la fracture téléphone / tablette. Cependant, vous pouvez également ajouter d'autres tailles. Consultez cette réponse pour un exemple de la façon d'ajouter un fichier de ressources de mise en page supplémentaire.
Si vous prenez également en charge les appareils antérieurs à Android 3.2, vous devrez ajouter large
xlarge
dossiers ou pour prendre en charge les tablettes. (Les téléphones sont généralement small
et normal
.)
Voici une image de ce que vos ressources pourraient aimer après l'ajout de fichiers xml supplémentaires pour différentes tailles d'écran.
Lorsque vous utilisez cette méthode, le système détermine tout pour vous. Vous n'avez pas à vous soucier du périphérique utilisé au moment de l'exécution. Vous fournissez simplement les ressources appropriées et laissez Android faire tout le travail.
Remarques
Si vous ciblez uniquement le niveau d'API> = 13, essayez
public static boolean isTablet(Context context) {
return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
à votre santé :-)
En pensant aux "nouveaux" répertoires acceptés (values-sw600dp par exemple), j'ai créé cette méthode basée sur la largeur de l'écran DP:
public static final int TABLET_MIN_DP_WEIGHT = 450;
protected static boolean isSmartphoneOrTablet(Activity act){
DisplayMetrics metrics = new DisplayMetrics();
act.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int dpi = 0;
if (metrics.widthPixels < metrics.heightPixels){
dpi = (int) (metrics.widthPixels / metrics.density);
}
else{
dpi = (int) (metrics.heightPixels / metrics.density);
}
if (dpi < TABLET_MIN_DP_WEIGHT) return true;
else return false;
}
Et sur cette liste, vous pouvez trouver certains des DP des appareils et des tailles de tablettes populaires:
Wdp / Hdp
GALAXY Nexus: 360/567
XOOM: 1280/752
GALAXY NOTE: 400/615
NEXUS 7: 961/528
GALAXY TAB (> 7 && <10): 1280/752
GALAXY S3: 360/615
Wdp = Largeur dp
Hdp = Hauteur dp
Eh bien, la meilleure solution qui a fonctionné pour moi est assez simple:
private boolean isTabletDevice(Resources resources) {
int screenLayout = resources.getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
boolean isScreenLarge = (screenLayout == Configuration.SCREENLAYOUT_SIZE_LARGE);
boolean isScreenXlarge = (screenLayout == Configuration.SCREENLAYOUT_SIZE_XLARGE);
return (isScreenLarge || isScreenXlarge);
}
Utilisé comme ceci:
public void onCreate(Bundle savedInstanceState) {
[...]
if (this.isTabletDevice(this.getResources()) == true) {
[...]
}
}
Je ne veux vraiment pas regarder les tailles de pixels, mais je ne compte que sur la taille de l'écran.
Fonctionne bien car le Nexus 7 (LARGE) est détecté comme une tablette, mais pas le Galaxy S3 (NORMAL).
Utilisez cette méthode qui renvoie true lorsque l'appareil est une tablette
public boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
Si la détection de la taille de l'écran ne renvoie pas la valeur correcte sur les appareils plus récents, essayez:
/*
Returns '1' if device is a tablet
or '0' if device is not a tablet.
Returns '-1' if an error occured.
May require READ_EXTERNAL_STORAGE
permission.
*/
public static int isTablet()
{
try
{
InputStream ism = Runtime.getRuntime().exec("getprop ro.build.characteristics").getInputStream();
byte[] bts = new byte[1024];
ism.read(bts);
ism.close();
boolean isTablet = new String(bts).toLowerCase().contains("tablet");
return isTablet ? 1 : 0;
}
catch (Throwable t)
{t.printStackTrace(); return -1;}
}
Testé sur Android 4.2.2 (désolé pour mon anglais.)
Je sais que ce n'est pas directement une réponse à votre question, mais d'autres réponses ici donnent une bonne idée de la façon d'identifier la taille de l'écran. Vous avez écrit dans votre question que vous aviez des problèmes d'inclinaison et que cela m'est arrivé aussi.
Si vous exécutez le gyroscope (ou le capteur de rotation) sur un smartphone, les axes x et y peuvent être définis différemment que sur une tablette, selon l'orientation par défaut de cet appareil (par exemple, Samsung GS2 est le portrait par défaut, Samsung GT-7310 est paysage par défaut, le nouveau Google Nexus 7 est le portrait par défaut, bien qu'il s'agisse d'une tablette!).
Maintenant, si vous souhaitez utiliser Gyroscope, vous pourriez vous retrouver avec une solution fonctionnelle pour les smartphones, mais la confusion des axes sur certaines tablettes ou l'inverse.
Si vous utilisez l'une des solutions ci-dessus pour choisir uniquement la taille de l'écran, puis appliquez
SensorManager.remapCoordinateSystem(inputRotationMatrix, SensorManager.AXIS_X,
SensorManager.AXIS_Y, outputRotationMatrix);
pour retourner l'axe s'il a une taille d'écran grande ou très grande, cela peut fonctionner dans 90% des cas, mais par exemple sur le Nexus 7, cela causera des problèmes (car il a une orientation portrait par défaut et une grande taille d'écran).
Le moyen le plus simple de résoudre ce problème est fourni dans le RotationVectorSample fourni avec les démos de l'API en définissant sceenOrientation sur nosensor
dans votre manifeste:
<activity
...
android:screenOrientation="nosensor">
...
</activity>
La méthode ci-dessous calcule la longueur diagonale de l'écran de l'appareil pour décider que l'appareil est un téléphone ou une tablette. le seul souci de cette méthode est de savoir quelle est la valeur seuil pour décider si l'appareil est une tablette ou non. dans l'exemple ci-dessous, je l'ai défini sur 7 pouces et plus.
public static boolean isTablet(Activity act)
{
Display display = act.getWindow().getWindowManager().getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
display.getMetrics(displayMetrics);
float width = displayMetrics.widthPixels / displayMetrics.xdpi;
float height = displayMetrics.heightPixels / displayMetrics.ydpi;
double screenDiagonal = Math.sqrt( width * width + height * height );
int inch = (int) (screenDiagonal + 0.5);
Toast.makeText(act, "inch : "+ inch, Toast.LENGTH_LONG).show();
return (inch >= 7 );
}
public boolean isTablet() {
int screenLayout = getResources().getConfiguration().screenLayout;
return (Build.VERSION.SDK_INT >= 11 &&
(((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) ||
((screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE)));
}
Il est de plus en plus difficile de faire la distinction entre le téléphone et la tablette. Par exemple (en août 2015), l'appareil Samsung Mega 6.3 extrait les ressources des dossiers sw600dp - donc en ce qui concerne Android, il s'agit d'une tablette.
La réponse de @Vyshnavi fonctionne dans tous les appareils que nous avons testés mais pas pour Mega 6.3.
La réponse @Helton Isac ci-dessus renvoie le Mega 6.3 en tant que téléphone - mais comme l'appareil saisit toujours des ressources de sw600dp, il peut causer d'autres problèmes - par exemple, si vous utilisez un viewpager pour les téléphones et non pour les tablettes, vous vous retrouverez avec des erreurs NPE .
En fin de compte, il semble juste qu'il y ait trop de conditions à vérifier et nous devrons peut-être accepter que certains téléphones soient en fait des tablettes :-P
C'est la méthode que j'utilise:
public static boolean isTablet(Context ctx){
return = (ctx.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
En utilisant:
Configuration. SCREENLAYOUT_SIZE_MASK
Configuration. SCREENLAYOUT_SIZE_LARGE
C'est la méthode recommandée!
pourquoi utiliser ça?
Use this method which returns true when the device is a tablet
public boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
Je vois de nombreuses façons ci-dessus.
/**
* Check if the Configuration's current {@link #screenLayout} is at
* least the given size.
*
* @param size The desired size, either {@link #SCREENLAYOUT_SIZE_SMALL},
* {@link #SCREENLAYOUT_SIZE_NORMAL}, {@link #SCREENLAYOUT_SIZE_LARGE}, or
* {@link #SCREENLAYOUT_SIZE_XLARGE}.
* @return Returns true if the current screen layout size is at least
* the given size.
*/
public boolean isLayoutSizeAtLeast(int size) {
int cur = screenLayout&SCREENLAYOUT_SIZE_MASK;
if (cur == SCREENLAYOUT_SIZE_UNDEFINED) return false;
return cur >= size;
}
il suffit d'appeler :
getResources().getConfiguration().
isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);
c'est bon?
J'avais besoin de détecter le smartphone / la tablette uniquement dans le fichier de mise en page, car j'utilise le code de navigation.
J'ai d'abord créé un répertoire layout-sw600dp mais cela ne fonctionnait pas bien car il s'activerait sur mon Nokia 8 en mode paysage, mais la hauteur de l'écran serait trop petite.
J'ai donc renommé le répertoire en layout-sw600dp-h400dp et j'ai obtenu l'effet souhaité. Le paramètre h-xxxdp doit dépendre de la quantité de contenu que vous souhaitez déposer sur votre mise en page et, en tant que tel, doit dépendre de l'application.
Veuillez vérifier le code ci-dessous.
private boolean isTabletDevice() {
if (android.os.Build.VERSION.SDK_INT >= 11) { // honeycomb
// test screen size, use reflection because isLayoutSizeAtLeast is
// only available since 11
Configuration con = getResources().getConfiguration();
try {
Method mIsLayoutSizeAtLeast = con.getClass().getMethod(
"isLayoutSizeAtLeast", int.class);
boolean r = (Boolean) mIsLayoutSizeAtLeast.invoke(con,
0x00000004); // Configuration.SCREENLAYOUT_SIZE_XLARGE
return r;
} catch (Exception x) {
x.printStackTrace();
return false;
}
}
return false;
}
Je pense qu'une tablette a une largeur et une hauteur minimale et maximale de 600 px,
il faut donc connaître la densité de l'écran et la hauteur / largeur en dp,
pour récupérer la valeur:
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
float density = metrics.density;
if((width/density>=600 && height/density>=600))
isTablette = true;
else
isTablette = false;
Par exemple, avoir une différence importante (au moins pour mon programme) entre le téléphone et la tablette. Il s'agit de l'orientation par défaut de l'appareil. Le téléphone a une orientation portrait, la tablette - paysage. Et respectivement méthode pour déterminer l'appareil:
private static boolean isLandscapeDefault(Display display) {
Log.d(TAG, "isTablet()");
final int width = display.getWidth();
final int height = display.getHeight();
switch (display.getOrientation()) {
case 0: case 2:
if(width > height) return true;
break;
case 1: case 3:
if(width < height) return true;
break;
}
return false;
}
EDITED: Suite aux discussions avec Dan Hulme a changé le nom de la méthode.
Je recommande la bibliothèque Android «caféine» qui contient un téléphone ou une tablette, et 10 pouces ~!
utilisation très simple.
la bibliothèque est ici.
https://github.com/ShakeJ/Android-Caffeine-library
et utilise
DisplayUtil.isTablet(this);
DisplayUtil.isTenInch(this);
Pour moi, la distinction entre téléphone et tablette n'est pas la taille de l'appareil et / ou la densité de pixels, qui changera avec la technologie et le goût, mais plutôt le rapport d'écran. Si j'affiche un écran de texte, j'ai besoin de savoir si, disons, 15 longues lignes sont nécessaires (téléphone) contre 20 lignes plus courtes (tablette). Pour mon jeu, j'utilise ce qui suit pour une estimation approximative du rectangle que mon logiciel traitera:
Rect surfaceRect = getHolder().getSurfaceFrame();
screenWidth = surfaceRect.width();
screenHeight = surfaceRect.height();
screenWidthF = (float) screenWidth;
screenHeightF = (float) screenHeight;
widthheightratio = screenWidthF/screenHeightF;
if(widthheightratio>=1.5) {
isTablet=false;
}else {
isTablet=true;
}