Android native question - Button positing with device scaling

Using

mPreview.setZOrderMediaOverlay(true);

right after adding the mPreview to the getOverlayView() solved. Thanks Joshua. Now I just need to check if that will make it to stay on top of everything or not (I want to add some images over the camera view).

PS: I was adding my view to getParent() because that is how it is instructed in the ads-provider sample project ("// TODO: Insert call to display new ad. You should add it as a child of ‘getParent()’."). Maybe you would want to update that info there.

Great!  I’m glad you’ve got it working.  You might also want to double check that your camera preview is still being displayed correctly when suspending/resuming your app via the Home key and via the Power button.  That’s when those threaded SurfaceViews tend to render in the wrong z-order on you.  But hopefully that setZOrderMediaOverlay() method takes care of it in those cases too.

 

Hi Josua. Sorry to bother you again. I searched a lot and didn’t find information about a very simple thing.

How can I get access to a Android View (that to the getOverlayView()) on my Corona code? (like to change its position)

On Android, you set the position of your view via LayoutParams that you pass into the container.  How you position it depends on the layout container.  Corona’s overlay view is a FrameLayout which allows you to “stack” views on top of each other so that one view does not affect the position of another view.  The idea here is to allow a Corona plugin to display a native Android view without affecting the position of other views created by other plugins.

In your case, I suppose you want to set your view to a specific (x,y) pixel position, right?  So, in my opinion, the best solution is to create your own AbsoluteLayout to be a container for your camera preview, and you would add your AbsoluteLayout to Corona’s overlay view fullscreen.  You would then use the AbsoluteLayout.LayoutParams inner class to position your camera preview.  You would set these params when you call addView() in the container… and when moving your camera preview, you would call the view’s setLayoutParams() method with a new instance of AbsoluteLayout.LayoutParams set to a new x/y width/height.

Thanks for the info Joshua.

Actually, my case is: I want to have a corona display object (image) in front of the camera preview that I added natively and then take a snapshot of it.

I spent the whole weekend going thru the insides of the Corona library and my conclusion is that this is not possible (or am I wrong?).

For what I understood (and for future users reference), Corona Enterprises creates the following view structure for an Android app

1. myContentView 1.1 glView (surfaceview that has all the corona objects) 1.2 mOverlayView 1.3 myAbsolutePopupLayout

So, it is impossible to have an object that is inside the glView (which would be my image) to be in front of the mOverlayView (which holds the camera preview).

I tried to move the whole glView to be in front of the mOverlayView (making the glView to have transparent background), but it didn’t work.

So, for what I see, it is impossible to create a plugin using Corona Enterprise that shows the camera inside of a Corona app in way that you can control the camera object as it were a display object (which is what we can do today using the shape camera fill on iOS), am I right?

What you’re trying to do isn’t going to work.  Corona’s display objects are rendered in OpenGL in the GLSurfaceView *behind* your Camera preview view.  If you want to display an image on top, then you’ll have to use an Android’s “ImageView” class instead.  You can’t render it in OpenGL.

Yeah, I noticed that. Very frustrating…

So, if you would implement a iOS camera fill type for Android, what would you do? You would have to do it using NDK?

Corona does not give you the ability render your own custom content in OpenGL via native APIs.  And we’re not planning on adding a camera fill on Android in the near future.  So, you’re only option is to change your design and display native Android views on top of the camera preview.

I know that you guys are not planing to camera fill for Android, that why I am trying to create some work around for it.

Thanks for all the explanations Joshua.

Using an Android ImageView is relatively straight forward.  If you want to use your Corona projects existing image files in the Android project’s Assets directory, then you can easily load it via our FileServices class.  If you call that class’ openFile() method with a relative path, then it’ll default to the Assets directory… or a Google Expansion file if applicable.

   http://docs.coronalabs.com/native/android/html/com/ansca/corona/storage/FileServices.html

Once you’ve opened the file, you would then pass the returned stream to Android’s BitmapFactory.decodeStream() method to decode the image to a raw bitmap.

   http://developer.android.com/reference/android/graphics/BitmapFactory.html#decodeStream(java.io.InputStream

The above will return a Java bitmap object (if successfully decoded) which you can pass into an ImageView class’ setImageBitmap() method.

   http://developer.android.com/reference/android/widget/ImageView.html#setImageBitmap(android.graphics.Bitmap

I was exactly thinking on how to load a file from the Corona Project… the FileServices will be of utmost help.

I was kind of frustrated because I would not have access to my camera view from Corona, but now it is clear to me that any info that I need (like position, contentBounds, …) I just need to expose them to Corona using my “plugin” functions. So I will be fine.

I will go with your solution. Thanks again.

