Xamarin Forms Adaptive Banner Ad Won't Load in Landscape - xamarin

I recently upgraded from a Galaxy S6 to a Galaxy S21 Ultra and now the AdMob adaptive banner advert will not load in landscape. On the S6 it is fine, but on the S21 I get the error:
[Ads] Ad failed to load : 1
The code I use to create the advert is here:
private void NewAdaptiveBannerAd()
{
try
{
adAdaptiveBannerView = new AdAdaptiveBannerView();
adAdaptiveBannerView.Padding = new Thickness(0);
adAdaptiveBannerView.BackgroundColor = (Color)Application.Current.Resources["baseBackground_Light"];
AdGrid.Children.Add(adAdaptiveBannerView, 0, 1);
adAdaptiveBannerView.HeightRequest = getCurrentOrientationAnchoredAdaptiveBannerAdSize(Android.App.Application.Context, (int)(DeviceDisplay.MainDisplayInfo.Width / DeviceDisplay.MainDisplayInfo.Density));
static int getCurrentOrientationAnchoredAdaptiveBannerAdSize(Context context, int adWidth)
{
int var3 = 0;
if (context == null)
{
return 0;
}
else
{
int var7 = 2;
switch (DeviceDisplay.MainDisplayInfo.Orientation)
{
case DisplayOrientation.Unknown: var7 = 0; break;
case DisplayOrientation.Portrait: var7 = 1; break;
case DisplayOrientation.Landscape: var7 = 2; break;
default: return 0;
}
if (var3 == 0)
{
var3 = var7;
}
int var8 = var3 == var7 ? (int)Math.Round((float)DeviceDisplay.MainDisplayInfo.Height / DeviceDisplay.MainDisplayInfo.Density) : (int)Math.Round((float)DeviceDisplay.MainDisplayInfo.Width / DeviceDisplay.MainDisplayInfo.Density);
int var9 = (int)Math.Min(90, Math.Round((float)var8 * 0.15F));
int var10;
if (adWidth > 655)
{
var10 = (int)Math.Round((float)adWidth / 728.0F * 90.0F);
}
else if (adWidth > 632)
{
var10 = 81;
}
else if (adWidth > 526)
{
var10 = (int)Math.Round((float)adWidth / 468.0F * 60.0F);
}
else if (adWidth > 432)
{
var10 = 68;
}
else
{
var10 = (int)Math.Round((float)adWidth / 320.0F * 50.0F);
}
var10 = Math.Max(Math.Min(var10, var9), 50);
return var10;
}
}
}
catch (Exception)
{
Console.WriteLine("Creation of banner ad in SavedCharts failed.");
}
}
adAdaptiveBannerView is declared at the top of the pages class. The getCurrentOrientationAnchoredAdaptiveBannerAdSize function is from another post on here that I can't find now.
I can't find anything that would explain this, or why it would behave differently between these two 'phones (is it the difference in Android versions, the different aspect ratio or what?). Testing on the emulator is difficult because it doesn't report orientation correctly.
Does anyone have any idea what's going on?
My app will, by it's nature, mostly be used in landscape mode, so this problem means there's a chance many people won't see the adverts.
PS I'm using Xamarin.GooglePlayServices.Ads version 119.8.0. I haven't been able to implement version 120 because there's no documentation or anything that would help me do it.
Edit 1: I've tried conditionally adding an adaptive banner ad when in portrait, and a standard banner ad using MarcTron.Admob. It doesn't work.
I wondered if it's because the S21 Ultra's display is 1440 x 3200 pixels with an aspect ration of 20:9, and Google Ad Mob can't cope with it. It's rather stupid if that's the case ('adaptive'?!). So I tried giving it a screen width of 2560 on the basis that it worked on the S6 (1440x3200), and 1600 (i.e. half), but neither worked.
Edit 2: I realised I'd made a mistake when I tried limiting the screen width to 2560px, which was that I only did that for the height request of the view, whereas I also needed to do it for the AdSize property of the AdMob class itself. Anyway, that is the problem - adaptive banner ads can't cope with a display 3200px wide.

