MoPub initialization with SdkInitializationListener - mopub

I like to initialize MoPub SDK in Android and continue loading banners and interstitials only if SDK init is complete and successful.
What can be a good way to accomplish this?

create a variable listner :
private SdkInitializationListener Listner2;
then put this code inside your oncreate :
final SdkConfiguration.Builder configBuilder = new SdkConfiguration.Builder("24534e1901884e398f1253216226017e");
configBuilder.withLogLevel(DEBUG);
Listner2 = new SdkInitializationListener() {
#Override
public void onInitializationFinished() {
Log.d("MoPub", "SDK initialized");
mInterstitial.load();
}
};
MoPub.initializeSdk(this, configBuilder.build(), Listner2);
The code above load test interstitial if SDK init is complete and successful.

Very easy to accomplish with Android's new Livedata objects. There objects are observable and you can receive their changes wherever you want in your app.
Technology and patterns used:
Livedata
Singleton pattern
MoPub SDK 5.11.1
I will show you how by code snippets
Singleton pattern
public class MoPubSdk {
private static MoPubSdk INSTANCE;
public static MoPubSdk getInstance(Activity activity) {
if(MoPubSdk.INSTANCE == null) {
MoPubSdk.INSTANCE = new MoPubSdk(activity);
}
return MoPubSdk.INSTANCE;
}
}
Constructor with SdkInitializationListener function
Note the MutableLiveData object that changes it's value to true (isInitialized) when the listener is called and the MoPub SDK is ready to call ads. Also see the showConsentIfNeeded function which you can see in the next code block. Just comment the function if not needed.
public class MoPubSdk {
private final MutableLiveData<Boolean> isMoPubSdkInitialized = new MutableLiveData<>();
private Activity mActivity;
private MoPubSdk(Activity activity) {
this.mActivity = activity;
SdkConfiguration sdkConfiguration = new SdkConfiguration.Builder("ANYadunitID")
.withLogLevel(BuildConfig.DEBUG ? MoPubLog.LogLevel.DEBUG : MoPubLog.LogLevel.NONE)
.build();
MoPub.initializeSdk(activity, sdkConfiguration, initSdkListener());
}
private SdkInitializationListener initSdkListener() {
return new SdkInitializationListener() {
#Override
public void onInitializationFinished() {
/* MoPub SDK initialized.
Check if you should show the consent dialog here, and make your ad requests. */
Log.d("MoPub", "SDK initialized");
isMoPubSdkInitialized.setValue(true);
showConsentIfNeeded();
}
};
}
public LiveData<Boolean> isMoPubSdkInitialized() {
return isMoPubSdkInitialized;
}
}
Optional consent Dialog
private void showConsentIfNeeded() {
PersonalInfoManager mPersonalInfoManager = MoPub.getPersonalInformationManager();
Log.d("customeee", "Can collect pers information? "+MoPub.canCollectPersonalInformation()
+ ".\nShould show consent dialog? "+mPersonalInfoManager.shouldShowConsentDialog());
if(!MoPub.canCollectPersonalInformation()) {
if(mPersonalInfoManager.shouldShowConsentDialog()) {
mPersonalInfoManager.loadConsentDialog(new ConsentDialogListener() {
#Override
public void onConsentDialogLoaded() {
mPersonalInfoManager.showConsentDialog();
}
#Override
public void onConsentDialogLoadFailed(#NonNull MoPubErrorCode moPubErrorCode) {
MoPubLog.i("Consent dialog failed to load.");
}
});
}
}
}
So much for initialization. Now let's call the MoPub SDK from an activity and continue with banner loading.
public class MyActivity extends Activity {
private MoPubSdk moPubSdk;
protected void onCreate(final Bundle savedInstanceState) {
moPubSdk = MoPubSdk.getInstance(this);
moPubSdk.isMoPubSdkInitialized().observe(this, new Observer<Boolean>() {
#Override
public void onChanged(Boolean aBoolean) {
if (aBoolean)
//Init your banner here.
}
});
}
}
The LiveData is easy to explain. First time the MoPub SDK initialization begins the Livedata object is false. It takes some time to init, on success the value switches to true and the observer gets called, you can begin banner loading.
On switching activities during init or call MoPubSdk#getInstance another time, the value is already true and gets passed directly on #observe call and you init your banner straight away.

