Flutter, Facebook Audience Network ads banner not showing when enter another screen - flutter

I use this plugin
facebook_audience_network 0.5.0
and I implemented this by this way
class FacebookAd{
static void faceInit() {
FacebookAudienceNetwork.init(
testingId: "xxxxxxx-xxxxx-xxxx-xxxx-xxxxxxxxxx",
);
}
static widget myBanner;
static void showBannerAd() {
myBanner = FacebookBannerAd(
placementId: "xxxxxxxxx_xxxxxxxxxxx",
keepAlive: true,
bannerSize: BannerSize.STANDARD,
listener: (result, value) {
print("Banner Ad: $result --> $value eee");
switch (result) {
case BannerAdResult.ERROR:
print("Error: $value");
break;
case BannerAdResult.LOADED:
print("Loaded: $value");
break;
case BannerAdResult.CLICKED:
print("Clicked: $value");
break;
case BannerAdResult.LOGGING_IMPRESSION:
print("Logging Impression: $value");
break;
}
},
);
}
}
}
and from other classes
return Scaffold(
bottomNavigationBar: FacebookAd.myBanner
)
so in the app, all of screens refer variable "myBanner" to show banner inside "bottomNavigationBar"
but the problem is when the screen is changed using pushNamed("/xxx")
sometimes the screen showing banner and sometimes not ! (mostly not)
how do I solve this problem this?
thank you

Here is how I was able to solve the FAN interstitials for different pages, unlike the AdMob you should manage the Facebook FAN ads centrally in a separate dart class.
class MyFacebookAdsManager {
static bool isInterstitialAdLoaded = false;
static String adsInterstitialUnitId = '';
static void init(String id) {
logger.i('$prefix init called');
adsInterstitialUnitId = id;
FacebookAudienceNetwork.init(
testingId: '<test-id-if-needed>',
);
loadNewFANInterstitialAd();
}
static void loadNewFANInterstitialAd() {
FacebookInterstitialAd.loadInterstitialAd(
placementId: adsInterstitialUnitId,
listener: (result, value) {
logger.i("$prefix >> FAN > Interstitial Ad: $result --> $value");
switch (result) {
case InterstitialAdResult.LOADED:
isInterstitialAdLoaded = true;
break;
case InterstitialAdResult.DISMISSED:
isInterstitialAdLoaded = false;
loadNewFANInterstitialAd();
break;
case InterstitialAdResult.ERROR:
isInterstitialAdLoaded = false;
logger.e('error loading facebook ads');
loadNewFANInterstitialAd();
break;
default:
}
},
);
}
static void showInterstitialAd() {
if (isInterstitialAdLoaded)
FacebookInterstitialAd.showInterstitialAd();
else
loadNewFANInterstitialAd();
}
}
Now in the main screen you will call the init once and only once.
MyFacebookAdsManager.init('test-id')
Finally, wherever you want to display the Ad, use the class created and show the ad.
MyFacebookAdsManager.showInterstitialAd();
In the same fashion, you should create separate classes and manage All banners & reward videos.

Related

How to disable haptic feedback in showTimePicker()?

In Flutter, if you show a time picker by calling showTimePicker(), it will heavily vibrate when picking the time (in dial mode).
Is there a way to disable the time picker dialogs haptic feedback?
Looking at the source code, you can see that everything related to vibration is private API
void _vibrate() {
switch (Theme.of(context).platform) {
case TargetPlatform.android:
case TargetPlatform.fuchsia:
case TargetPlatform.linux:
case TargetPlatform.windows:
_vibrateTimer?.cancel();
_vibrateTimer = Timer(_kVibrateCommitDelay, () {
HapticFeedback.vibrate();
_vibrateTimer = null;
});
break;
case TargetPlatform.iOS:
case TargetPlatform.macOS:
break;
}
}
void _handleTimeChanged(TimeOfDay value) {
_vibrate();
setState(() {
_selectedTime.value = value;
});
}
So unfortunately, the only clean way is to create your own TimePickerDialog and change that behavior.

SplitButton does not close the dropdownitems once clicked

I am using component SfSplitButton of Blazor Syncfusion version 19.2.48 in razor page as below:
<SfSplitButton Content="Downloads"
Disabled="IsDownloadReportButtonDisabled"
CssClass="mr-2">
<SplitButtonEvents ItemSelected="OnDownloadReportItemSelected"></SplitButtonEvents>
<DropDownMenuItems>
<DropDownMenuItem Id="DownloadTcaReportItem" Text="Download Report"></DropDownMenuItem>
<DropDownMenuItem Id="DownloadTcaConsentReportItem" Text="Download Consent"></DropDownMenuItem>
#if (_isAccountOccupationalHealth)
{
<DropDownMenuItem Id="DownloadTcaSummaryReportItem" Text="Download Summary Report"></DropDownMenuItem>
}
</DropDownMenuItems>
</SfSplitButton>
#code{
private async Task OnDownloadReportItemSelected(MenuEventArgs args)
{
switch (args.Item.Id)
{
case "DownloadTcaReportItem":
//Do some task
break;
case "DownloadTcaSummaryReportItem":
//Do some task
break;
case "DownloadTcaConsentReportItem":
//Do some task
break;
}
}
}
after click on dropdown items still showing in the other pages