Google AdMab adaptive banner adverts cannot cope with a screen width of 3200px. I don't know what the actual limit is but since it works on my other device that has a screen width of 2560px I've limited it to that, like so:
adView.AdSize = AdSize.GetCurrentOrientationAnchoredAdaptiveBannerAdSize(Android.App.Application.Context, (int)(Math.Min(2560,DeviceDisplay.MainDisplayInfo.Width) / DeviceDisplay.MainDisplayInfo.Density));
and applied the same Math.Min() limiter to the code in my question.
The has the slightly unfortunate side-effect of a gap either side of the banner ad (3200-2560)/2=320 pixels wide. This doesn't violate Google's policies though (https://developers.google.com/admob/android/banner/adaptive).
I suggest this is a bug in Google's API (or at least the NuGet package), as an 'adaptive' ad that can't cope with all screen resolutions in real devices doesn't live up to its name.

Related

cocos2dx Windows Phone 10 game graphic quality

I am trying to clone a game for Windows phone. This is not for commerical.
I've created new cocos2dx win10 project with cocos creator. And tried to build and executed on Windows Phone 10 Lumia 935. But when I execute on real device, the graphic quality is lower than the original one. The 2 screenshots were attached.
I've setted screen resoulution to 800 x 480. And all images are not scaled.
This is the image on original game.
And this is the image on my new game.
Why these 2 image quality is different?
The original image is this.
What's the reason? I've read this article, but still not found correct answer.
https://github.com/cocos2d/cocos2d-x/issues/15901
The codes that I've implemented was added.
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
glview = GLViewImpl::createWithRect("RealHillClimb", cocos2d::Rect(0, 0, designResolutionSize.width, designResolutionSize.height));
#else
glview = GLViewImpl::create("RealHillClimb");
#endif
director->setOpenGLView(glview);
}
director->setAnimationInterval(1.0f / 180);
glview->setDesignResolutionSize(1280, 720, ResolutionPolicy::NO_BORDER);
auto frameSize = glview->getFrameSize();
int a = Device::getDPI();
if (frameSize.height > mediumResolutionSize.height)
{
director->setContentScaleFactor(MIN(largeResolutionSize.height/designResolutionSize.height, largeResolutionSize.width/designResolutionSize.width));
}
else if (frameSize.height > smallResolutionSize.height)
{
director->setContentScaleFactor(MIN(mediumResolutionSize.height/designResolutionSize.height, mediumResolutionSize.width/designResolutionSize.width));
}
else
{
director->setContentScaleFactor(MIN(smallResolutionSize.height/designResolutionSize.height, smallResolutionSize.width/designResolutionSize.width));
}
director->setContentScaleFactor(1);
cocos2d::Size dsize = glview->getDesignResolutionSize();
float d = director->getContentScaleFactor();
register_all_packages();
auto scene = SCNSplash::createScene();
director->runWithScene(scene);
return true;

Out of memory error when reloading activity several times

