Help please. I have created a script to add a resume funtion for users by seeing an reward base ad from Admob in unity. It works fine when user is online. but performance is too slow (not playable) when user device is in offline mode.
When the script is disable game works fine in both online and offline.
The problem maybe in RequestRewardBasedVideo() funtion.
using System;
using UnityEngine;
using GoogleMobileAds.Api;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class RewardAdResume : MonoBehaviour
{
private string app_id = "....................";
private RewardBasedVideoAd rewardBasedVideo;
public rewdResume RewdResume;
public bool adClosed;
public Text txt2;
public GameObject ops;
public GameObject rw1;
public GameObject rw2;
public GameObject rw3;
public bool opsld;
public GameObject opsLdImg;
// Start is called before the first frame update
void Start()
{
//on publish enable
//MobileAds.Initialize(app_id);
adClosed = false;
opsld = false;
this.RequestRewardBasedVideo();
}
void Update()
{
if (adClosed)
{
if (rewdResume.resumes)
{
txt2.text = adClosed + " Rewarded " + rewdResume.resumes;
RewdResume.resume();
rewdResume.resumes = false;
}
else
{
roverCore.adclosed = true;
}
adClosed = false;
}
if (opsld) {
opsLdImg.GetComponent<Image>().fillAmount += Time.deltaTime * 0.2f;
if (opsLdImg.GetComponent<Image>().fillAmount == 1) {
roverCore.adclosed = true;
ops.SetActive(false);
rw1.SetActive(true);
rw2.SetActive(true);
rw3.SetActive(true);
opsld = false;
}
}
}
private void RequestRewardBasedVideo()
{
string adUnitId = "ca-app-pub-3940256099942544/5224354917";
this.rewardBasedVideo = RewardBasedVideoAd.Instance;
// Called when an ad request has successfully loaded.
rewardBasedVideo.OnAdLoaded += HandleRewardBasedVideoLoaded;
// Called when an ad request failed to load.
rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoFailedToLoad;
// Called when an ad is shown.
rewardBasedVideo.OnAdOpening += HandleRewardBasedVideoOpened;
// Called when the ad starts to play.
rewardBasedVideo.OnAdStarted += HandleRewardBasedVideoStarted;
// Called when the user should be rewarded for watching a video.
rewardBasedVideo.OnAdRewarded += HandleRewardBasedVideoRewarded;
// Called when the ad is closed.
rewardBasedVideo.OnAdClosed += HandleRewardBasedVideoClosed;
// Called when the ad click caused the user to leave the application.
rewardBasedVideo.OnAdLeavingApplication += HandleRewardBasedVideoLeftApplication;
// Create an empty ad request.
AdRequest adRequest = new AdRequest.Builder().AddTestDevice("2077ef9a63d2b398840261c8221a0c9b").Build();
// Load the rewarded video ad with the request.
this.rewardBasedVideo.LoadAd(adRequest, adUnitId);
}
public void UserOptToWatchAd()
{
if (rewardBasedVideo.IsLoaded())
{
roverCore.showChanceTimeout = false;
rewardBasedVideo.Show();
}
else {
ops.SetActive(true);
rw1.SetActive(false);
rw2.SetActive(false);
rw3.SetActive(false);
opsld = true;
//roverCore.adclosed = true;
}
}
#region rewd event
public void HandleRewardBasedVideoLoaded(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoLoaded event received");
}
public void HandleRewardBasedVideoFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
this.RequestRewardBasedVideo();
}
public void HandleRewardBasedVideoOpened(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoOpened event received");
}
public void HandleRewardBasedVideoStarted(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoStarted event received");
}
public void HandleRewardBasedVideoClosed(object sender, EventArgs args)
{
adClosed = true;
}
public void HandleRewardBasedVideoRewarded(object sender, Reward args)
{
rewdResume.resumes = true;
}
public void HandleRewardBasedVideoLeftApplication(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardBasedVideoLeftApplication event received");
}
#endregion
private void OnDisable()
{
// Called when an ad request has successfully loaded.
rewardBasedVideo.OnAdLoaded -= HandleRewardBasedVideoLoaded;
// Called when an ad request failed to load.
rewardBasedVideo.OnAdFailedToLoad -= HandleRewardBasedVideoFailedToLoad;
// Called when an ad is shown.
rewardBasedVideo.OnAdOpening -= HandleRewardBasedVideoOpened;
// Called when the ad starts to play.
rewardBasedVideo.OnAdStarted -= HandleRewardBasedVideoStarted;
// Called when the user should be rewarded for watching a video.
rewardBasedVideo.OnAdRewarded -= HandleRewardBasedVideoRewarded;
// Called when the ad is closed.
rewardBasedVideo.OnAdClosed -= HandleRewardBasedVideoClosed;
// Called when the ad click caused the user to leave the application.
rewardBasedVideo.OnAdLeavingApplication -= HandleRewardBasedVideoLeftApplication;
}
}
rewardBasedVideo.OnAdFailedToLoad += HandleRewardBasedVideoFailedToLoad;
public void HandleRewardBasedVideoFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
this.RequestRewardBasedVideo();
}
When user device is offline, rewarded ad will fail to load almost every sec. So, you will send a lot of requests. That may cause FPS drops.
If i were you, i would start a coroutine for requesting a new rewarded video and wait at least 30 sec. to request a new rewarded ad.
Related
I have an ASP.NET web form application hosted on IIS.
In the app, I have a code snippet that should make some work on the background from the moment the application starts.
The problem is when I have created the singleton class and initialize it from Global.asax ->
Application_Start(), The code runs only when the first user is connecting to the site.
How can I set it to run without any dependency from the user side?
Any Idea?
The singleton class example:
public sealed class SingeltonBackgroundWork
{
private static SingeltonBackgroundWork updater = null;
private static Timer timer;
private SingeltonBackgroundWork()
{
//Milliseconds * Seconds * Minutes
timer = new Timer(1000 * 60 * 10);
timer.Elapsed += new ElapsedEventHandler(OnElapsed);
timer.AutoReset = true;
timer.Enabled = true;
}
private void OnElapsed(object sender, ElapsedEventArgs e)
{
//DO SOME WORK
}
public static void InitProcess()
{
if (updater == null)
{
updater = new SingeltonBackgroundWork();
}
}
}
Global.asax Application_Start():
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
SingeltonBackgroundWork.InitProcess();
}
I need to retrieve the real-time location of the device, I had implement ILocationListener in my Service Class as I want this to run even after the app is in the background or closed I have referred - this
and it seems not working for me even if I change my device location the location change event is not fired
My Service Class with Implemented ILocationListener
[Service]
public class LocationService : Service, ILocationListener
{
public event EventHandler<LocationChangedEventArgs> LocationChanged = delegate { };
public event EventHandler<ProviderDisabledEventArgs> ProviderDisabled = delegate { };
public event EventHandler<ProviderEnabledEventArgs> ProviderEnabled = delegate { };
public event EventHandler<StatusChangedEventArgs> StatusChanged = delegate { };
public LocationService()
{
}
// Set our location manager as the system location service
protected LocationManager LocMgr = Android.App.Application.Context.GetSystemService ("location") as LocationManager;
readonly string logTag = "LocationService";
IBinder binder;
public override void OnCreate ()
{
base.OnCreate ();
Log.Debug (logTag, "OnCreate called in the Location Service");
}
// This gets called when StartService is called in our App class
[Obsolete("deprecated in base class")]
public override StartCommandResult OnStartCommand (Intent intent, StartCommandFlags flags, int startId)
{
Log.Debug (logTag, "LocationService started");
return StartCommandResult.Sticky;
}
// This gets called once, the first time any client bind to the Service
// and returns an instance of the LocationServiceBinder. All future clients will
// reuse the same instance of the binder
public override IBinder OnBind (Intent intent)
{
Log.Debug (logTag, "Client now bound to service");
binder = new LocationServiceBinder (this);
return binder;
}
// Handle location updates from the location manager
public void StartLocationUpdates ()
{
//we can set different location criteria based on requirements for our app -
//for example, we might want to preserve power, or get extreme accuracy
var locationCriteria = new Criteria();
locationCriteria.Accuracy = Accuracy.NoRequirement;
locationCriteria.PowerRequirement = Power.NoRequirement;
// get provider: GPS, Network, etc.
var locationProvider = LocMgr.GetBestProvider(locationCriteria, true);
Log.Debug (logTag, string.Format ("You are about to get location updates via {0}", locationProvider));
// Get an initial fix on location
LocMgr.RequestLocationUpdates(locationProvider, 2000, 0, this);
Log.Debug (logTag, "Now sending location updates");
}
public override void OnDestroy ()
{
base.OnDestroy ();
Log.Debug (logTag, "Service has been terminated");
// Stop getting updates from the location manager:
LocMgr.RemoveUpdates(this);
}
My Binder Class
public class LocationServiceBinder : Binder
{
public LocationService Service
{
get { return this.service; }
} protected LocationService service;
public bool IsBound { get; set; }
// constructor
public LocationServiceBinder (LocationService service)
{
this.service = service;
}
}
public class LocationServiceConnection : Java.Lang.Object, IServiceConnection
{
public event EventHandler<ServiceConnectedEventArgs> ServiceConnected = delegate {};
public LocationServiceBinder Binder
{
get { return this.binder; }
set { this.binder = value; }
}
protected LocationServiceBinder binder;
public LocationServiceConnection (LocationServiceBinder binder)
{
if (binder != null) {
this.binder = binder;
}
}
// This gets called when a client tries to bind to the Service with an Intent and an
// instance of the ServiceConnection. The system will locate a binder associated with the
// running Service
public void OnServiceConnected (ComponentName name, IBinder service)
{
// cast the binder located by the OS as our local binder subclass
LocationServiceBinder serviceBinder = service as LocationServiceBinder;
if (serviceBinder != null) {
this.binder = serviceBinder;
this.binder.IsBound = true;
Log.Debug ( "ServiceConnection", "OnServiceConnected Called" );
// raise the service connected event
this.ServiceConnected(this, new ServiceConnectedEventArgs () { Binder = service } );
// now that the Service is bound, we can start gathering some location data
serviceBinder.Service.StartLocationUpdates();
}
}
// This will be called when the Service unbinds, or when the app crashes
public void OnServiceDisconnected (ComponentName name)
{
this.binder.IsBound = false;
Log.Debug ( "ServiceConnection", "Service unbound" );
}
}
public class ServiceConnectedEventArgs : EventArgs
{
public IBinder Binder { get; set; }
}
My MainActivity
public class MainActivity : Activity
{
readonly string logTag = "MainActivity";
// make our labels
TextView latText;
TextView longText;
TextView altText;
TextView speedText;
TextView bearText;
TextView accText;
#region Lifecycle
//Lifecycle stages
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
Log.Debug (logTag, "OnCreate: Location app is becoming active");
SetContentView (Resource.Layout.Main);
// This event fires when the ServiceConnection lets the client (our App class) know that
// the Service is connected. We use this event to start updating the UI with location
// updates from the Service
App.Current.LocationServiceConnected += (object sender, ServiceConnectedEventArgs e) => {
Log.Debug (logTag, "ServiceConnected Event Raised");
// notifies us of location changes from the system
App.Current.LocationService.LocationChanged += HandleLocationChanged;
//notifies us of user changes to the location provider (ie the user disables or enables GPS)
App.Current.LocationService.ProviderDisabled += HandleProviderDisabled;
App.Current.LocationService.ProviderEnabled += HandleProviderEnabled;
// notifies us of the changing status of a provider (ie GPS no longer available)
App.Current.LocationService.StatusChanged += HandleStatusChanged;
};
latText = FindViewById<TextView> (Resource.Id.lat);
longText = FindViewById<TextView> (Resource.Id.longx);
altText = FindViewById<TextView> (Resource.Id.alt);
speedText = FindViewById<TextView> (Resource.Id.speed);
bearText = FindViewById<TextView> (Resource.Id.bear);
accText = FindViewById<TextView> (Resource.Id.acc);
altText.Text = "altitude";
speedText.Text = "speed";
bearText.Text = "bearing";
accText.Text = "accuracy";
// Start the location service:
App.StartLocationService();
}
protected override void OnPause()
{
Log.Debug (logTag, "OnPause: Location app is moving to background");
base.OnPause();
}
protected override void OnResume()
{
Log.Debug (logTag, "OnResume: Location app is moving into foreground");
base.OnResume();
}
protected override void OnDestroy ()
{
Log.Debug (logTag, "OnDestroy: Location app is becoming inactive");
base.OnDestroy ();
// Stop the location service:
App.StopLocationService();
}
#endregion
#region Android Location Service methods
///<summary>
/// Updates UI with location data
/// </summary>
public void HandleLocationChanged(object sender, LocationChangedEventArgs e)
{
Android.Locations.Location location = e.Location;
Log.Debug (logTag, "Foreground updating");
// these events are on a background thread, need to update on the UI thread
RunOnUiThread (() => {
latText.Text = String.Format ("Latitude: {0}", location.Latitude);
longText.Text = String.Format ("Longitude: {0}", location.Longitude);
altText.Text = String.Format ("Altitude: {0}", location.Altitude);
speedText.Text = String.Format ("Speed: {0}", location.Speed);
accText.Text = String.Format ("Accuracy: {0}", location.Accuracy);
bearText.Text = String.Format ("Bearing: {0}", location.Bearing);
});
}
public void HandleProviderDisabled(object sender, ProviderDisabledEventArgs e)
{
Log.Debug (logTag, "Location provider disabled event raised");
}
public void HandleProviderEnabled(object sender, ProviderEnabledEventArgs e)
{
Log.Debug (logTag, "Location provider enabled event raised");
}
public void HandleStatusChanged(object sender, StatusChangedEventArgs e)
{
Log.Debug (logTag, "Location status changed, event raised");
}
#endregion
}
the above public void HandleLocationChanged(object sender, LocationChangedEventArgs e) {}
never get fired on my device location change
The SeekBar widget is an interactive slider that allows the user to select one value from a range of values. As the user moves the slider left or right, the value of the SeekBar will change
public int getProgressPercentage(int currentDuration, int totalDuration)
{
int percentage;
int currentSeconds = (int)(currentDuration / 1000);
int totalSeconds = (int)(totalDuration / 1000);
//calculating percentage
percentage = (((int)currentSeconds) / totalSeconds) * 100;
return percentage;
}
public void UpdatedTimerTask()
{
//Displaying time
//txtCurrentTimer.Text = utils.miliSecondsTotimer (player.CurrentPosition);
//txtTotalTimer.Text = utils.miliSecondsTotimer (player.Duration);
//Updating progress bar(seekbar)
int progress=(int)(utils.getProgressPercentage(player.CurrentPosition,player.Duration));
seekBar.Progress = progress;
}
void SeekBar_ProgressChanged (object sender, SeekBar.ProgressChangedEventArgs e)
{
UpdatedTimerTask ();
}
public void StartMedia(string url_string)
{
player = new MediaPlayer ();
seekBar.Progress = 0;
seekBar.Max = 100;
player.Reset ();
player.SetAudioStreamType (Stream.Music);
player.SetDataSource(url_string);
player.Prepare();
player.Start ();
imgPlayorPause.SetImageResource (Resource.Drawable.ic_pause_black_36dp);
UpdatedTimerTask ();
}
seekBar.SetOnSeekBarChangeListener (this); has some invalid argument.
SeekBar won't run when media player are playing.
You have two options:
SetOnSeekBarChangeListener()
If you want to use SetOnSeekBarChangeListener you have to implement IOnSeekBarChangeListener in the class of this (usually your activity. The disadvantage of this is, that you can only have one event listener.
[Activity]
public class MyActivity : Activity, SeekBar.IOnSeekBarChangeListener
{
protected override void OnCreate(Bundle bundle)
{
// ...
seekbar.SetOnSeekBarChangeListener(this);
}
public void OnProgressChanged(SeekBar seekBar, int progress, bool fromUser)
{
// do some stuff
}
public void OnStartTrackingTouch(SeekBar seekBar)
{
}
public void OnStopTrackingTouch(SeekBar seekBar)
{
}
}
ProgressChanged Event
Xamarin maps Java methods that are called like SetXyzListener to the event called Xyz.
If you want to use ProgressChanged you have to register your handler with seekbar.ProgressChanged += SeekbarOnProgressChanged. The disadvantage of this is, that you have to ensure to remove the handler with seekbar.ProgressChanged -= SeekbarOnProgressChanged when you do not need the event anymore. You should do this in the counterpart of the lifecycle method where you have added the handler. In the following example I used OnResume and OnPause.
[Activity]
public class MyActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// ...
}
protected override void OnResume()
{
base.OnResume();
seekbar.ProgressChanged += SeekbarOnProgressChanged;
}
protected override void OnPause()
{
seekbar.ProgressChanged -= SeekbarOnProgressChanged;
base.OnPause();
}
private void SeekbarOnProgressChanged(object sender, SeekBar.ProgressChangedEventArgs progressChangedEventArgs)
{
// do some stuff
}
}
I have a problem about scan-period when i'm using android-beacon-library. And here is my problem:
I have three main class: MainActivity, BaseService and BeaconService.
MainActivity: Just do startForeground and stopForeground operation.
BaseService: Do some parameters initialization, BeaconManager and so on.
BeaconService: Beacon operation.
I describe my problems first. I’m using a foreground service to do scan operation and the backgroundScanPeriod is 20l. And i also have a MainActivity with two buttons, startService and stopService. The scan-period is 10s when First time i open the app and click startService.
And then i click HOME and kill this app the service is running normal and the scan-period is 10s also. But when i re-open MainActivity by click the notification on the picture.
The scan-period will become 1s. It's fast for me. But the scan-period would become normal if i click HOME again. That means, the scan-period will become very fast every time except the first time i open the MainActivity.
I wanna know why. And here is my important code below:
MainActivity.class
#OnClick(R.id.start_service)
void start_Service() {
if (Utils.isServiceRunning(MainActivity.this, Constants.CLASSNAME)) {
Toast.makeText(this, "service is running, don't start again", Toast.LENGTH_SHORT).show();
} else {
Intent intent = new Intent(MainActivity.this, BeaconService.class);
intent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
startService(intent);
setInfo();
}
}
#OnClick(R.id.stop_service)
void stop_Service() {
if (Utils.isServiceRunning(MainActivity.this, Constants.CLASSNAME)) {
Intent intent = new Intent(MainActivity.this, BeaconService.class);
intent.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(intent);
setInfo();
} else {
Toast.makeText(this, "service is dead, don't kill again", Toast.LENGTH_SHORT).show();
}
}
BaseService.class
private void setBeaconManager() {
beaconManager.setBackgroundBetweenScanPeriod(20l);
beaconManager.setBackgroundMode(true);
beaconManager.getBeaconParsers().clear();
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout(Constants.BEACON_LAYOUT.COMMON_LAYOUT));
}
BeaconService.class
public class BeaconService extends BaseService implements BootstrapNotifier, BeaconConsumer {
private static final int NOTIFICATION = R.string.notify_service_started;
private static final String TAG = "BeaconService";
private int size = -1;
private RegionBootstrap regionBootstrap;
private BackgroundPowerSaver backgroundPowerSaver;
private Beacon beacon;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
regionBootstrap = new RegionBootstrap(this, region);
beaconManager.bind(this);
backgroundPowerSaver = new BackgroundPowerSaver(getApplicationContext());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null && intent.getAction() != null) {
switch (intent.getAction()) {
case Constants.ACTION.STARTFOREGROUND_ACTION:
startForeground(NOTIFICATION, getNotification());
break;
case Constants.ACTION.STOPFOREGROUND_ACTION:
Log.d(TAG, "Received stop foreground request");
stopForeground(true);
stopSelf();
break;
}
}
return START_STICKY;
}
#Override
public void onDestroy() {
beaconManager.unbind(this);
regionBootstrap.disable();
Log.d(TAG, "service onDestroy");
}
/**
* Called when at least one beacon in a Region is visible.
*
* #param region region
*/
#Override
public void didEnterRegion(Region region) {
// TODO: 3/8/16 reload all the resource
Log.d(TAG, "didEnterRegion called");
L.object(region);
try {
beaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
}
/**
* Called when no beacons in a Region are visible.
*
* #param region region
*/
#Override
public void didExitRegion(Region region) {
// TODO: 3/8/16 close all the resource
Log.d(TAG, "didExitRegion called");
try {
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
e.printStackTrace();
}
beaconManager.unbind(this);
regionBootstrap.disable();
L.object(region);
}
/**
* Called with a state value of MonitorNotifier.INSIDE when at least one beacon in a Region is visible
*
* #param region region
*/
#Override
public void didDetermineStateForRegion(int i, Region region) {
Log.d(TAG, "switch from seeing/not seeing beacons");
L.object(region);
}
#Override
public void onBeaconServiceConnect() {
Log.d(TAG, "onBeaconServiceConnect");
if (null == beaconManager.getRangingNotifier()) {
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Log.d(TAG, "beacons.size():" + beacons.size() + "," + this);
if (beacons.size() != 0) {
Iterator<Beacon> iterator = beacons.iterator();
if (beacons.size() != size) {
saveBeacon(iterator);
size = beacons.size();
}
}
}
});
}
}
/**
* Save beacon p-o-j-o to SQLite.
*/
private void saveBeacon(Iterator<Beacon> iterator) {
while (iterator.hasNext()) {
beacon = iterator.next();
L.object(beacon);
entity.setId(null);
entity.setUuid(beacon.getId1().toString());
entity.setMajor(beacon.getId2().toString());
entity.setMinor(beacon.getId3().toString());
entity.setTxpower(beacon.getTxPower());
entity.setTime(Utils.getCurrentTime());
dbHelper.provideNinjaDao().insert(entity);
Log.d(TAG, "sql save success");
}
}
private Notification getNotification() {
CharSequence text = getText(R.string.notify_service_started);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0);
Notification notification = new Notification.Builder(this)
.setSmallIcon(R.mipmap.ninja_turtle)
.setTicker(text)
.setWhen(System.currentTimeMillis())
.setContentTitle(getText(R.string.info_service))
.setContentText(text)
.setContentIntent(contentIntent)
.build();
return notification;
}
}
Hope you guys can help me. Thanks in advance.
A few points:
There are two different sets of settings for scan period using the Android Beacon Library, foreground and background. When using the BackgroundPowerSaver as shown in the code, the Android Beacon Library automatically switches back and forth between the foreground scan period and the background scan period.
When using the BackgroundPowerSaver, manually setting beaconManager.setBackgroundMode(true) will only have an effect until the next time the app cycles to the foreground -- the BackgroundPowerSaver will change the value of this setting automatically.
The units of the scan periods is milliseconds. So setting beaconManager.setBackgroundBetweenScanPeriod(20l); sets the scan period to be 20 milliseconds. This is way too short to pick up beacons reliably. I recommend a minimum scan period of 1100 ms. The longer the period, the higher probability of detecting a beacon, but the more battery is used.
If you want to wait 10 seconds between scans, you want to set: beaconManager.setBackgroundBetweenScanPeriod(10000l); // 10000 ms = 10.0 secs
If you want the same scan periods to apply both in the foreground and background, simply set them to be the same:
beaconManager.setBackgroundBetweenScanPeriod(10000l);
beaconManager.setForegroundBetweenScanPeriod(10000l);
beaconManager.setBackgroundScanPeriod(1100l);
beaconManager.setForegroundScanPeriod(1100l);
As most of you experienced, developing a console app is as easy as:
void mainloop(){
while (1){
giveInstructions();
getInput();
if (!process()) break;
printOutput();
}
}
int main(){
mainloop();
return 0;
}
However, in GUI it becomes an issue.
We can still giveInstructions(), process(), and printOutput(), but getInput() wouldn't work because it relies on an event, usually button click or key down.
How can I port a console app to a gui app with minimum code changes? (preferably do not change the main method, and as little change to the mainloop function as possible)
Note: I'm not too comfortable with threading yet.
Since there is no specific language given, I will show an example in C# where you would be able to use the same code as the console app with a simple GUI.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//using form-editor, double-click buttons or use the following
btnInput.Click += new EventHandler(btnInput_Click);
btnContinue.Click += new EventHandler(btnContinue_Click);
giveInstructions();
}
private void giveInstructions()
{
txtInfo.Text = "";
txtInput.Text = "";
//display instructions to multi-line textbox
}
private void btnInput_Click(object sender, EventArgs e)
{
//or you can just add another button for exit.
if (txtInput.Text == "expected value for exit")
{
Application.Exit();
}
else
{
getInput();
}
}
private void getInput()
{
string strInput = txtInput.Text;
//do stuff
printOutput();
}
private void printOutput()
{
//display output to multi-line textbox
}
private void btnContinue_Click(object sender, EventArgs e)
{
giveInstructions();
}
}