Related

AAC: How return result (handle click) from ViewModel to activity?

I want to use in my project Android Architecture Components (AAC).
Nice.
Here my activity:
import androidx.appcompat.app.AppCompatActivity;
public class TradersActivity extends AppCompatActivity {
private TradersViewModel tradersViewModel;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tradersViewModel = ViewModelProviders.of(this).get(TradersViewModel.class);
tradersViewModel.getIsEnableSwipeProgress().observe(this, new Observer<Boolean>() {
#Override
public void onChanged(Boolean isEnable) {
// do some work with UI
}
});
}
// button click
public void onClickViewJson(Trader trader) {
tradersViewModel.doClickJsonView(trader);
}
}
Here my ViewModel
public class TradersViewModel extends ViewModel {
private MutableLiveData<Boolean> isEnableSwipeProgress = new MutableLiveData<>();
public void doClickJsonView(Trader trader) {
// DO_SOME_COMPLEX_BUSINESS_LOGIC
}
public MutableLiveData<Boolean> getIsEnableSwipeProgress() {
return isEnableSwipeProgress;
}
}
In the screen I has button. And when click this button I call activity's method - onClickViewJson(Trader trader) .
This method call tradersViewModel.doClickJsonView(trader);
In the viewModel this method do some complex business logic.
After method finish it work I need to return result (json) to the my activity.
How I can do this?
Remember that in MVVM, ViewModels have not idea about your view.
Your ViewModel should expose variables so your views can observe and react over them.
private MutableLiveData<Boolean> isEnableSwipeProgress = new MutableLiveData<>();
private MutableLiveData<JSONDto> jsonLiveData = new MutableLiveData<>();
public void doClickJsonView(Trader trader) {
// DO_SOME_COMPLEX_BUSINESS_LOGIC
jsonLiveData.postValue(/* the json you obtain after your logic finish */ )
}
public MutableLiveData<Boolean> getIsEnableSwipeProgress() {
return isEnableSwipeProgress;
}
public LiveData<JSONDto> getJsonDto() {
return this.jsonLiveData;
}
And in your view, you react over your jsonDto changes:
tradersViewModel.getJsonDto().observe(this, new Observer<JSONDto>() {
#Override
public void onChanged(JSONDto json) {
if (json != null) {
// Do what you need here.
}
}
});

Pushing data from one user to another in Vaadin web app

