How to stop AppOpenAd showing multiple times? (Unity) - ios

I have implemented AppOpenAds from Admob, they work as intended...To a point.
Unfortunately, when the viewer is watching a 'rewarded' video (ie to get coins in-game) after it finishes, it then shows an AppOpenAd, as it obviously thinks the user has left the app (when they have just watched a video instead). So they are getting a double-whammy ad!
Is there any way I can stop this?
It's using this;
private void OnAppStateChanged(AppState state)
{
// Display the app open ad when the app is foregrounded.
UnityEngine.Debug.Log("App State is " + state);
if (state == AppState.Foreground)
{
AppOpenAdManager.Instance.ShowAdIfAvailable();
}
}
Edit - just to clarify - Rewarded ads work, they just then show an AppOpenAd when the rewarded ad finishes due to it thinking I was outside of the app.

Related

Unable to get ReplayKit (w/RPBroadcastActivityViewController) to stream to YouTube live - get "The user declined application recording" error

I'm trying to use ReplayKit to live stream from within an iOS app on iOS 11 and Swift 4. My code succesfully live streams to MobCrush, but when I select YouTube and the broadcast is supposed to get kicked off it fails.
Relevant code:
func broadcastActivityViewController(_ broadcastActivityViewController: RPBroadcastActivityViewController,
didFinishWith broadcastController: RPBroadcastController?,
error: Error?) {
//1
guard error == nil else {
print("Broadcast Activity Controller is not available.")
print("ERROR BROADCASTING: " + error!.localizedDescription)
return
}
//2
broadcastActivityViewController.dismiss(animated: true) {
//3
broadcastController?.startBroadcast { error in
//4
//TODO: Broadcast might take a few seconds to load up. I recommend that you add an activity indicator or something similar to show the user that it is loading.
//5
if error == nil {
print("Broadcast started successfully!")
self.broadcastStarted()
}
}
}
}
It Prints:
Broadcast Activity Controller is not available.
ERROR BROADCASTING: The user declined application recording
Trying to figure out if this is an issue with YouTube or with some permissions/implementation problem on my side.
It's worth noting that ReplayKit streaming clearly does not work for some of the advertised platforms (e.g. Periscope), but I have successfully gotten YouTube ReplayKit to work with some other apps I tested, so it should be possible.
I'm seeing a similar thing.
MobCrush - Works beautifully
Periscope - Stream starts, connects & the entry shows-up in Periscope but the video is blank/inaccessable when you want to view it either live or saved.
Youtube - An error occurs, stopping streaming from starting, yet a Scheduled Livestream entry appears for the live stream you attempted to do. This is scheduled about 8 hours in the past for me. (But I'm sure this value depends on your system clock relative to the US West Coast)
So. It appears only MobCrush seems to have upheld its end of the bargain.

Adobe Air Application - Not in background and not in Foreground - iPhone

I have an adobe air application - AS3 for iOs and Android.
Whenever the user clicks the home button, and thus the application is now in the background, the application automatically stops, which is the expected behavior. Now, if the user is in the application, and he double clicks his home button, showing all the multiple windows, the application continues running, which is not what i want. How can i access that state ( Not Background, not foreground )? If i can access it, i would then put my pausing code into that state, but how can i access that particular state?
When the user clicks the home button the app is moved to the background and suspended. The app isn't closed. The OS can close the app to free memory. If your app is a memory hog you'll see this happening.
You use events dispatched by the NativeApplication object. Below is example code to listen and handle these events.
import flash.events.Event;
import flash.desktop.NativeApplication;
import flash.desktop.SystemIdleMode;
// create listeners to NativeApplication
private var naApplication: NativeApplication;
naApplication = NativeApplication.nativeApplication;
naApplication.addEventListener(Event.ACTIVATE, eActivate);
naApplication.addEventListener(Event.DEACTIVATE, eDeactivate);
naApplication.addEventListener(Event.EXITING, eExiting);
private function eActivate(e: Event): void {
// app has opened or resumed
application.systemIdleMode = SystemIdleMode.KEEP_AWAKE;
}
private function eDeactivate(e: Event): void {
// app is going to be moved to background
application.systemIdleMode = SystemIdleMode.NORMAL;
}
private function eExiting(e: Event): void {
// app is going to be closed by user or by the OS (usually to free up memory)
// do whatever exit code here then remove all listeners (to be clean don't rely on OS to close them)
application.removeEventListener(Event.ACTIVATE, eActivate);
application.removeEventListener(Event.DEACTIVATE, eDeactivate);
application.removeEventListener(Event.EXITING, eExiting);
application.systemIdleMode = SystemIdleMode.NORMAL;
removeEventListener(Event.ENTER_FRAME, eMainTimer);
}
The systemIdleMode and ENTER_FRAME are just examples of typical code. Let me know of any questions.

WinRT - How to Enable "Timed Logout" Feature in Webview or Detect Pointer Pressed/Tapping Event in Webview

I am developing a WinRT app. One of the requirements is that the app should have a "timed logout" feature. What this means is that on any screen, if the app has been idle for 10 mins, the app should logout and navigate back to the home screen.
By using this link and applied the logic given in below link
https://stackoverflow.com/a/18878954/3560390
Its works fine in all screens except webview,because webview not supports any touch event or tap event.
https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.webview.aspx
How to enable "timed logout" feature in WinRT webview ?
Any help is welcome..
Thanks!
Unfortunately, this limitation hasn't been fixed with the improvements to the WebView in Windows 10.
Here are 2 things you can try:
1) When the user navigates to the page, begin your 10 minute timer. After 10 minutes, display a modal dialog with an "OK" button which says something like "Click to continue browsing...". The user then has 10 seconds (or whatever you choose) to click OK. If not, then navigate back to the home screen.
2) The WebView does have working GotFocus and LostFocus events. Perhaps you can use these methods to restart your 10 minute timer.
An Idea
If your WebView is loading content with ms-appx-web, ms-local-stream, or https content (which would require a content URI rule in your appxmanifest) OR if you are using NavigateToString, then you may be able to do something like this:
private void WebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
MyWebView.InvokeScript("eval", new[]
{
"document.addEventListener('mousemove', function(){window.external.notify('MouseMove');});"
});
}
private void MyWebView_ScriptNotify(object sender, NotifyEventArgs e)
{
if( e.Value == "MouseMove" )
{
// Restart timer
}
}

