Xamarin Forms AdMob trouble with AudioManager - c#

When i get request from admob, every millisecond my debug console spamming me:
D/AudioManager (26589): getStreamVolume isRestricted mode = 0.
I don't have any single line of code about sound. Ad(banner) is showing but this affects on the performance. Anyone have this problem?
I tried a lot of samples like this:
https://startdebugging.net/how-to-add-admob-to-your-xamarin-forms-app/
https://xamarinhelp.com/admob-xamarin-forms-display-google-ads-mobile-app/

(I highly doubt it is affecting performance, if AudioManager was spamming logcat at a high enough rate, the OS would rate limit its output...)
It is telling you that an meadiation/interstitial ad wants to play some sound and the OS is replying that the channel is muted (at level 0).
Now you can request that your app is muted and that no ads be requested/played that contain an audio track:
Android.Gms.Ads.MobileAds.SetAppMuted(true);
Note: Video ads that are ineligible to be shown with muted audio are not returned for ad requests made when the app volume is reported as muted or set to a value of 0. This may restrict a subset of the broader video ads pool from serving.
https://developers.google.com/admob/android/global-settings

Related

Why can't a windows service created in C# detect that a screen saver is currently running?

As part of some work I need to get done for Windows 10, I have written a code in C# that essentially detects every minute whether a PC is in screen saver mode or not, and it writes to a table in MySQL the relevant status ("PC in use" if the screen saver is off, "available PC" if the screen saver is on).
I did this using (full link if required - https://www.codeproject.com/Articles/17067/Controlling-The-Screen-Saver-With-C):
// Returns TRUE if the screen saver is actually running
public static bool GetScreenSaverRunning( )
{
bool isRunning = false;
SystemParametersInfo( SPI_GETSCREENSAVERRUNNING, 0,
ref isRunning, 0 );
return isRunning;
}
The code works flawlessly in console application mode (I made a loop to test it out over a minute with a check up on screen save status every 10 seconds), this means in MySQL the status was set correctly every time, depending on the screen save status at the moment of the check up.
The problem occurs when I use this code for a windows service. The service is installed correctly, the log on tab is set on Local System (I also tried with the logged in user instead, same results) and I allow the service to interact with the desktop, just in case, but the difference here is that no matter if the PC enters screen save or not, it always returns false on GetScreenSaverRunning(), thus setting the status of the PC in MySQL as "PC in use", even if the screen saver is on at the moment of check up.
I get the sense that the problem isn't in the code itself, since it works without any issues as a console application, but perhaps something behind the scenes. I tried to search here and on many other websites, haven't found anything related to such a problem.
Does anyone have any idea at all what might be the issue? Any help and/or suggestions will be greatly appreciated!
Thank you in advance.
(I could post the code if required, but it is pretty much straight forward and the main part of it, controlling the screen save detection, is taken from the website mentioned above, afterwards it's a simple if (GetScreenSaverRunning() == true) )
Ever since Vista, Services are barred from a Interactive Session. Even if they run under the same rights, they do not get a interactive Session. I would guess that is getting in the way here.
While you can overwrite this behavior in the Service settings, this is not adviseable for new code. Consider making this a Background Task started by the Task Sheduler instead.
Because the windows service runs in different session then the windows logon. You can't interact with the desktop related services unless you run the windows service in win logon session. There used to be an option in Windows service manager where you can set the properties to "Interact with desktop session" but I don't think that ever worked.
There's a work around to run the windows service using the win logo session.
See this helper class that can get the current logged on user session and interact with the desktop services. https://github.com/murrayju/CreateProcessAsUser/blob/master/ProcessExtensions/ProcessExtensions.cs

Error android.app.ServiceConnectionLeaked when InApp purchase

I am developing an Android App with Xamarin Android.
I'm using the InAppBilling Plugin from James Montemagno.
When I call PurchaseAsync Method the PlayStore dialog opens. But in the background my app freezes and I dont get any result.
var purchase = await CrossInAppBilling.Current.PurchaseAsync(productId, ItemType.Subscription, "apppayload");
In the Sys Log theres a android.app.ServiceConnectionLeaked error:
02-17 22:13:05.434 LENOVO YT3-X50L Error 8031 ActivityThread android.app.ServiceConnectionLeaked: Activity md5742c3bd4cdfedb6330d25c53207d662c.ShopActivity has leaked ServiceConnection md57a6f08dbc6561d468b2675b2ac9edab2.InAppBillingImplementation_InAppBillingServiceConnection#2277a40 that was originally bound here
at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:1092)
at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:986)
at android.app.ContextImpl.bindServiceCommon(ContextImpl.java:1303)
at android.app.ContextImpl.bindService(ContextImpl.java:1286)
at android.content.ContextWrapper.bindService(ContextWrapper.java:604)
at mono.android.view.View_OnClickListenerImplementor.n_onClick(Native Method)
at mono.android.view.View_OnClickListenerImplementor.onClick(View_OnClickListenerImplementor.java:30)
at android.view.View.performClick(View.java:5205)
at android.view.View$PerformClick.run(View.java:21164)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
I only get this error on LENOVO YT3-X50L. On Samsung phones it works fine...
ServiceConnectionLeaked
The CrossInAppBilling code does not take into consideration that your Activity can be killed/flushed from memory due to memory pressure/requirements and does not directly do anything to try to prevent it, it is up the app developer to determine when they need to take special action.
This is something I see a lot of in lower-end Android devices and the the new Android Oreo Go (<=1MB) test devices, but can happen on any device, but mostly noticeable on 2GB and lower devices.
Before calling any external code flush/release as much memory as possible
Focusing on releasing images is usually the largest payoff for memory reduction (restore them after the purchase is completed)
In cases of the Oreo Go 512MB devices I have had to go the extra mile and finish the current Activity, create a new blank/empty transient Activity and then call the external code (app billing, camera, etc) and upon completion, restore the original activity and bring it up to date with the new information externally obtained.
Note: profile your app and the activity first in order to focus your time.
Use your own Keep-Alive Service
Using Start/StopService and not Bind/UnBindService
Make it a Foreground Service
Note: This does not prevent the OS from killing/flushing your Activities/Services, it just provides a "hint" that it should not...
Note: Monitor the Importance state within the RunningAppProcessInfo to determine if your app is entering ReasonServiceInUse before you execute the external code.