I get the fact that it might take more than 10 lines of code (hopefully not more than 50), but I was wondering if you could help me anyway.
I'm trying to update one user's UI thread at runtime, based on another user's input. I've created a basic project which implements three predefined users (jim, tom and threeskin). I'd like to send a message from jim to tom and have it appear as a new Label object in tom's UI, without threeskin ever knowing about it, even though they're all logged in. Oh, and jim shouldn't have to refresh his page. The label should just spawn on screen out of it's own accord.
To say that I'd appreciate some help would be the understatement of the decade.
public class User {
public String nume;
public User(String nume) {
super();
this.nume = nume;
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
public class Engine implements ServletContextListener {
public static ArrayList<User>userbase;
public void contextDestroyed(ServletContextEvent arg0) { }
public void contextInitialized(ServletContextEvent arg0) {
System.out.println("This code is running at startup");
userbase =new ArrayList<User>();
userbase.add(new User("jim"));userbase.add(new User("tom"));userbase.add(new User("threeskin"));
}
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
public class InfigeUI extends UI {
User us3r;
#WebServlet(value = "/*", asyncSupported = true)
#VaadinServletConfiguration(productionMode = false, ui = InfigeUI.class)
public static class Servlet extends VaadinServlet {}
protected void init(VaadinRequest request) {
VerticalLayout everything=new VerticalLayout();
setContent(everything);
if (us3r==null){everything.addComponent(auth());}else{everything.addComponent(main());}
}
ComponentContainer auth(){
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
TextField userField=new TextField();
Button login = new Button("Log in");
login.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
us3r=login(userField.getValue());
if (us3r!=null){
saveValue(InfigeUI.this, us3r);
layout.removeAllComponents();
layout.addComponent(main());
}else{Notification.show("I only know jim, tom and threeskin. Which one are you?");}}
});
layout.addComponent(userField);
layout.addComponent(login);
return layout;
}
User login(String nume){
for (int i=0;i<Engine.userbase.size();i++){
if (nume.equals(Engine.userbase.get(i).nume)){return Engine.userbase.get(i);}
}
return null;
}
static void saveValue(InfigeUI ui,User value){
ui.us3r=value;
ui.getSession().setAttribute("something", value);
VaadinService.getCurrentRequest().getWrappedSession().setAttribute("something", value);
}
ComponentContainer main(){
VerticalLayout vl=new VerticalLayout();
Label label=new Label("This is the post-login screen");
String name=new String(us3r.nume);
Label eticheta=new Label(name);
TextField to=new TextField("Send to");
TextField message=new TextField("Message");
Button sendNow=new Button("Send now!");
vl.addComponent(eticheta);
vl.addComponent(label);
vl.addComponent(eticheta);
vl.addComponent(to);
vl.addComponent(message);
vl.addComponent(sendNow);
return vl ;
}
}
Basically you want three things
UI updates for a user which does no action himself, or in other words a message sent from the server to the browser. To enable this, you need to annotate the UI class using #Push. Otherwise, the update will only be shown when the user does something which causes a server visit, e.g. clicks a button
Some way of sending messages between UI instances (there is one UI instance per user). You can use some message bus implementation for this (CDI, Spring, ...) or you can make a simple on using a static field (static fields are shared between all users). See e.g. https://github.com/Artur-/SimpleChat for one way of doing it. It's also a good idea here to avoid all *.getCurrent methods as they in many cases will refer to another UI than you think (e.g. sender when you are in the receiver code), and you will do something else than you intend.
Safely update a UI when a message arrives. This is done using UI.access, also visible in the chat example.
First of all you need to enable the server push on your project help
based on Vaadin Documentation.
However, below code example will give what you want:
Create an Broadcast Listener Interface:
public interface BroadcastListener {
public void receiveBroadcast(final String message);
}
The Broadcaster Class:
public class Broadcaster {
private static final List<BroadcastListener> listeners = new CopyOnWriteArrayList<BroadcastListener>();
public static void register(BroadcastListener listener) {
listeners.add(listener);
}
public static void unregister(BroadcastListener listener) {
listeners.remove(listener);
}
public static void broadcast(final String message) {
for (BroadcastListener listener : listeners) {
listener.receiveBroadcast(message);
}
}
}
Your UI with Push Enalbed (via Annotation):
#Push
public class BroadcasterUI extends UI implements BroadcastListener {
#Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
final TextArea message = new TextArea("",
"The system is going down for maintenance in 10 minutes");
layout.addComponent(message);
final Button button = new Button("Broadcast");
layout.addComponent(button);
button.addClickListener(new Button.ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
Broadcaster.broadcast(message.getValue());
}
});
// Register broadcast listener
Broadcaster.register(this);
}
#Override
public void detach() {
Broadcaster.unregister(this);
super.detach();
}
#Override
public void receiveBroadcast(final String message) {
access(new Runnable() {
#Override
public void run() {
Notification n = new Notification("Message received",
message, Type.TRAY_NOTIFICATION);
n.show(getPage());
}
});
}
you can find the full link here.

Windows Phone: how to manage shake events?