Web Audio API on iOS Safari do not play even after user interaction

I know that there is a limitation in iOS Safari where the audio is not playing until user triggers an interaction. So I have placed the code inside a touchstart event. But unfortunately, I have tried almost every combination, and I couldn't get it to play on iOS Safari.
Here are the things I have tried:
putting the audio load outside the touchstart callback
try adding a gain node
use 0.01 as the start time
and none of the above works in iOS Safari, but they can all play in desktop Chrome and Safari. Here is the link to the gist, you can see the versions where I made the changes (P.S. the click event is used for testing on desktop)
https://gist.github.com/angelathewebdev/32e0fbd817410db5dea1
Sounds play only when currentTime starts to run, but scheduling sounds exactly at currentTime doesn't seem to work. They need to be a little bit into the future (ex: 10ms). You can use the following createAudioContext function to wait until the context is ready to make noise. User action doesn't seem to be required on iPhone, but no such success on iPad just yet.
function createAudioContext(callback, errback) {
var ac = new webkitAudioContext();
ac.createGainNode(); // .. and discard it. This gets
// the clock running at some point.
var count = 0;
function wait() {
if (ac.currentTime === 0) {
// Not ready yet.
++count;
if (count > 600) {
errback('timeout');
} else {
setTimeout(wait, 100);
}
} else {
// Ready. Pass on the valid audio context.
callback(ac);
}
}
wait();
}
Subsequently, when playing a note, don't call .noteOn(ac.currentTime), but do .noteOn(ac.currentTime + 0.01) instead.

Audio and Recording Reuse on iPhone with Monotouch

I just started testing this very simple audio recording application that was built through Monotouch on actual iPhone devices today. I encountered an issue with what seemed to be the re-use of the AVAudioRecorder and AVPlayer objects after their first use and I am wondering how I might could solve it.
Basic Overview
The application consists of the following three sections :
List of Recordings (TableViewController)
Recording Details (ViewController)
New Recording (ViewController)
Workflow
When creating a recording, the user would click the "Add" button from the List of Recordings area and the application pushes the New Recording View Controller.
Within the New Recording Controller, the following variables are available:
AVAudioRecorder recorder;
AVPlayer player;
each are initialized prior to their usage:
//Initialized during the ViewDidLoad event
recorder = AVAudioRecorder.Create(audioPath, audioSettings, out error);
and
//Initialized in the "Play" event
player = new AVPlayer(audioPath);
Each of this work as intended on the initial load of the New Recording Controller area, however any further attempts do not seem to work (No Audio Playback)
The Details area also has a playback portion to allow the user to playback any recordings, however, much like the New Recording Controller, playback doesn't function there either.
Disposal
They are both disposed as follows (upon exiting / leaving the View) :
if(recorder != null)
{
recorder.Dispose();
recorder = null;
}
if(player != null)
{
player.Dispose();
player = null;
}
I have also attempted to remove any observers that could possible keep any of the objects "alive" in hopes that would solve the issue and have ensured they are each instantiated with each display of the New Recording area, however I still receive no audio playback after the initial Recording session.
I would be happy to provide more code if necessary. (This is using MonoTouch 6.0.6)
After further investigation, I determined that the issue was being caused by the AudioSession as both recording and playback were occurring within the same controller.
The two solutions that I determined were as follows:
Solution 1 (AudioSessionCategory.PlayAndRecord)
//A single declaration of this will allow both AVAudioRecorders and AVPlayers
//to perform alongside each other.
AudioSession.Category = AudioSessionCategory.PlayAndRecord;
//Upon noticing very quiet playback, I added this second line, which allowed
//playback to come through the main phone speaker
AudioSession.OverrideCategoryDefaultToSpeaker = true;
Solution 2 (AudioSessionCategory.RecordAudio & AudioSessionCategory.MediaPlayback)
void YourRecordingMethod()
{
//This sets the session to record audio explicitly
AudioSession.Category = AudioSessionCategory.RecordAudio;
MyRecorder.record();
}
void YourPlaybackMethod()
{
//This sets the session for playback only
AudioSession.Category = AudioSessionCategory.MediaPlayback;
YourAudioPlayer.play();
}
For some additional information on usage of the AudioSession, visit Apple's AudioSession Development Area.

Resources