my roaming data dosen't sync between devices

I made a UWP application. I use the roamingdata.I save the setting by this:
public static void WriteCode(string pwd)
{
ApplicationDataContainer RoamingSettings = ApplicationData.Current.RoamingSettings;
RoamingSettings.Values["Code"] = EncryptHelper.PwdEncrypt(pwd);
}
I read the setting by this:
public static string GetCode()
{
ApplicationDataContainer RoamingSettings = ApplicationData.Current.RoamingSettings;
string str = (String)RoamingSettings.Values["Code"];
if (!String.IsNullOrEmpty(str))
return str;
else
return EncryptHelper.PwdEncrypt("123");
}
I complete the application and upload to windows store and passed check. Then I download this app on my phone.
I change the ApplicationData.Current.RoamingSettings on phone. I write something to the ApplicationData.Current.RoamingFolder on my phone.
Next I closed the app on my phone and download the app on my PC. But when I opened the app on my PC, I found that the ApplicationData.Current.RoamingSettings and the ApplicationData.Current.RoamingFolder didn't change anything.
I checked the C:\Users\XXX\AppData\Local\Packages\XXX\RoamingState on my PC,there was nothing. I checked C:\Users\XXX\AppData\Local\Packages\XX\Settings on my PC,there was roaming.lock and settings.dat. But I can't read the lastest settings and roaming data that I haved added on my phone anymore.
I have waited for 2 hours, there was no change on my PC.
there is something that I should state first:
1 All the deploy work was done by windows store.
2 I check my PC application setting after closed the app on phone. I even shut down my mobile phone to observe the change to my PC.
what's wrong with my code? or what's wrong with the roamingdata mechanism? I need an answer, thank you!
The code you've posted is right. However, there are some possible reasons for the failure of roaming data sync:
Any user can benefit from roaming app data if they use a Microsoft account to log on to their device. However, users and group policy administrators can switch off roaming app data on a device at any time. If a user chooses not to use a Microsoft account or disables roaming data capabilities, she will still be able to use your app, but app data be local to each device.
Keep in mind that roaming data is associated with a user's Microsoft account. Roaming data will only sync if a user logs into her devices using the same Microsoft account and installs the app on several devices.
Don't use roaming for data that relies on instant syncing. Windows doesn't guarantee an instant sync; roaming could be significantly delayed if a user is offline or on a high latency network.
Roaming of settings is not instant. The system weighs several factors when determining when to send the data. We can detect whether new roaming data has arrived on the local device by listening for the ApplicationData.DataChanged event. This event occurs when app data has just finished syncing from the cloud. Any time a device receives new roaming data, the DataChanged event will fire, passing in the updated ApplicationData object. This lets us make any adjustments to our app when data has changed.
For important, time critical settings, use the HighPriority setting associated with RoamingSettings like following:
// High Priority setting, for example, last page position in book reader app
roamingSettings.values["HighPriority"] = "65";
This is a special key in the roaming settings we can use for data we need to sync immediately. Adding HighPriority to any setting will have it synced as quickly as possible.
Don't roam large sets of app data. There's a limit to the amount of app data an app may roam; use RoamingStorageQuota property to get this maximum. If an app hits this limit, no data can roam until the size of the app data store no longer exceeds the limit.
The name of each setting can be 255 characters in length at most. Each setting can be up to 8K bytes in size and each composite setting can be up to 64K bytes in size. The sync engine may limit the total size of settings and files that can roam. It’s important to keep track of the amount of data you’re attempting to roam. If the total amount of data you’re attempting to sync exceeds the limit, then nothing will sync between the devices.
App data only roams between installed apps with the same version number. For example, devices on version 2 will transition data between each other and devices on version 3 will do the same, but no roaming will occur between a device running version 2 and a device running version 3. If you install a new app that utilized various version numbers on other devices, the newly installed app will sync the app data associated with the highest version number.
If you are using versioning in your roaming date, please make sure you are dealing with the right version.
These are some possible reasons that can cause roaming data doesn't sync between devices. For more info, please check Roaming data in Store and retrieve settings and other app data.