Public List In MainActivity and MVVM

I need some help with MVVM architecture.
I have a RecyclerView that receives LiveData and display it perfectly, however, my recyclerView requires another source of Data to customize colors and backgrounds of TextViews. for now I'm using a public list declared in the Mainactivity, But I've read that it's not a good practice.
is it possible to perform a non-live request to database from inside RecyclerView, in order to replace the public list ? if not I would really like some suggestions.
here is my onBindViewHolder:
#Override
public void onBindViewHolder(#NonNull ResultRecyclerViewAdapter.ResultHolder holder, int position) {
Results currentResult = results.get(position);
holder.ston1.setText(currentResult.getSton1());
holder.ston2.setText(String.valueOf(currentResult.getSton2()));
holder.ston1.setBackgroundColor(0xFF12FF45);
holder.ston2.setBackgroundColor(0xFF12FF45);
holder.ston1.getBackground().setAlpha(100);
holder.ston2.getBackground().setAlpha(100);
for (Ston ston: MainActivity.Stons){
if (currentResult.getStonCode().equals(ston.getStonCode()) && currentResult.getStonType().equals(ston.getStonType())){
switch (ston.getStonSelected()) {
case "WADS":
holder.ston1.getBackground().setAlpha(255);
break;
case "WQAS":
holder.ston2.getBackground().setAlpha(255);
break;
}
break;
}
}
holder.ston1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Boolean found = false;
for (Ston ston: MainActivity.Stons){
if (currentResult.getStonCode().equals(ston.getStonCode())){
found = true;
break;
}
}
if (!found) {
holder.ston1.getBackground().setAlpha(255);
MainActivity.Stons.add(new Stons(currentResult.getStonCode(),"WADS",
currentResult.getStonType()));
}
else {
for (Ston ston : MainActivity.Stons) {
if (currentResult.getStonCode().equals(ston.getStonCode()) && ston.getStonSelected().equals("WADS") &&
ston.getStonType().equals(currentResult.getStonType())){
MainActivity.Stons.remove(ston);
holder.ston1.getBackground().setAlpha(100);
break;
}
}
}
}
});
holder.ston2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Boolean found = false;
for (Ston ston: MainActivity.Stons){
if (currentResult.getStonCode().equals(ston.getStonCode())){
found = true;
break;
}
}
if (!found) {
holder.ston2.getBackground().setAlpha(255);
MainActivity.Stons.add(new Stons(currentResult.getStonCode(),"WQAS",
currentResult.getStonType()));
}
else {
for (Ston ston : MainActivity.Stons) {
if (currentResult.getStonCode().equals(ston.getStonCode()) && ston.getStonSelected().equals("WQAS") &&
ston.getStonType().equals(currentResult.getStonType())){
MainActivity.Stons.remove(ston);
holder.ston2.getBackground().setAlpha(100);
break;
}
}
}
}
});
One option that I see is to create new type specifically for your recyclerview adapter that will hold both Results object and information that you use for background alpha. So in your activity (or fragment) when livedata observer is triggered you don't directly pass it to adapter, but first create collection of objects of your new type, and then pass it to adapter. And I strongly suggest you to use Kotlin if possible, there you can use collection mapping to map collection from the db to your new type's collection.

Redirect to another page from DisplayAlert Popup Xamarin.Form

Hey Everyone I am using Autofac(MVVM) my problem is how to redirect to another page from DisplayAlert Popup by clicking ok button in popup screen? As the display alert is in my Views and in my ViewModels the ICommand navigate to another page is navigator.
PushAsync<PageViewModel>();
Some of my Code snip:
ViewModels
public class HomePageViewModel : ViewModelBase
{
private readonly INavigator _navigator;
public HomePageViewModel(INavigator navigator)
{
_navigator = navigator;
CmdInvites = new Command(Cmdinvites);
}
public ICommand CmdInvites { get; private set; }
//Invite PhoneBook
private void Cmdinvites()
{
_navigator.PushAsync<PhoneContactViewModel>();
}
}
zxing.OnScanResult += (result) =>
Device.BeginInvokeOnMainThread(async () => {
// Stop analysis until we navigate away so we don't keep reading barcodes
zxing.IsAnalyzing = false;
// Show an alert
await DisplayAlert("Scanned Barcode", result.Text, "OK");
// Navigate away
await Navigation.PopAsync();
<-------------this is where i want to redirect the {Binding CmdInvites}
});
Thank you for the time reading my post.
You can use another DisplayAlert method constructor which will be like this:
Device.BeginInvokeOnMainThread(async () => {
// Stop analysis until we navigate away so we don't keep reading barcodes
zxing.IsAnalyzing = false;
// Show an alert
if(await DisplayAlert("Scanned Barcode", result.Text, "Accept","Cancel"))
{
// Navigate away
await Navigation.PopAsync();
<-------------this is where i want to redirect the {Binding CmdInvites}
}
});

