I'm writing an Android app using Gameplay3D. I can compile fine using NDK and generate APK using ANT (both debug and release). The app installs, starts and runs perfectly on a Galaxy S3 and a Nexus 4, but when I try to start it on a Nexus 7 it just doesn't display anything. Just a black screen with the nav bar at the bottom.
I have two Nexus 7s, each with a different version of Android (one is 4.3, other is 4.4).
I'm not highly experienced with Android development, but here is my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.secretCompany.secretGame"
android:versionCode="15"
android:versionName="1.0.0">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- This is the platform API where the app was introduced. -->
<uses-sdk android:minSdkVersion="10" />
<uses-feature android:glEsVersion="0x00020000"/>
<application android:icon="#drawable/icon" android:label="#string/app_name" android:hasCode="true">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
android:label="#string/app_name"
android:configChanges="orientation|keyboardHidden"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="landscape">
<!-- Tell NativeActivity the name of or .so -->
<meta-data android:name="android.app.lib_name"
android:value="secretGame" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
I've changed the game's name and company as they're currently a secret, but other than that this is exactly how it appears in the file.
Any help would be greatly appreciated :)
Additional Info:
The only thing the app does is render sprites and accept input. No sound, no internet, no nothing else.
Both Nexuses (Nexi? :P) are the 2012 edition, not the new 2013 version.
I use render-to-texture. Could this be a problem? Maybe with non-power-of-2 textures?
I tested and the code is still running, I just can't see anything.
AH finally, I figured it out myself, from this post. The problem was that almost all of my textures were not power-of-2 and the ones that were were off screen at the time.
Silly me.
Edit: Or maybe not... now it won't display ANYTHING, not even the textures that were power-of-2 before... does an OpenGL FBO have to have a square texture to work on power-of-2 devices?
Edit2: Ah, ok I finally found the problem. I was correct initially about the sprites not having power-of-2 textures, but then I re-enabled my render-to-texture and it stopped working. Turns out the problem was that I was rendering to a different FBO and then extracting the texture to turn it into a sprite and render into the primary FBO...and of course the texture wasn't power-of-2. I just created the texture at the lowest PO2 size that the entire screen would still fit into, then modified the UV coords of the fullscreen sprite so the extra texture parts were put offscreen. Problem solved!
Related
I am making an android game, but when I build the apk and run it on my mobile then it shows me the black bars on the side. The game is in landscape mode, and the camera is in a perspective mode in Unity. How do I fix it?
Player Settings -> Android -> Resolution and Presentation
Set Aspect Ratio Mode to Custom
Set Up To value to 2.2 (or even larger).
For legacy versions,
Android >= 8.0, add android:maxAspectRatio to unity activity
<activity
android:maxAspectRatio="2.2"
android:resizeableActivity="true" />
Android < 8.0, add android.max_aspect to application tag
<application>
<meta-data android:name="android.max_aspect" android:value="2.2" />
I’m making a LibGDX (1.9.9) game that is meant to be fixed in landscape mode, but when I run it on certain devices, it shows up in portrait mode.
I’ve tested it on several physical and virtual devices ranging from Android 4 to 11 as well as on an iPhone simulator through RoboVM (2.3.9). This happens on an android virtual tablet (Android 11) and the iPhone simulator. It has gotten stuck in portrait a couple times on a physical device as well, but I have not been able to reproduce it. I haven’t been able to understand why this could be.
I have landscape (android:screenOrientation="landscape”) set in the android manifest.
Gdx.input.getRotation() returns 90 when it is properly set on landscape, but 0, when in portrait so perhaps I can try checking if it is 0 and change the rotation dynamically, but I have not been able to find out how to do that either.
I’ve tried a workaround where I check if screen width < screen height and rotate the camera 90 degrees if that is true to put it into landscape manually, but that causes the camera to become distorted in the manner shown below even though I know I’ve modified the aspect ratio correctly for the rotation.
How camera distorts when trying to rotate to landscape
I am using OrthographicCamera without any Viewports.
// Screen dimensions
width = ((float) Gdx.graphics.getWidth() / (float) Gdx.graphics.getHeight()) * GameSpecs.WORLD_HEIGHT;
height = GameSpecs.WORLD_HEIGHT;
System.out.println("width: " + width);
System.out.println("height: " + height);
System.out.println("orientation: " + Gdx.input.getNativeOrientation());
System.out.println("rotation: " + Gdx.input.getRotation());
// If showing portrait and needs to be rotated
rotateForProperLayout = width < height;
if (rotateForProperLayout) {
height = ((float) Gdx.graphics.getHeight() / (float) Gdx.graphics.getWidth()) * GameSpecs.WORLD_HEIGHT;
width = GameSpecs.WORLD_HEIGHT;
}
cam = new OrthographicCamera(width, height);
// Rotate camera to be in landscape
if (rotateForProperLayout) {
cam.rotate(-90);
}
cam.translate(cam.viewportWidth / 2f, cam.viewportHeight / 2f);
cam.update();
My Android Manifest...
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mydev.mygame” >
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:isGame="true"
android:appCategory="game"
android:label="#string/app_name"
android:theme="#style/GdxTheme" >
<activity
android:name="com.mydev.mygame.AndroidLauncher"
android:label="#string/app_name"
android:screenOrientation=“landscape"
android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize|screenLayout">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Any help in trying to understand the reason for this or possible workarounds would be greatly appreciated. Please let me know if I should clarify anything or provide more information.
Thanks in advance.
Since no ones helped you so far I'll post my android manifest, you should maybe post yours since this is almost certainly where the problem is. I set this up a long time ago and, to be honest, can't really remember exactly why everything is set as it is, but it works for me. Note: I use device rotation to control my game in some modes.
As for your manual screen rotation issues, you could access the cameras projection matrix and scale it accordingly to get it looking ok. I do not recommend this though, since it is difficult to track how screen resize calls should alter your layout when you also have to track screen rotation. You would have to consider if the width change should actually be considered a height change when in portrait mode and vice versa (depending on your game complexity). I would recommend just sorting out your manifest. Good luck.
android:screenOrientation="fullSensor"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/GdxTheme" >
<activity
android:name="com.funferret.tr.AndroidLauncher"
android:label="#string/app_name"
android:screenOrientation="sensorLandscape"
android:configChanges="keyboard|keyboardHidden|navigation|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
My application is a simple WebView "wrapper" that displays a web page in a fixed landscape orientation, the page has a centered div that is 760px wide and 415px high and this should be displayed scaled on all devices so it (roughly) fits the screen, the user cannot change the scaling... I've almost got everything working apart from the scaling.
I have the following viewport meta tag on the page :
<meta name="viewport" content="width=device-width, target-densityDpi=device-dpi, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
The manifest for the WebView wrapper .apk I've created is as follows:
<supports-screens android:smallScreens="true"
android:normalScreens="true" android:largeScreens="true"
android:anyDensity="true" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name="{my name}"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I should mention that originally the .apk target was Android 2.2 and I've recently changed up to 2.3.1 and added another line to the manifest but that's made no difference to anything :
android:xlargeScreens="true"
I added the following in to the .java code :
webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
webview.setScrollbarFadingEnabled(false);
webview.getSettings().setSupportZoom(false);
webview.getSettings().setBuiltInZoomControls(false);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
For the purpose of this question just assume that the only content on the entire site is the following <div>:
<div style="margin: auto; position:relative; align:center; top:0px; width:760px; height:415px; background-color:#000000">
My problem is I can't to come up with a "one-size-fits-all" scaling solution across all Android devices, everything else I've tasked myself with delivering works fine.
I've tried this on three different devices, one tablet and two phones, and there is a large gap on the left, right and bottom of the <div> layer. It looks like the 760px width has about another 50px gap on either side and the same underneath on each of the devices, all I want to do is scale that up so it roughly fills the screen on all of the devices.
My phone says it's got a window.innerWidth of 854 with a window.devicePixelRatio of 1.5 and if I change the initial and maximum scale to 1.12 the <div> layer fits just about perfectly on my device. The table says it's got a window.innerWidth of 980 with a window.devicePixelRatio of 1.0 and seems to like a scale of around 1.27. I don't know the details of the third device but using 1.1 seem to do the trick on that.
Of course changing the initial scaling isn't a solution and even attempting it would be a complete nightmare so, fingers crossed, can anyone tell me the blindingly obvious thing that I'm missing that'll make this work? Or am I just asking the impossible to automatically scale the view to a fixed size <div>?
Right... On the way home I was stuck in a jam and had a jolly good think, I came to the conclusion that I was dramatically over-thinking this problem.
This is rough but it does the job, I removed the meta tag from the site and added this to the application :
// Set up up the scaling value
float scaling = 100;
int display_width;
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
display_width = dm.widthPixels;
scaling = (((float)display_width/760)*100); // 760 here is my container div width
scaling = (int) Math.floor(scaling);
// Set up the webview and apply the scale value
webview = (WebView) findViewById(R.id.webview);
webview.setInitialScale((int)scaling);
That works quite well but I have encountered two issues since I made this post.
The first is that by removing the meta tag I seem to have removed my limitation on the maximum/minimum scale, this means that clicking on any <INPUT> element which displays the Android keyboard will result in a change in the scaling. Luckily, adding this line to the code solves this issue so far :
webview.getSettings().setDefaultZoom(ZoomDensity.FAR);
The second I don't have a workable solution for and is that some devices, such as the Archos101 tablet, have software buttons instead of hardware buttons. The scaling code here will scale to the device width and that means the site goes underneath the software buttons... Currently thinking about implementing a solution based on READ_PHONE_STATE or optionally adding the ability to quit the application without hardware buttons and adding this to the manifest :
<uses-permission android:name="archos.permission.FULLSCREEN.FULL" />
Hopefully someone else will find this and save themselves some time.
I'm writing an application that needs to display a full-screen splashscreen image on start. Actually, not exactly full-screen, because status bar is still visible.
This application will be run on a wide range of phones (e.g. from Wildfire to Sensation), but not on tablets. Though, if it can be made to look good on tablets without much effort, I will do that of course.
The problem is - how can I make sure that this splashscreen looks good and fills the entire screen on all devices? It has stretchable parts on all sides, so I can make it a 9-patch if necessary, but I'm still at loss on what pixel sizes I should use.
I resolve that I need to provide images for (small|large)-(ldpi|mdpi|hdpi). What pixel sizes of those images should be? How to calculate them?
I have done it in multiple applications that i made an image of 480x800px and then took an image view or linearlayout and gave it fill_parent attributes in widht and height. It worked perfectly on all types of screen
[EDIT] One thing more just add that image in hdpi folder only.
For Splash Screen in your xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:scaleType="fitXY"
android:src="#drawable/splash"/>
</LinearLayout>
and in your AndroidManifest.xml
<activity android:name=".Splash" android:theme="#android:style/Theme.NoTitleBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
The Theme.NoTitleBar will also remove the title bar from the splash screen
And for the image for splash screen use images of sizes:
As i had read somewhere and then used
For Portrait: 600 x 1024 px
For Landscape: 1024 x 600 px
I use these sizes in my app and have tested them on android versions 1.6 to 2.3 in each version the resolution of the images appears excellent
In the end, I found out that if I provide an hdpi image, it will auto-scale down for lesser dpi. So, to avoid complications, I created a 800x800 image with croppable sides and used it.
On a "normal" size screen hdpi device, I understand that 72 x 72 pixels graphics should be used, and they should otherwise follow the Icon Design Guidelines (which some of the platform graphics interestingly do not do). When I try to do this by creating my own new graphics or by copying a graphics file from the Android SDK, however, the graphic in the menu is too big, and it forces the text label, i.e., the title, that should be below it to not appear. If I "force" the use of a 48 x 48 pixels graphic, then the size looks good and the text label has room to appear, but this doesn't seem like the right solution, since the graphic display quality is diminished, and the documentation clearly says a 72 x 72 graphic should be used.
I understand the 9-patch graphics should be used to help ensure proper-looking scaling, but none of the menu icon graphics in the platform drawable folders appear to actually be 9-patch, as they don't have any 9-patch markers. For these screenshots, I did add 9-patch markers to a copy of the Android SDK platform 10 72 x 72 hdpi ic_menu_share.png graphic. (The draw9patch.bat tool unexpectedly changed the colors of the graphic.)
In the following four screenshots, I'm showing nine menu icon displays, running on my G2, and running on an emulator with G2-like qualities: Android 2.2 API 8 WVGA800 240dpi. (Both of these devices have "normal" sized hdpi screens.) Since the menu icon graphics will only show six at a time, there are two screenshots for each device: v1 and v2. Following the screenshots are the code components used to generate this application, along with a link to the complete project with all of the graphics files I used.
Emulator_2.2_API8_WVGA800-240_v1:
(Note: In the above screenshot of the emulator, the icon labeled "G2 Platform" should probably instead be labeled "Running Platform", since the displayed graphic is from the currently running Android platform - not from the G2 platform. I was just too lazy to correct this.)
Emulator_2.2_API8_WVGA800-240_v2:
G2_v1:
G2_v2:
(Please note I carefully followed the Icon Design Guidelines when creating and copying these graphics.)
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="fubar.guiexamples"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:anyDensity="true" />
<application
android:icon="#drawable/icon"
android:label="#string/app_name">
<activity
android:name=".MenuIconConfusion"
android:label="#string/app_name">
<intent-filter>
<action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MenuIconConfusion.java:
public class MenuIconConfusion extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_options_menu, menu);
return true;
}
}
main_options_menu.xml v1:
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/g2_platform_with_title"
android:icon="#android:drawable/ic_menu_share"
android:title="G2 Platform" />
<item
android:id="#+id/g2_platform_no_title"
android:icon="#android:drawable/ic_menu_share" />
<item
android:id="#+id/platform_10_auto_selection_with_title"
android:icon="#drawable/ic_menu_share"
android:title="Platform 10 Auto" />
<item
android:id="#+id/platform_10_auto_selection_no_title"
android:icon="#drawable/ic_menu_share" />
<item
android:id="#+id/pixels_auto_selection"
android:icon="#drawable/ic_menu_pixels"
android:title="Pixels" />
</menu>
main_options_menu.xml v2:
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="#+id/platform_10_hdpi_72_with_title"
android:icon="#drawable/ic_menu_share_p10_hdpi_72"
android:title="Platform 10 72 Copy" />
<item
android:id="#+id/platform_10_hdpi_72_no_title"
android:icon="#drawable/ic_menu_share_p10_hdpi_72" />
<item
android:id="#+id/platform_10_mdpi_48_with_title"
android:icon="#drawable/ic_menu_share_p10_mdpi_48"
android:title="Platform 10 48 Copy" />
<item
android:id="#+id/platform_10_hdpi_72_9_patch_with_title"
android:icon="#drawable/ic_menu_share_p10_hdpi_72_nine_patch"
android:title="Platform 10 72 9p Copy" />
<item
android:id="#+id/platform_10_hdpi_72_9_patch_no_title"
android:icon="#drawable/ic_menu_share_p10_hdpi_72_nine_patch" />
<item
android:id="#+id/pixels_auto_selection"
android:icon="#drawable/ic_menu_pixels"
android:title="Pixels" />
</menu>
Some Clarifications Regarding the Screenshots and Code:
As I did for this demo, I understand that we're not supposed to use graphics from android:drawable, for the reasons described in the menu icon design guidelines.
For some of the icons, I dislayed them each twice - once each with a title, and once each without a title - to see whether having a title influenced which graphic was selected and whether the selected graphic was scaled.
The icon labeled "Platform 10 48 Copy" is a 48 x 48 pixel graphic, copied from the Android SDK platform 10 drawable-mdpi folder.
The two lighter colored icons are from the nine patch image. Note they exhibit no scaling characteristics.
The "72" icon was included to show that drawable-hdpi resources are indeed being auto-selected by the running platform, as expected. Were the drawable-hdmi resources instead used, then the displayed number would be "48".
POSSIBLE QUESTIONS:
In a nutshell, I didn't expect much of the results displayed in these screenshots. While I did expect the drawable-hdpi 72 x 72 graphics to be used, I also expected them to display with enough room for the associated titles. So...
I might be asking, "How do I get the menu icon graphics to scale, in order to leave room to dislay the associated title?"
I might be asking, "What size graphics are we really supposed to use for menu icons, nevermind what the official documentation says?"
I might be asking, "What the hell is going on here? What don't I understand?"
The Android project files with the graphics I used can be downloaded from https://sites.google.com/site/androidguiexamples/home/downloads/MenuIconConfusion.zip
All your icons are in the res/drawable directory. So I think the OS is auto-scaling your icons so that they appear as incorrect sizes. They should be split into different directories based on the dpi level the icon is targeted for. 72x72 icons go in res/drawable-hdpi, 48x48 go in res/drawable-mdpi and 36x36 go in res/drawable-ldpi. Note that they should all have the same name.
res/drawable-hdpi/ic_menu.png
res/drawable-mdpi/ic_menu.png
res/drawable-ldpi/ic_menu.png
Then in your menu layout just reference the image using #drawable/ic_menu.png. The OS will then figure out which one to use based on the dpi of the device it is running on.
And as Joseph Earl says, they shouldn't be 9-patch images.
The Android system will select HDPI icons for the target you specified
This will leave enough room for text on the icons
So you might be wondering why you're getting something that looks wrong - simply icons should not be nine-patches, which is why the existing ones did not have nine-patch markers.
A nine-patch is used for a graphic that needs to be resized in a manner that cannot be done by simply scaling/stretching an image (e.g. a button background which expands to fill the content but the corner-radius stays the same, or the window title background). So generally a nine patch is used for a background image of some type.