Existe uma maneira de verificar se o usuário está usando um tablet ou telefone? Estou com problemas na função de inclinação e no meu novo tablet (Transformer)
Existe uma maneira de verificar se o usuário está usando um tablet ou telefone? Estou com problemas na função de inclinação e no meu novo tablet (Transformer)
Respostas:
Como foi mencionado anteriormente, você não deseja verificar se o dispositivo é um tablet ou telefone, mas deseja conhecer os recursos do dispositivo,
Na maioria das vezes, a diferença entre um tablet e um telefone é o tamanho da tela e é por isso que você deseja usar arquivos de layout diferentes. Esses arquivos são armazenados nos res/layout-<qualifiers>
diretórios. Você pode criar um arquivo XML no diretório res/values-<same qualifiers>
para cada um dos seus layouts e colocar nele um recurso int / bool / string para distinguir entre os layouts que você usa.
Arquivo res/values/screen.xml
(supondo que res/layout/
contenha seus arquivos de layout para aparelhos)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">phone</string>
</resources>
Arquivo res/values-sw600dp/screen.xml
(supondo que res/layout-sw600dp/
contenha seus arquivos de layout para tablets pequenos como o Nexus 7)
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">7-inch-tablet</string>
</resources>
Arquivo res/values-sw720dp/screen.xml
(supondo que res/layout-sw720dp/
contenha seus arquivos de layout para tablets grandes como o Nexus 10):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="screen_type">10-inch-tablet</string>
</resources>
Agora o tipo de tela está acessível através da R.string.screen_type
constante.
Para detectar se o dispositivo é ou não um tablet, use o seguinte código:
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);
}
Os tamanhos de tela LARGE e XLARGE são determinados pelo fabricante com base na distância do olho em que devem ser utilizados (daí a idéia de um tablet).
Mais informações: http://groups.google.com/group/android-developers/browse_thread/thread/d6323d81f226f93f
Configuration.SCREENLAYOUT_SIZE_XLARGE
, então você não precisa usar uma constante e pode usar >= LARGE
.
Este post me ajudou muito,
Infelizmente, não tenho a reputação necessária para avaliar todas as respostas que me ajudaram.
Eu precisava identificar se meu dispositivo era um tablet ou telefone, com isso eu seria capaz de implementar a lógica da tela. E, na minha análise, o tablet deve ter mais de 7 polegadas (Xlarge) começando no MDPI.
Aqui está o código abaixo, criado com base nesta postagem.
/**
* 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;
}
Por que não calcular o tamanho da diagonal da tela e usá-lo para decidir se o dispositivo é um telefone ou tablet?
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 );
}
É claro que se pode argumentar se o limiar deve ser de 9 polegadas ou menos.
não há diferença. Você deve definir o que acha que é a diferença e verificar isso. A guia galáxia é um telefone? ou um tablet? e porque?
Você deve definir quais recursos específicos procura e codificar para isso.
Parece que você está procurando por 'inclinação'. Eu acho que é o mesmo que o acelerômetro (isso é uma palavra?). Você pode apenas verificar se o dispositivo suporta, usando:
public class Accel extends Activity implements SensorListener {
...
SensorManager sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
boolean accelSupported = sensorMgr.registerListener(this,
SENSOR_ACCELEROMETER,
SENSOR_DELAY_UI);
...
}
(em http://stuffthathappens.com/blog/2009/03/15/android-accelerometer/ . não testei)
Minha suposição é que, quando você define 'Celular / Telefone', deseja saber se pode fazer uma ligação telefônica no dispositivo que não pode ser feita em algo que seria definido como 'Tablet'. A maneira de verificar isso está abaixo. Se você deseja saber algo baseado em sensores, tamanho da tela, etc., essa é realmente uma pergunta diferente.
Além disso, enquanto o uso da resolução da tela, ou o gerenciamento de recursos grande ou grande, pode ter sido uma abordagem válida no passado, novos dispositivos 'móveis' agora vêm com telas grandes e altas resoluções que estão desfocando essa linha e, se você realmente deseja Para conhecer a ligação telefônica ou a capacidade de não ligar, a seguir é 'melhor'.
TelephonyManager manager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
if(manager.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE){
return "Tablet";
}else{
return "Mobile";
}
Baseado em Robert Dale Johnson III e Helton Isac, eu vim com esse código Espero que seja útil
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;
}
Então, no seu código, faça um filtro como
if(isTabletDevice(Utilities.this) && isTablet(Utilities.this)){
//Tablet
} else {
//Phone
}
No código-fonte do aplicativo Google IOSched 2017 , o seguinte método é usado:
public static boolean isTablet(Context context) {
return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
Para aqueles que desejam consultar o código do Google para decidir quais dispositivos usarão uma interface do usuário do Tablet, consulte abaixo:
// 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
?
Este método é uma recomendação do Google. Vejo esse código no aplicativo oficial do Google para Androidiosched
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; }
As outras respostas listam várias maneiras de determinar programaticamente se o dispositivo é um telefone ou tablet. No entanto, se você ler a documentação , essa não é a maneira recomendada de oferecer suporte a vários tamanhos de tela.
Em vez disso, declare recursos diferentes para tablets ou telefones. Você fazer isso do meu adicionando pastas de recursos adicionais para layout
, values
, etc.
Para o Android 3.2 (nível 13 da API), adicione uma sw600dp
pasta. Isto significa que o de s mallest w IDþ é pelo menos 600dp, que é aproximadamente a divisão celular / comprimido. No entanto, você também pode adicionar outros tamanhos. Confira esta resposta para um exemplo de como adicionar um arquivo de recurso de layout adicional.
Se você também suporta dispositivos anteriores ao Android 3.2, precisará adicionar large
ou xlarge
pastas para dar suporte aos tablets. (Os telefones são geralmente small
e normal
.)
Aqui está uma imagem de como seus recursos podem ser depois de adicionar arquivos xml extras para diferentes tamanhos de tela.
Ao usar esse método, o sistema determina tudo para você. Você não precisa se preocupar com o dispositivo que está sendo usado em tempo de execução. Você apenas fornece os recursos apropriados e deixa o Android fazer todo o trabalho.
Notas
Se você está segmentando apenas o nível da API> = 13, tente
public static boolean isTablet(Context context) {
return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
}
Felicidades :-)
Pensando nos diretórios "novos" aceitos (valores-sw600dp, por exemplo), criei esse método com base na largura da tela 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;
}
E nesta lista, você pode encontrar alguns dos DP de dispositivos populares e tamanhos de tablet:
Wdp / Hdp
GALAXY Nexus: 360/567
XOOM: 1280/752
GALAXY NOTA: 400/615
NEXUS 7: 961/528
GALAXY TAB (> 7 && <10): 1280/752
GALAXY S3: 360/615
Wdp = Largura dp
Hdp = Altura dp
Bem, a melhor solução que funcionou para mim é bastante simples:
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);
}
Usado assim:
public void onCreate(Bundle savedInstanceState) {
[...]
if (this.isTabletDevice(this.getResources()) == true) {
[...]
}
}
Eu realmente não quero olhar para o tamanho dos pixels, mas apenas confiar no tamanho da tela.
Funciona bem, pois o Nexus 7 (GRANDE) é detectado como um tablet, mas não o Galaxy S3 (NORMAL).
Use este método que retorna verdadeiro quando o dispositivo é um tablet
public boolean isTablet(Context context) {
return (context.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
Se a detecção do tamanho da tela não retornar o valor correto em dispositivos mais recentes, tente:
/*
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;}
}
Testado no Android 4.2.2 (desculpe pelo meu inglês.)
Sei que essa não é uma resposta direta à sua pergunta, mas outras respostas aqui dão uma boa idéia de como identificar o tamanho da tela. Você escreveu na sua pergunta que tinha problemas com a inclinação e isso também aconteceu comigo.
Se você executar o giroscópio (ou sensor de rotação) em um smartphone, os eixos xe y poderão ser definidos diferentemente do que em um tablet, de acordo com a orientação padrão desse dispositivo (por exemplo, Samsung GS2 é o retrato padrão, Samsung GT-7310 é cenário padrão, o novo Google Nexus 7 é o retrato padrão, embora seja um tablet!).
Agora, se você quiser usar o giroscópio, poderá acabar com uma solução funcional para smartphones, mas com confusão de eixos em alguns tablets ou o contrário.
Se você usar uma das soluções acima para escolher apenas o tamanho da tela e aplicar
SensorManager.remapCoordinateSystem(inputRotationMatrix, SensorManager.AXIS_X,
SensorManager.AXIS_Y, outputRotationMatrix);
girar o eixo se tiver um tamanho de tela grande ou grande, isso pode funcionar em 90% dos casos, mas, por exemplo, no Nexus 7, ele causará problemas (porque possui orientação retrato padrão e um tamanho de tela grande).
A maneira mais simples de corrigir isso é fornecida no RotationVectorSample que acompanha as demos da API, definindo sceenOrientation como nosensor
no seu manifesto:
<activity
...
android:screenOrientation="nosensor">
...
</activity>
O método abaixo é calcular o comprimento diagonal da tela do dispositivo para decidir se é um telefone ou tablet. a única preocupação desse método é qual é o valor limite para decidir se o dispositivo é tablet ou não. no exemplo abaixo, defino-o como 7 polegadas e acima.
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)));
}
Está ficando cada vez mais difícil traçar a linha entre telefone e tablet. Por exemplo (em agosto de 2015), o Samsung Mega 6.3 dispositivo extrai recursos das pastas sw600dp - no que diz respeito ao Android, é um tablet.
A resposta do @Vyshnavi funciona em todos os dispositivos que testamos, mas não no Mega 6.3.
A resposta acima @ Helton Isac retorna o Mega 6.3 como telefone - mas como o dispositivo ainda captura recursos do sw600dp, pode causar outros problemas - por exemplo, se você usar um visor para telefones e não para tablets, acabará com erros de NPE .
No final, parece que há muitas condições a serem verificadas e talvez tenhamos que aceitar que alguns telefones são realmente tablets :-P
Este é o método que eu uso:
public static boolean isTablet(Context ctx){
return = (ctx.getResources().getConfiguration().screenLayout
& Configuration.SCREENLAYOUT_SIZE_MASK)
>= Configuration.SCREENLAYOUT_SIZE_LARGE;
}
Usando:
Configuração. SCREENLAYOUT_SIZE_MASK
Configuração. SCREENLAYOUT_SIZE_LARGE
Este e o metodo recomendado!
por que usar isso?
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;
}
Eu vejo muitas maneiras acima. a classe de configuração tem a resposta certa logo abaixo:
/**
* 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;
}
apenas ligue :
getResources().getConfiguration().
isLayoutSizeAtLeast(Configuration.SCREENLAYOUT_SIZE_LARGE);
está certo?
Eu precisava detectar o smartphone / tablet apenas no arquivo de layout, porque estou usando o código de navegação.
O que fiz primeiro foi criar um diretório layout-sw600dp, mas não estava funcionando bem porque seria ativado no meu Nokia 8 no modo paisagem, mas a altura da tela seria muito pequena.
Renomeei o diretório como layout-sw600dp-h400dp e obtive o efeito desejado. O parâmetro h-xxxdp deve depender da quantidade de conteúdo que você deseja soltar no layout e, como tal, deve depender do aplicativo.
Verifique o código abaixo.
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;
}
Acho que um tablet tem largura e altura mín. E máx. De 600 px,
portanto , é necessário conhecer a densidade da tela e a altura / largura em dp
para recuperar o valor:
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;
Por exemplo, tenha uma diferença importante (pelo menos para o meu programa) entre o telefone e o tablet. É a orientação padrão do dispositivo. Telefone tem uma orientação retrato, o tablet - paisagem. E método respectivamente para determinar o dispositivo:
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;
}
EDITADO: Após as discussões com Dan Hulme, mudou o nome do método.
Eu recomendo a biblioteca android 'cafeína' que contém telefone ou tablet e 10 polegadas ~!
uso muito fácil.
a biblioteca está aqui.
https://github.com/ShakeJ/Android-Caffeine-library
E use
DisplayUtil.isTablet(this);
DisplayUtil.isTenInch(this);
Para mim, a distinção entre telefone e tablet não é o tamanho do dispositivo e / ou a densidade de pixels, que mudará com a tecnologia e o gosto, mas a proporção da tela. Se estou exibindo uma tela de texto, preciso saber se, digamos, são necessárias 15 linhas longas (telefone) versus 20 linhas mais curtas (tablet). Para o meu jogo, uso o seguinte para uma estimativa aproximada do retângulo com o qual meu software lidará:
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;
}