How can you create a widget inside an android application? (Use App Widget Host class?)

I need to create an application that contains multiple widgets. These are not desktop widgets. I need to be able to interact with these widgets as if they were desktop widgets, but they need to be encased inside a larger application. (Each widget has it's own functionality and behavior when clicked.)
Is this possible in android? Or do I need to create an application and create each object that I'd like to behave like a widget actually as a view?
Ex. The parent app is for a car. Example of "in app" widgets are: oil change history (list of last three oil change dates visible, clicking on a date will open a scan of the receipt, etc.), tire pressure monitor, lap speed history (shows last four laps, pinching and expanding will show more than four), etc.
Can I make each of these objects widgets? Or do they have to be views inside the app?
Edit: The Android developer's App Widget Host page mentions: "The AppWidgetHost provides the interaction with the AppWidget service for apps, like the home screen, that want to embed app widgets in their UI."
Has anyone created their own App Widget Host or worked directly with this class?
Create your appwidget normally
Then in your activity add this code
Call selectWidget() to open popup to pick avaible widget
//init
mAppWidgetManager = AppWidgetManager.getInstance(this);
mAppWidgetHost = new AppWidgetHost(this, R.id.APPWIDGET_HOST_ID);
//select widget
void selectWidget() {
int appWidgetId = this.mAppWidgetHost.allocateAppWidgetId();
Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
addEmptyData(pickIntent);
startActivityForResult(pickIntent, R.id.REQUEST_PICK_APPWIDGET);
}
void addEmptyData(Intent pickIntent) {
ArrayList customInfo = new ArrayList();
pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo);
ArrayList customExtras = new ArrayList();
pickIntent.putParcelableArrayListExtra(AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras);
};
//Configure the widget
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK ) {
if (requestCode == REQUEST_PICK_APPWIDGET) {
configureWidget(data);
}
else if (requestCode == REQUEST_CREATE_APPWIDGET) {
createWidget(data);
}
}
else if (resultCode == RESULT_CANCELED && data != null) {
int appWidgetId = data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
if (appWidgetId != -1) {
mAppWidgetHost.deleteAppWidgetId(appWidgetId);
}
}
}
private void configureWidget(Intent data) {
Bundle extras = data.getExtras();
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
if (appWidgetInfo.configure != null) {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
intent.setComponent(appWidgetInfo.configure);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
startActivityForResult(intent, REQUEST_CREATE_APPWIDGET);
} else {
createWidget(data);
}
}
//adding it to you view
public void createWidget(Intent data) {
Bundle extras = data.getExtras();
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
AppWidgetHostView hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
hostView.setAppWidget(appWidgetId, appWidgetInfo);
layout.addView(hostView);
}
//Update widget
#Override
protected void onStart() {
super.onStart();
mAppWidgetHost.startListening();
}
#Override
protected void onStop() {
super.onStop();
mAppWidgetHost.stopListening();
}
//Now to remove it call this
public void removeWidget(AppWidgetHostView hostView) {
mAppWidgetHost.deleteAppWidgetId(hostView.getAppWidgetId());
layout.removeView(hostView);
}
Hope this helps
If you want to embed a specific widget in your app, and know the package name and class name:
public boolean createWidget(View view, String packageName, String className) {
// Get the list of installed widgets
AppWidgetProviderInfo newAppWidgetProviderInfo = null;
List<AppWidgetProviderInfo> appWidgetInfos;
appWidgetInfos = mAppWidgetManager.getInstalledProviders();
boolean widgetIsFound = false;
for(int j = 0; j < appWidgetInfos.size(); j++)
{
if (appWidgetInfos.get(j).provider.getPackageName().equals(packageName) && appWidgetInfos.get(j).provider.getClassName().equals(className))
{
// Get the full info of the required widget
newAppWidgetProviderInfo = appWidgetInfos.get(j);
widgetIsFound = true;
break;
}
}
if (!widgetIsFound) {
return false;
} else {
// Create Widget
int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
AppWidgetHostView hostView = mAppWidgetHost.createView(getApplicationContext(), appWidgetId, newAppWidgetProviderInfo);
hostView.setAppWidget(appWidgetId, newAppWidgetProviderInfo);
// Add it to your layout
LinearLayout widgetLayout = view.findViewById(R.id.widget_view);
widgetLayout.addView(hostView);
// And bind widget IDs to make them actually work
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
boolean allowed = mAppWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, newAppWidgetProviderInfo.provider);
if (!allowed) {
// Request permission - https://stackoverflow.com/a/44351320/1816603
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, newAppWidgetProviderInfo.provider);
final int REQUEST_BIND_WIDGET = 1987;
startActivityForResult(intent, REQUEST_BIND_WIDGET);
}
}
return true;
}
}