The accelerometer is activated (if I set ReadingChanged it works).
Why the shaking event isn't handled?
namespace AppExample
{
public sealed partial class MainPage : Page
{
private Accelerometer accel;
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
accel = Accelerometer.GetDefault();
//accel.ReadingChanged += accel_ReadingChanged;
accel.Shaken += accel_Shaken;
}
void accel_Shaken(Accelerometer sender, AccelerometerShakenEventArgs args)
{
Debug.WriteLine("shaken");
}
}
}
If you mind, there is helper librairy called ShakeGestures to handle shake gestures for windows phone 8. check this question
If you're running Windows Phone 8 , Shaken event won't trigger and does not raise any errors according to MSDN page.
Otherwise it seems like a weird bug to me , I couldn't find any information about it.
You can call the Dispatcher in order to show the result on the main thread.
namespace AppExample
{
public sealed partial class MainPage : Page
{
Accelerometer accel;
public MainPage()
{
this.InitializeComponent();
accel = Accelerometer.GetDefault();
accel.ReadingChanged += accel_ReadingChanged;
accel.Shaken += accel_Shaken;
}
await this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
LabelTest.Text = "Shaken!! " + args.Reading.AccelerationX.ToString();
});
async private void accel_Shaken(object sender, AccelerometerShakenEventArgs e)
{
await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
_shakeCount++;
ScenarioOutputText.Text = _shakeCount.ToString();
});
}
}
}

Android WebView in a ViewSwitcher loadUrl loads once

I have in my ViewSwitcher a ListView and a WebView. In my ListView's adapter, I have an onclick listener that writes the clicked url in the list to sharedpreferences. I'm trying to load that url into the WebView using an onSharedPreferencesChangedListener.
This is the code in my adapter:
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewSwitcher.showNext();
Settings.writeSettings(context, "webviewUrl",
urls.get(position));
}
});
return convertView;
And in the preference listener:
#Override
public void onSharedPreferenceChanged(SharedPreferences pref, String key) {
if (key.equals("webviewUrl")) {
Log.d("TAG", pref.getString(key, null));
WebView wv = (WebView) findViewById(R.id.rss_webview);
wv.getSettings().setJavaScriptEnabled(true);
wv.setWebViewClient(new MyWebViewClient());
wv.loadUrl("about:blank");
wv.loadUrl(pref.getString(key, null));
}
}
This works great except it only works once. The preference listener code logs the correct urls, and the code executes each time I want it to, but wv.loadUrl() method seems to do nothing after the first successful call. Can anyone explain to me why this is happening and perhaps offer a solution? Thanks.
I solved the problem by implementing a static ViewHolder on the WebView whose reference I needed to keep longer than its views' lifecycle.
private static final class WebViewHolder {
WebView wv;
}
#Override
public void onSharedPreferenceChanged(SharedPreferences pref, String key) {
WebViewHolder holder = new WebViewHolder();
if (key.equals("webviewUrl")) {
if (wv == null) {
wv = new WebView(this);
holder.wv = (WebView) findViewById(R.id.rss_webview);
holder.wv.getSettings().setJavaScriptEnabled(true);
holder.wv.setWebViewClient(new MyWebViewClient());
wv.setTag(holder);
} else {
holder = (WebViewHolder) wv.getTag();
}
holder.wv.loadUrl("about:blank");
holder.wv.loadUrl(pref.getString(key, null));
}
}

GWT is making an unexpected event call

My code is below: I am seeing that on running the app the loadWidget method gets invoked even when the adminLink is not clicked. This is not want I want, but I'm not sure what is causing the issue. Please advise
public class LoginModule implements EntryPoint {
LoginPopup loginPopup;
private class LoginPopup extends PopupPanel {
public LoginPopup() {
super(true);
}
public void loadWidget(){
System.out.println("I am called 1");
CommonUi cUi = new CommonUi();
//#342 moved code to common area
FormPanel loginForm = cUi.getLoginFormUi();
setWidget(loginForm);
}
}
#Override
public void onModuleLoad() {
//#251 improved login popup ui.
final Anchor adminLink = new Anchor("User Login");
// final Label adminLink = new Label("User Login");
adminLink.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
// Instantiate the popup and show it.
loginPopup = new LoginPopup();
loginPopup.loadWidget();
loginPopup.showRelativeTo(adminLink);
loginPopup.show();
}
});
if(RootPanel.get("admin") !=null)
RootPanel.get("admin").add(adminLink);
}
}
Running Dev Mode, set a breakpoint in that method in your Java IDE, and take a look at the current stack, what code is calling that method. If that is the only code in your app, then this only appears to be invokable from that onClick handlers, so it is a matter of figuring out why that is being invoked.