I am wondering how Android draws views on the screen inside layouts with specific android:layout_width and android:layout_height in pixels.
I am using the Android class view extends android.view.SurfaceView . Just MjpegView display MJPEG stream from camera in Android app. I work with this code (with minor changes): Android ICS and MJPEG using AsyncTask
This MjpegView class is placed inside a RelativeLayout . MjpegView object is added programmatically, and this RelativeLayout has attributes defined this way:
android:layout_width="800px" android:layout_height="600px"
Values โโof this size are required for this application, so I cannot change them. The application works only in landscape orientation. My MjpegView should be set to 320 x 240 pixel size inside RelativeLayout (800 x 600 px) . My application enlarges this RealtiveLayout to fill the screen on the current device. And this is also a problem with streaming MJPEG. I am working on a Nexus 7 (2012 version) that has a resolution of 1280 x 800 .
To get the actual size of this view inside the layout, I have to measure the height of the Nexus 7 screen without actions and navigation bars. To get this, I used this method inside one Activity :
@Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); RelativeLayout parentLayout = (RelativeLayout) findViewById(R.id.parent_layout); if (parentLayout != null && isLandscape) { this.measuredActivityHeight = parentLayout.getBottom(); } }
I get the value 703 as measuredActivityHeight current activity. So, to get the ratio in which Android translates 320 x 240 px inside 800 x 600 px to the dp value on the screen, I wrote this method:
public int calculateForCurrentScreen(float pixelValue) { float ratio = PageActivity.measuredActivityHeight / 600f; int result = (int) (pixelValue * ratio); return result; }
So, for 320 x 240 px on Nexus 7 I get 374 x 281 . And to get MjpegView in this size, I need to use this method inside the MjpegView class:
public void setResolution(int width, int height) { holder.setFixedSize(width, height); }
And the size of the streaming view is in the desired size. But this look has additional black areas. Thus, in fact, the whole view (camera stream + black areas on the lower and right sides) has a size of 440 x 328 .
I checked that the Rect object in MjpegView draws with a size of 374 x 281 , so this is normal. SurfaceHolder and Canvas also have this size. Bitmap object has a size of 320 x 240 , but this is normal because the Bitmap object is from the camera stream. And it changes to the desired size.
The problem disappears (there are no black areas, and MjpegView is in the correct position and size relative to other views) when I switched the RelativeLayout to 800dp x 600dp and setResolution(320, 240) MjpegView for the MjpegView object, but the whole layout is too big at that moment.
EDIT
Thanks @mathiash for your comment. I just downloaded a screenshot from Nexus 7 (2012 edition) to show you my problem.
As you can see, the green area is a RelativeLayout with a specific size of 800 x 600 px . To get the MJPEG stream from http://trackfield.webcam.oregonstate.edu/ . I used this URL: http://trackfield.webcam.oregonstate.edu/axis-cgi/mjpg/video.cgi?resolution=320x240 .
For this screenshot, I called the setResolution(320, 240) method. And the black area has 374 x 281 and a video stream of 320 x 240 .

For this screenshot, I called the setResolution(374, 281) method. And the black area is much larger, and the video stream is 374 x 281 . And in this case, the video stream has the correct size, but this black area is not needed.
