I would like to create a CustomEventBanner but have some questions. Im not sure if I do the right things at the right place. Where should I add the Banner to my layout? Do I have to call every method of the CustomEventBannerListener? Which are those which are absolutly necessary? How do I know if there is no Ad to display (no anouncer)??
I actually can display Ad with admob but not using my CustomAd :(
Here is my code:
public class CustomAd implements CustomEventBanner, AdResponseHandler {
private CustomEventBannerListener bannerListener;
protected SASBannerView mBannerView;
#Override
public void requestBannerAd(final CustomEventBannerListener listener,
final Activity activity, String label, String serverParameter,
AdSize adSize, MediationAdRequest mediationAdRequest, Object extra) {
// Keep the custom event listener for use later.
this.bannerListener = listener;
// Determine the best ad format to use given the adSize. If the adSize
// isn't appropriate for any format, an ad will not fill.
// Create banner instance
mBannerView = new SASBannerView(activity);
// Set the listener to register for events.
this.mBannerView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
listener.onClick();
} catch (Throwable t) {
}
}
});
// Load the ad with the ad request giving an AdResponseHandler
mBannerView.loadAd(42295, "286177", 18008, true, "", this);
}
#Override
public void destroy() { // The destroy method gets called when the mediation
// framework refreshes
// and removes the custom event. Perform any necessary cleanup here.
if (this.mBannerView != null) {
this.mBannerView.onDestroy();
}
}
#Override
public void adLoadingCompleted(SASAdElement arg0) {
this.bannerListener.onReceivedAd(this.mBannerView);
}
#Override
public void adLoadingFailed(Exception arg0) {
this.bannerListener.onFailedToReceiveAd();
}
}
The code looks pretty good. Though your banner doesn't seem to be doing anything on click other than notifying onClick(). If you're banner ends up hitting an external web browser or the play store, you can also call onPresentScreen() and onLeaveApplication() in the onClickListener.
Note that this is just the Custom Event component of your app to implement the SAS network. Your main activity still needs to create an AdView (with a mediation ID set up to target your custom event) and load an ad into it.
Only the onReceivedAd and onFailedToReceiveAd are absolutely necessary for mediation to run. The others are useful so that your main AdView's AdListener can listen for these events.
Related
So I'm trying to call a dialogFragment, it works perfectly until I call the onDismiss function from the activity to make an action...
I got a dialog fragment in the hangman game which says if you won or loose, there is a button in the dialog which says if "try again" or "next word", in case you won or loose,
it looks like this:
When the client clicks one of these buttons the dialog will disappear and a new word should appear and reset everything except the word if won...
So I've tried to set onDismiss listener to the dialogFragment inside the activity where the current game is running, but instead of setting dismiss listener, the app crashes with this error:
java.lang.IllegalStateException: Fragment already added: WonDialogFragment{db6bbec}
here is the code where I call the dialogFragment:
// in case the user won
if (isWon) {
// Disable all the buttons immediately.
setEnabledToEachButton(false);
// check if there is already a dialog.
if (!dialogFragment.isAdded() && !dialogFragment.isVisible()) {
// show the dialog
dialogFragment.show(getSupportFragmentManager(), WonDialogFragment.WON_TAG);
dialogFragment.onDismiss(new DialogInterface() {
#Override
public void cancel() {
}
#Override
public void dismiss() {
currentIndex++;
nextWordOrTryAgain();
updateTextView();
}
});
}
}
if I should provide more information to solve my problem let me know...
thank you for your time.
onDismiss is a lifecycle method of DialogFragment. You are not supposed to call it.
You have 2 options,
Try to use the OnDismissListener:
dialogFragment.getDialog().setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialogInterface) {
currentIndex++;
nextWordOrTryAgain();
updateTextView();
}
}
Or to Create a custom listener interface:
public interface DialogDismissed {
void onDialogDismissed();
}
Inside you dialog, have a setter and keep the listener interface:
public void setListener(DialogDismissed listener) {
mListener = listener;
}
When you call dismiss() inside you dialog use:
if (mListener != null) {
mListener.onDialogDismissed()
}
And when creating the Dialog, set the listener:
dialogFragment.setListener(new DialogDismissed {
#Override
void onDialogDismissed() {
currentIndex++;
nextWordOrTryAgain();
updateTextView();
}
});
I'm mainly using mapbox in my projet, but in one instance, I need to display the map in the recyclerView. To do so, I thought of using MapSnapshotter instead of the static Map Api since the user may not have connection.
Unfortunately, when doing my testing, I can't get the MapSnapshotter.callback working properly. Sometime the image is loaded/created and other time it's not, and it does feel to be random.
Mapbox.getInstance(this, MyMapbox.getToken());
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(MapboxMap mapboxMap) {
map = mapboxMap;
MapSnapshotter.Options options = new MapSnapshotter.Options(mapView.getMeasuredWidth(),mapView.getMeasuredHeight());
options.withRegion(mapboxMap.getProjection().getVisibleRegion().latLngBounds);
options.withStyle(mapboxMap.getStyleUrl());
MapSnapshotter mapSnapshotter = new MapSnapshotter(getContext(), options);
mapSnapshotter.start(new MapSnapshotter.SnapshotReadyCallback() {
#Override
public void onSnapshotReady(MapSnapshot snapshot) {
Log.i(LOG_TAG, "onSnapshotReady");
Bitmap bitmap = snapshot.getBitmap();
imageview.setImageBitmap(bitmap);
}
}, new MapSnapshotter.ErrorHandler() {
#Override
public void onError(String error) {
Log.i(LOG_TAG, error);
}
});
}
});
So after some twisting, I finally figure it out. The issue, was that MapSnapshotter.start is a Async task and since the phone is loading 3 items in the recycler view when first launched and in turn, each one of the item is calling the MapSnapshotter.start in the same thread before the previous one is done, so canceling it. This explain why only the last item has is image loaded.
A way to solve this issue is to make the Async task become Sync, but I don't recommande this solution.
The others way is add a property MapSnapshotter in your Adapter. Doing so, each of yours items will have is own MapSnapshotter.
I want to pass some credentials data after user 'log in'/'sign in' from my android application to libgdx game.
Firsly I want to ask you - is it good practice to just start my game using the intent?
I have declared my start activity in manifest.xml file as .LoginActivity (for example), and then after user do some action - android side is starting the game using next code:
private void initializeListeners(){
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getBaseContext(), AndroidLauncher.class);
startActivity(intent);
}
});
}
Is there some best practices how do I start my game from activity ?
Another question related is - how do I pass data from android acitivity to libgdx game?
I saw some suggestions at this link: https://github.com/libgdx/libgdx/wiki/Interfacing-with-platform-specific-code .
I am not using Swarm framework yet(maybe later) and I want to use my own interfaces to pass the data in to the game.
I have declared next interface:
public interface DataPasser {
void passData(String userName);
}
And implement it inside Screen implementation inside core part of the game, smth like this:
#Override
public void passData(String userName) {
font.draw(batch, userName, 0, 450);
}
I just draw a string with passed data.
The main problem is - when should I call this method inside my android part?
I am calling the Intent and game is starting without passed data inside the intent - that's why I asking - what's the best way to start the game.
How should I pass the data and start the game - suggest something please.
you didn't have much code, so a lot of this is general tips.
In the core module you add a constructor with the arguments you want (the LibGDX game itself, assuming you used the project generator).
You add a constructor where you take in two strings: username and password.
You use Intent to pass the data from one activity to the game activity, and the game activity sends the Strings to the constructor of the game.
write your android activity here and pass userName in constructor.
class AndroidLauncher : AndroidApplication() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = AndroidApplicationConfiguration()
//pass your name here
mainClass = ApplicationCore("username");
initialize(mainClass, config);
}
/*
* all stuff code
*/
}
this is your core mainClass.
public class ApplicationCore extends ApplicationAdapter {
public String userName;
public ApplicationCore(String userName) {
this.userName=userName;
// use this username whenever you want.
}
#Override
public void create() {
initGame();
}
private void initGame() {
//write code for initialize
}
#Override
public void render() {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//render functionalities
}
#Override
public void dispose() {
batch.dispose();
}
#Override
public void resume() {
super.resume();
}
#Override
public void pause() {
super.pause();
}
}
When returning to an activity using the back button and
startActivity(new Intent(this, ActivityMainMenu.class));
is called, are there any methods that automatically go to a custom view?
I've noticed that when going back to the view, it's no longer invalidated.
Basically without using the activity's onResume I want to be able to resume my custom view.
For anyone else who wants to know you can use:
protected void onAttachedToWindow()
It's called every time a view is attached to the Window.
In the Android Source for TextView, it posts a Runnable.
if (ss.error != null) {
final CharSequence error = ss.error;
// Display the error later, after the first layout pass
post(new Runnable() {
public void run() {
setError(error);
}
});
}
Right now I have my ApplicationActivity, this activity is responsible for managing multiple views (GLSurfaceViews). Can / Should I have all the views set the renderer to a "global" renderer?
Code:
public class ApplicationActivity extends Activity
{
private static final String TAG = ApplicationActivity.class.getSimpleName();
private final Stack<Screen> screens = new Stack<Screen>();
private GlRenderer glRenderer;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Log.d(TAG, "Main Activity Created");
setupGraphics();
ChangeScreen(new MainMenu(this, glRenderer)); //Creating a new Screen sets the renderer
}
private void setupGraphics()
{
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
glRenderer = new GlRenderer(this);
}
public void Draw() //Is called by the glRenderer onDrawFrame() { mainActivity.Draw() }
{
}
}
Its the same activity switching between GLSurfaceViews and by my knowledge I believe that the method setRenderer sets the view renderer and then starts the rendering thread (creating a new thread) but I don't want to recreate the thread every time I switch between views - may create potential problems.
So in the end I want a Renderer class just to keep graphics sepreate from business logic and such but, I don't know if using one Renderer is even possible, without setting the thread again?
You can only use Multiple Views with the same Renderer only if you properly switch out between them with GLSurfaceView.onPause() / .onResume();
My specific case:
#Override
protected void onPause() //Overrides onPause from Activity
{
surfaceViews.peek().onPause();
super.onPause();
}
So everytime the activity pauses I would have to pause the current View. And if the Activity resumes then resume the View also.
I also have a method called SetView which will either (pause and remove then change to another View) or (pause and then change to another View) this is accomplished using a Stack
public void SetView(View screen)
{
if (!screens.empty())
{
screens.peek().onPause();
screens.pop();
}
screens.push(screen);
setContentView(screens.peek());
}
Of course though because we are using Views instead of Activities now we must Override the onBackPressed() to go back to previous Views.
#Override
public void onBackPressed()
{
if (screens.size() == 1)
super.onBackPressed();
else
{
screens.pop();
setContentView(screens.peek());
screens.peek().onResume();
}
}
By doing new GLRenderer() you create new instance of your class. So there is no problem to have the same renderer used in different activities.
EDIT: I seem to misunderstand your question - if you want many GL surfaces visible at once, then no, it is not possible. But it got nothing to do with reusing renderer code.