PS: I mentioned before that you may want to update the ads-provider sample project to use getOverlayView() instead of getParent() (as you suggested), but actually I noticed yesterday that the getParent() is a private function that uses getOverlayView(). So the sample is correct. :slight_smile:

I’m moving this to the Enterprise forum.

Rob

So, after looking a lot I came to the conclusion that there is not simple way of having a Corona-style content scaling.

I found a good paper that talks about the different approaches that can be used. The paper is available at: http://www.vanteon.com/downloads/Scaling_Android_Apps_White_Paper.pdf

There isn’t a simple means of doing this on Android.  Google expects you to position your views using layouts such as the RelativeLayout, FrameLayout, LinearLayout, etc. which positions your views relative to other views in the activity… which also means that they’ll be positioned in various positions on devices having different resolutions.

If you’re trying to set your button’s position to a very particular pixel position, relative to what appears in Corona, then your only option is to use Android’s AbsoluteLayout.  That layout allows you to set the (x,y) pixel position of your view onscreen.  I haven’t done this in XML before, but I do know how to do this in Java.  What you need to do is create your own AbsoluteLayout object that will serve as the container for your button and add that layout to the layout returned by CoronaActivity.getOverlayView().  You would then add your button to your layout via AbsoluteLayout .addView(yourButton, parameters) where “parameters” is an instance of the “AbsoluteLayout.LayoutParams” inner class which allows you to set the x/y position in pixels.  You can fetch the pixel width and height of Corona’s OpenGL view via the CoronaActivity.getContentWidthInPixels() and CoronaActivity.getContentHeightInPixels() methods, which should help you position your views relative to what is rendered in Corona.

Here are some links to help you out…

http://docs.coronalabs.com/native/android/html/com/ansca/corona/CoronaActivity.html#getOverlayView()

http://docs.coronalabs.com/native/android/html/com/ansca/corona/CoronaActivity.html#getContentHeightInPixels()

http://developer.android.com/reference/android/widget/AbsoluteLayout.html

http://developer.android.com/reference/android/widget/AbsoluteLayout.LayoutParams.html

Also check out our “ExtendingUI” sample app that is included with Corona Enterprise.  It shows you how to add Android views on top of the CoronaActivity.  It doesn’t do the same thing that you’re after, but there are other bits of gold in its Java code that might help you out.

Hi Joshua.

Thanks for the reply.

Yes, you are right. To make something similar to Corona I would have to use the Absolute Layout and them set my objects position via code (For others wanting to know how to do it, please check the paper that I linked in the post above). The only downside on that approach is that I think the xml layout preview will not reflect these dynamic positions (I think, I didn’t test it).

In my case, since the button was transparent, I replaced the button with a LinearLayout (which resizes automatically with the device screen) and it worked.

Thanks!

Does it have to be a button in the middle of the screen?

Our “ExendingUI” sample project shows you how to display a button bar docked at the top and bottom of the activity using Android’s UI classes.  We just add them to Corona’s FrameLayout and dock them by setting the gravity to top or bottom.  Just trying to find you a simpler alternative.

Thanks for you help Josua. I really appreciate it.

The whole problem is that you guys from Corona made me spoiled with all the easiness of the platform. Now when I go to native, it is all unproductive :slight_smile:

No, the buttons don’t need to be in the center. I actually was creating a mockup, and used the layout image as the background and want to create an transparent button at the same position where it is displayed in the background image.  

But, Android scales the background but not the position of the objects, so my transparent button ended misplaced when different devices.

For the mockup purposes I solved using LinearLayouts. For the final approach, I was actually thinking in using Corona Cards, going Android native only when I needed to access the resource that Corona does not provide (front/back camera inside the app).

On Android, Corona Cards/Enterprise actually has an undocumented “CameraView” Java class that supports both the front/rear camera.  We use it as a fallback mechanism in case we can’t find a Camera app on the device (should never happen; keyword is “should”) or if your app does not have the required Android permissions.  This CameraView can easily be embedded within an Activity.  You’re welcome to use it on Android, with the one disclaimer being that since it is undocumented we reserve the right to change it in the future.

Wow, simply amazing. Definitively going to use it.

No problem in being undocumented, the app is a promotional marketing tool for a client and will only be live for 1 month.

Oh and one bit of warning, our “CameraView” on Android is a native UI Java control and is not rendered in OpenGL… but the advantage of that is it’ll work on Android 2.x, because only Android 4.0 and higher supports rendering camera out to OpenGL.

If you want to see it in action in a Corona Simulator app, then build our Camera sample app without the CAMERA permission.  It should switch to our Corona made CameraActivity and CameraView… with the one issue being is that the CameraActivity stretches the camera output to fill the screen, but that’s just an issue with the activity.  In native code, you would set the width and height of the CameraView to match the aspect ratio of the camera’s resolution.