Programmatically enabling Windows 8 Pro mobile broadband device

Background
The company I work on is developing a kiosk-like application for tablets running Windows 8 Pro (on desktop mode). The user shouldn't be able to access anything that isn't the application itself: charms will be disabled, the taskbar will be hidden behind the application, etc.
This also means the user shouldn't be able to change network settings, leaving the responsability to keep the device always connected to us. Up to now, I had success using the Mobile Broadband API to assure the device is connected whenever there's a mobile network available. It'll detect disconnect events and try to connect again.
The Problem
Although the user shouldn't be able to do it, I'm considering the case where the user follows this steps:
User opens right-side charm,
clicks on Settings,
clicks on Network,
clicks on More PC Settings,
clicks on Wireless, and
disables the mobile broadband device.
I would like to be able to revert this programmatically and enable it again.
The Attempts
I have tried some different ways to force 3G being reenabled. Most of them give me the same result: they supposedly enable the device without errors, but I still cannot use it. Enable-NetAdapter in Powershell doesn't throw errors, and the Enable method of Win32_NetworkAdapter appears to work, but no dice.
I thought maybe the method IMbnRadio::SetSoftwareRadioState could be what I'm after, but I can't get to it when the device is disabled. The method IMbnInterfaceManager::GetInterfaces throws a COMException claiming the element could not be found (HRESULT = 0x80070490).
MbnInterfaceManager mbnInterfaceManager = new MbnInterfaceManager();
IMbnInterfaceManager interfaceManager = (IMbnInterfaceManager)mbnInterfaceManager;
// The following line throws a COMException:
IMbnInterface[] interfaces = (IMbnInterface[])interfaceManager.GetInterfaces();
mobileInterface = interfaces[0];
mobileRadio = (IMbnRadio)mobileInterface;
uint requestId;
mobileRadio.SetSoftwareRadioState(MBN_RADIO.MBN_RADIO_ON, out requestId);
Is there a way to override user preferences set on "More PC Settings?"
I found a sketchy way to solve this. Keep in mind this is undocumented, wrong, shameless and immoral, and will probably break eventually. The client is aware of this, but prefers to keep the access to the OS limited.
The setting in case is saved in the Registry. At least in the computers I've checked, it's stored in HKLM\SYSTEM\CurrentControlSet\Control\Class\{4d36e972-e325-11ce-bfc1-08002be10318}\0022 in a key named RadioOff.
The Airplane Mode setting is also stored in the Registry, but in a different place. It's at HKLM\SYSTEM\CurrentControlSet\Control\RadioManagement\SystemRadioState in a key named (Default).
After changing these keys and rebooting, everything seems to work fine. I'll repeat though: you really shouldn't be doing this, especially the Airplane Mode thing.

Getting the current device time

I'm using WIA (Windows Image Acquisition) to grab photos from a camera. Using WIA 2.0, .net 4 C#, my test device is a Nikon D90 (yup, I have it actually plugged in). So the scenario is:
User has camera plugged into PC
User takes a photo from the camera itself
My application downloads the image via WIA
All of the above is working.
The problem I'm having is getting the current time from the device itself. The first time I get the time from the device I get the correct time, all good. If I run my application again, WIA seems to cache the time I got earlier and returns that, which is useless.
// use the WIA.DeviceManager to get the deviceInfo (not shown)
var device = deviceInfo.Connect();
var prop = device.Properties["Device Time"];
Vector deviceTimeVector = (Vector)prop.get_Value();
var deviceTime = deviceTimeVector.Date;
Does anyone who's done some work with WIA know how to reliably get the current time from a device? I've tried a synchronise but this doesn't seem to have any effect.
_device.ExecuteCommand(WIA.CommandID.wiaCommandSynchronize);
Open to suggestions too. I was thinking my only other way would be to "calibrate" the device by taking a test shot, checking what the time taken of that picture was but there's problems with this too.
Please let me know if you need any information.

Categories

Resources