【问题标题】:android get screen size via Candroid通过C获取屏幕大小
【发布时间】:2012-08-26 15:37:56
【问题描述】:

我想通过 c 获得屏幕尺寸。我知道 jni 支持从 c 调用 java。但是有没有人知道另一种方法?我的意思是从低级模块获取屏幕大小而不调用 java。

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

public class MainActivity extends Activity
{

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
    super.onCreate(savedInstanceState);
    Log.v("getWidth", Integer.toString(getWindowManager().getDefaultDisplay().getWidth()));
    Log.v("getHeight", Integer.toString(getWindowManager().getDefaultDisplay().getHeight()));
    }
}

我认为 /dev/graphics 与我的问题有关

【问题讨论】:

    标签: java android android-ndk


    【解决方案1】:

    是的,您可以从 /dev/graphics/fb0 获取屏幕分辨率,但是(至少在我的手机上),读取权限仅限于 root 和“图形”组中的用户。无论如何,您都可以这样做(为了清楚起见,删除了错误检查):

    // ... other standard includes ...
    #include <sys/ioctl.h>
    #include <linux/fb.h>
    
    //...
    
    struct fb_var_screeninfo fb_var;
    int fd = open("/dev/graphics/fb0", O_RDONLY);
    ioctl(fd, FBIOGET_VSCREENINFO, &fb_var);
    close(fd);
    // screen size will be in fb_var.xres and fb_var.yres
    

    我不确定这些是否被视为“公共”NDK 接口,因为我不知道 Google 是否认为“Android 在 Linux 上运行并使用 Linux Framebuffer 接口”是公共 API 的一部分,但它似乎确实有效。

    如果您确实想确保它是可移植的,您可能应该有一个调用 Java WindowManager API 的 JNI 回退。

    【讨论】:

      【解决方案2】:

      您不需要缓冲区,但如果您从 java 中传入 Surface,您可以使用 ANativeWindow 类。

      void Java_com_justinbuser_nativecore_NativeMethods_setSurface(JNIEnv * env, jobject this, jobject surface){
              ANativeWindow nativeWindow = ANativeWindow_fromSurface(env, surface);
          int width =  ANativeWindow_getWidth(renderEngine->nativeWindow);
          int height = ANativeWindow_getHeight(renderEngine->nativeWindow);
      }
      

      【讨论】:

      • 问题是关于获取屏幕尺寸。
      • ANativeWindow_getHeight 不可靠地减去导航栏。
      【解决方案3】:

      您还可以在原生活动中像这样处理APP_CMD_INIT_WINDOW“app 命令”时获取窗口大小:

      static void engine_handle_cmd(struct android_app* app, int32_t cmd) {
      struct engine* engine = (struct engine*)app->userData;
      switch (cmd) {
      case APP_CMD_INIT_WINDOW:
          if (engine->app->window != NULL) {
              int width = ANativeWindow_getWidth(engine->app->window);
              int height = ANativeWindow_getHeight(engine->app->window);
          }
      

      如果您想了解如何设置engine 结构和engine_handle_cmd 回调,请查看native-activity 示例NDK 项目中的main.c

      【讨论】:

      • 问题是关于获取屏幕尺寸。
      【解决方案4】:

      对于像我这样正在寻找纯 C++ 方法的人来说,阅读 /dev/graphics/fb0 并不可靠。在许多设备上,它返回一个不正确的结果(在我的设备上它返回 640 X 400)。

      对于无法使用ANativeWindowANativeWindow_Buffer 的情况(例如在本机二进制可执行文件中),这是一个问题。

      什么对我有用:

      假设您有一部已root的手机,您可以处理以下命令的输出以可靠地读取分辨率。

      su -c dumpsys display | grep mBaseDisplayInfo
      

      【讨论】:

        【解决方案5】:

        要获得屏幕分辨率,您必须使用 struct ANativeWindow_Buffer:

        typedef struct ANativeWindow_Buffer {
            // The number of pixels that are show horizontally.
            int32_t width;
        
            // The number of pixels that are shown vertically.
            int32_t height;
        
            // The number of *pixels* that a line in the buffer takes in
            // memory.  This may be >= width.
            int32_t stride;
        
            // The format of the buffer.  One of WINDOW_FORMAT_*
            int32_t format;
        
            // The actual bits.
            void* bits;
        
            // Do not touch.
            uint32_t reserved[6];
        } ANativeWindow_Buffer;
        

        使用函数ANativeWindow_lock

        /**
         * Lock the window's next drawing surface for writing.
         */
        int32_t ANativeWindow_lock(ANativeWindow* window, ANativeWindow_Buffer* outBuffer, ARect* inOutDirtyBounds);
        

        这里是docs

        如果您正在寻找此功能的用法,请查看名为 native-plasma 的 android-ndk 示例。

        【讨论】:

        • 问题是关于获取屏幕尺寸。
        • 嘿@user7860670,感谢您的回复。我使用上面的代码来获取屏幕大小。洗手,阿尔乔姆。
        【解决方案6】:

        这对我有用:

        DisplayMetrics displaymetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
        int height = displaymetrics.heightPixels;
        int width = displaymetrics.widthPixels;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-02-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多