I am developping an app that has a main activity showing the app title (two animated imageviews overlayed), two animated pictures, also overlayed, and three buttons. This activity also has a background image, which is the same that is used by the other activities.
The app flows from one activity to another and, eventually, this main activity is launched again (with the FLAG_ACTIVITY_CLEAR_TOP). Everything works fine but, after reloading it several times, an Out Of Memory error happens on my Android 2.1 device.
At first, I had all the images in the drawable folder and the problem appeared after reaching the main activity 5 times. Then, I adjusted the bitmap sizes and put them in the approppriate folders depending on the density and the problem appeared after reaching the main activity 14 times. Now, I just removed the background image for test purposes and the Out Of Memory appears after more than 20 re-launches.
Also, if I press the Home button and then switch back to my app, the problem seems not to appear until much later.
Moreover, I tested the app in a Nexus 5 and the Out Of Memory never happens.
So... is that a problem with my phone? with Android 2.1?
Thanks!
[EDIT]
I think that I have located the problem but, still, strange behavior.
For example, at one point, I need to recreate the activity. As the "recreate" method is not available for my min API level (7), I do it as follows:
Intent refresh = new Intent(getActivity(), getActivity().getClass());
refresh.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(refresh);
Which, I think, is correct. I release the onClickListeners and clear the animations in onStop(). However, if I put a breakpoint in onStop(), it is not called when I expect it to happen. Sometimes it is called as soon as the activity is recreated but sometimes it is called several seconds later.
However, if I press the Home button, onStop is properly called and when I switch back to the application everything works fine.
The easiest solution is to add in manifest under application tag
android:largeHeap="true"
But this is won't solve your problem, just delay it to a few more rounds
This link will help you to analyze your application and see what cause this:
http://blogs.innovationm.com/android-out-of-memory-error-causes-solution-and-best-practices/
My Guess this is related to images because i had this issue also..
The android official link to this problem is:
http://developer.android.com/training/displaying-bitmaps/index.html
This the link that helped me.. Try it out
http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
Hope that helps
check this outLoading Large Bitmaps Efficiently
Read Bitmap Dimensions and Type
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
Load a Scaled Down Version into Memory
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
imageView.setImageBitmap(
decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

GPS accuracy Issues

I am developing a windows phone sports tracker app, that uses gps sensors to calculate the distance travelled by the runner, I am using geocoordinatewatcher class for the same, setting the movement threshold to 100. But, I find my app giving distance values even when the device is kept stationary. My app should give distance only when the device changes its position. I found the same bug in othere apps that are on the marketplace, please tell me where am I doing wrong?
My Code.
watcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
watcher.MovementThreshold = 150;
watcher.PositionChanged += watcher_PositionChanged;
watcher.Start();
{
latitudeCurrent = e.Position.Location.Latitude;
longitudeCurrent = e.Position.Location.Longitude;
if (stepCounter == 0)
{
latitudePrevious = latitudeCurrent;
longitudePrevious = longitudeCurrent;
distanceTravelled += Math.Round(Calculate(latitudePrevious,longitudePrevious,latitudeCurrent,longitudeCurrent),2);
txbDistanceTravelled.Text = distanceTravelled.ToString();
txbCalories.Text=string.Format("{0:f0}", distanceTravelled * 65);
stepCounter++;
var millisPerKilometer = (distanceTravelled) * (System.Environment.TickCount - _previousPositionChangeTick);
txbPace.Text = TimeSpan.FromMilliseconds(millisPerKilometer).ToString(#"mm\:ss");
double hrs = counterTick / 3600;
if (!double.IsNaN((distanceTravelled / hrs)))
{
txbSpeed.Text = (distanceTravelled / hrs).ToString();
}
else
{
txbSpeed.Text = "0";
}
}
}
You are developing your app for Windows Phone 7 or Windows Phone 8? IF you are developing for the later, you need to use the new Geolocator class and not GeoCoordinateWatcher.
Also, as LewisBenge said, if you are testing This indoor you can get WiFi positions or even cellular data. It could be better to test outdoor.
Your GPS signal might be weak in the place where you are testing. Try it in the outdoor location.

Which API can be used to _capture_ the mouse when moving OS X "Carbon" windows?

On request I have implemented support for moving an OS X window by dragging it using an area within the content part of the window, i.e replicating the drag and move functionality of the title bar but in another area.
The problem I have yet to resolve is the fact that if the user drags the mouse quickly it can leave the window area and then no more mouse move events are received.
On windows this type of problem can simply be fixed by calling the win32 method SetCapture(), what's the corresponding OSX method?
This application is a cross platform C++ application using Carbon for the OS X specific parts. (And yes, I know all about the Cocoa benefits but this is an older code base and there no time nor money for a Cocoa port at this point in time.)
I have found Carbon API methods like for example TrackMouseLocation() but can't really see how I could use them for this application. In listing 2-7 here http://developer.apple.com/legacy/mac/library/documentation/Carbon/Conceptual/Carbon_Event_Manager/Tasks/CarbonEventsTasks.html
the mouse is captured but the problem is that TrackMouseLocation() blocks waiting for input. Blocking is something this application can not do since it also host a flash player that must be called many times per second.
The protototype I have assembled when trying to figure this out basically looks like this:
switch(GetEventKind(inEvent))
{
case kEventMouseDown:
// A silly test to make parts of the window border "draggable"
dragging = local_loc.v < 25 || local_loc.h < 25;
last_screen_loc = screen_loc;
break;
case kEventMouseUp:
dragging = false;
break;
case kEventMouseMoved:
break;
case kEventMouseDragged:
if (dragging) {
Rect rect;
GetWindowBounds (windowRef, kWindowContentRgn, &rect);
int dx = screen_loc.h - last_screen_loc.h;
int dy = screen_loc.v - last_screen_loc.v;
rect.left += dx;
rect.right += dx;
rect.top += dy;
rect.bottom += dy;
SetWindowBounds (windowRef, kWindowContentRgn, &rect);
}
last_screen_loc = screen_loc;
break;
Any ideas appreciated?
I feel you should track mouse in Window as well as out of window. Following code should solve your problem,
EventHandlerRef m_ApplicationMouseDragEventHandlerRef;
EventHandlerRef m_MonitorMouseDragEventHandlerRef;
{
OSStatus ErrStatus;
static const EventTypeSpec kMouseDragEvents[] =
{
{ kEventClassMouse, kEventMouseDragged }
};
ErrStatus = InstallEventHandler(GetEventMonitorTarget(), NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_MonitorMouseDragEventHandlerRef);
ErrStatus = InstallApplicationEventHandler(NewEventHandlerUPP(MouseHasDragged), GetEventTypeCount(kMouseDragEvents), kMouseDragEvents, this, &m_ApplicationMouseDragEventHandlerRef);
return true;
}
//implement these functions
OSStatus MouseHasDragged(EventHandlerCallRef inCaller, EventRef inEvent, void *pUserData){}
Hope it helps!!
I Hope It Help´s you too:
// Get Mouse Position --> WAY 1
printf("Get Mouse Position Way 1\n");
HICoordinateSpace space = 2;
HIGetMousePosition(space, NULL, &point);
printf("Mouse Position: %.2f %.2f \n", point.x, point.y);
// Get Mouse Position --> WAY 2
printf("Get Mouse Position Way 2\n");
CGEventRef ourEvent = CGEventCreate(NULL);
point = CGEventGetLocation(ourEvent);
printf("Mouse Position: %.2f, y = %.2f \n", (float)point.x, (float)point.y);
I´m looking for the way to get a WindowPart Reference at a certain location (over all windows of all aplications)
Certain methods in Carbon doesn´t work, always return 0 as a windowRef... Any ideas?
You could also try just calling DragWindow in response to a click in your window's content area. I don't think you need to implement the dragging yourself.

Letter-sized Document truncated when printing from browser on Mac OS X

The bottom of the page is truncated when printed. (Approx 1/2 to 1").
This printing problem does not seem to be specific to Flash (printing certain PDFs also yields this problem), but that is where we found it.
The problem does not occur in older versions of OS X, but does occur in the most recent versions (10.5.5 and up). Not sure where the line is. The same application on Windows works fine.
It happens in Safari and Firefox.
Our Flash CS3 (AS2) application uses the PrintJob object to send pages to the printer. The pages are supposed to be letter-sized. On Windows they are letter-sized and print fine. But on the Mac, the pages are truncated. When the browser Print dialog comes up, if you change paper size to A4, the document prints fine. IT IS NOT SUPPOSED TO BE A4.
What is going on?
Here is a fraction of our printing code:
private function runPagePrintJob(pages:Array):Void {
var pj:PrintJob = new PrintJob();
if (pj.start()) {
var paperHeight:Number = this.pointsToPixels(pj.pageHeight);
var paperWidth:Number = this.pointsToPixels(pj.pageWidth);
for (var i:Number=0; i<pages.length; i++) {
var mc:PrintablePage = pages[i];
var xScale:Number = paperWidth / mc._width;
var yScale:Number = paperHeight / mc._height;
if ((xScale < 1) || (yScale < 1)) {
mc.setScale(Math.min(xScale, yScale) * 100);
}
mc.setBGSize(paperWidth, paperHeight);
var xMin:Number = 0;
var xMax:Number = paperWidth;
var yMin:Number = 0;
var yMax:Number = paperHeight;
pj.addPage(mc, {xMin:xMin, xMax:xMax, yMin:yMin, yMax:yMax}, {printAsBitmap:true});
}
pj.send();
}
delete pj;
this.close();
}
private function pointsToPixels(pts:Number):Number {
return pts/72*System.capabilities.screenDPI;
}
Have you tried this with more than one printer model? I've seen similar problems that have been the result of a buggy printer driver.

Resources