How to add AdMob ads? - java

I've been following this tutorial (http://www.kilobolt.com/day-7-creating-an-android-game-from-start-to-finish.html) for creating an Android game. Now I would like to add AdMob ads to the game in GameScreen Class inside private void drawGameOverUI() {...}.
I got the context from SampleGame Class using
private static Context context;
public Screen getInitScreen() {
SampleGame.context = getApplicationContext();
...
}
public static Context getAppContext() {
return SampleGame.context;
}
In GameScreen Class inside private void drawGameOverUI() I have this
contextGameScreen = SampleGame.getAppContext();
LinearLayout layout = new LinearLayout(contextGameScreen);
adView = new AdView(contextGameScreen, AdSize.BANNER, "...");
layout.addView(adView);
adView.loadAd(new AdRequest());
but I got this error "Cannot resolve constructor 'AdView(android.content.Context, com.google.ads.AdSize, java.lang.String)'" for (contextGameScreen, AdSize.BANNER, "...");.
On Google Developers (https://developers.google.com/mobile-ads-sdk/docs/admob/fundamentals#android) they use 'this', but when I use (this, AdSize.BANNER, "..."); I got the error "Cannot resolve constructor 'AdView(com.name.GameScreen, com.google.ads.AdSize, java.lang.String)'".
Can you please help me with this, how to solve this error, and to get this to work? This means alot to me. And also what exactly is 'this'?

Your problem is that contextGameScreen in
new AdView(contextGameScreen, AdSize.BANNER, "...")
is not an instance of android.content.Context. Eg an Activity or an Application.
It is very hard to work out exactly what you are doing as you have only provided disconnected scraps of code, but what you need to do is to provide the AdView constructor the Activity in which in will be embedded.

Related

Android 11: Tried to access UI constants from a non-visual Context

I was running project OnmiNotes on Github when I ran, and looking at Logcat, the result was an error: "Tried to access UI constants from a non-visual Context", I found out that this is a new error on android 11, and there are quite a few suggestions to correct this error on gg, I look at them, those cases are not suitable for my case. And the person who wrote this app wrote on android 8, so they probably didn't know this error. Below are the code lines I find relevant.
There is an error in Logcat:
Tried to access UI constants from a non-visual
Context:it.feio.android.omninotes.OmniNotes#e9ea0eUI constants, such as
display metrics or window metrics, must be accessed from Activity or
other visual Context. Use an Activity or a Context created with
Context#createWindowContext(int, Bundle), which are adjusted to the
configuration and visual bounds of an area on screen
and:
Tried to access visual service WindowManager from a non-visual Context:it.feio.android.omninotes.OmniNotes#e9ea0e Visual services, such as WindowManager, WallpaperService or LayoutInflater should be accessed from Activity or other visual Context. Use an Activity or a Context created with Context#createWindowContext(int, Bundle), which are adjusted to the configuration and visual bounds of an area on screen.
And there are two command lines I see mentioned in logcat error
1.In BaseActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
// Forces menu overflow icon
try {
ViewConfiguration config = ViewConfiguration.get(this.getApplicationContext()); //ERROR IN LOGCAT IN THIS LINE
#SuppressLint("SoonBlockedPrivateApi") Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
if (menuKeyField != null) {
menuKeyField.setAccessible(true);
menuKeyField.setBoolean(config, false);
}
} catch (Exception e) {
LogDelegate.w("Just a little issue in physical menu button management", e);
}
super.onCreate(savedInstanceState);
}
MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);//ERROR IN LOGCAT IN THIS LINE
setTheme(R.style.OmniNotesTheme_ApiSpec);
binding = ActivityMainBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
EventBus.getDefault().register(this);
Prefs.getPreferences().registerOnSharedPreferenceChangeListener(this);
initUI();
if (IntroActivity.mustRun()) {
startActivity(new Intent(getApplicationContext(), IntroActivity.class));
}
}
Does anyone know how to deal with it? Any help will be appreciated.
Replace this.getApplicationContext() and getApplicationContext() with this. this appears to be an Activity in both places.

Activity Instance does not exist- null object reference

I am trying to develop an Android application. For my use case I want to use a custom typeface and I wrote a that gathers all available TextViews in a View, so that I can set the typeface easily by a loop. I thought I should source out the text manipulation things to an own class named TextManager.class . But now when I am executing the app I am getting an error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference
It occurs when I am trying to set Typeface in TextMangaer.class . I did a bit of research and found out that it is because the activity instance does not exist at this point. But I don't get it why, cause when I am trying to do this in Start.class there is no problem.
//Start.class
public class Start extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // set fullscreen
//Initialize shared preferences
prefs = getSharedPreferences("User", Context.MODE_PRIVATE);
editor=prefs.edit();
setContentView(R.layout.start_screen);
TextManager textManager= new TextManager();
textManager.setTypeface(getTextViews((ViewGroup) findViewById(R.id.root_menu)));
}
}
and my TextManager.class:
public class TextManager extends Start{
public TextManager(){
super();
}
public void setTypeface(List<Integer> idsOfTextViews){
Typeface typeFaceIkarosLight= Typeface.createFromAsset(getAssets(), "font/ikaros_light.otf");
for(int i=0; i < idsOfTextViews.size();i++){
((TextView)findViewById(idsOfTextViews.get(i))).setTypeface(typeFaceIkarosLight);
}
}
}
So how could I fix this or how should I write this? If anybody could help me figure it out that would be great. Thanks in advance.
Problem is context is null for getting assets.
Use getContext() or getApplicationContext() in case of being used in an activity but if it is being used in a fragment then use getActivity().getContext()
Typeface font = Typeface.createFromAsset(getContext().getAssets(), "font/ikaros_light.otf");
Instead of
Typeface typeFaceIkarosLight= Typeface.createFromAsset(getAssets(), "font/ikaros_light.otf");
Its better to make method which return typeface instead passing textview ids as an argument. you can do it like this :
public Typeface getTypeFace(Context context){
Typeface typeFaceIkarosLight = Typeface.createFromAsset(context.getAssets(), "font/ikaros_light.otf");
return typeFaceIkarosLight;
}
If you want to use custom fonts then you can take this example
This tutorial will show you how to set custom font on TextView, EditText and on Button.
http://androiderstack.com/index.php/2017/08/14/use-custom-font-in-textview-edittext-and-button-in-android/
This will surely help you

Android Banner Ads Example; Unknown Package 'R'

So I am trying to get ads to work for my first Android ap, I am following the Google developers tutorial found here: https://developers.google.com/mobile-ads-sdk/docs/admob/fundamentals
Thus my code looks like what it looks like in the example:
package com.google.example.gms.ads.banner;
import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdSize;
import com.google.android.gms.ads.AdView;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
/**
* A simple {#link Activity} that embeds an AdView.
*/
public class BannerSample extends Activity {
/** The view to show the ad. */
private AdView adView;
/* Your ad unit id. Replace with your actual ad unit id. */
private static final String AD_UNIT_ID = "TO_BE_DISCOVERED_SHORTLY";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an ad.
adView = new AdView(this);
adView.setAdSize(AdSize.BANNER);
adView.setAdUnitId(AD_UNIT_ID);
// Add the AdView to the view hierarchy. The view will have no size
// until the ad is loaded.
LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
layout.addView(adView);
// Create an ad request. Check logcat output for the hashed device ID to
// get test ads on a physical device.
AdRequest adRequest = new AdRequest.Builder()
.addTestDevice(AdRequest.DEVICE_ID_EMULATOR)
.addTestDevice("INSERT_YOUR_HASHED_DEVICE_ID_HERE")
.build();
// Start loading the ad in the background.
adView.loadAd(adRequest);
}
#Override
public void onResume() {
super.onResume();
if (adView != null) {
adView.resume();
}
}
#Override
public void onPause() {
if (adView != null) {
adView.pause();
}
super.onPause();
}
/** Called before the activity is destroyed. */
#Override
public void onDestroy() {
// Destroy the AdView.
if (adView != null) {
adView.destroy();
}
super.onDestroy();
}
}
However, when I compile this I get the following errors:
BannerSample.java:25: error: package R does not exist
setContentView(R.layout.activity_main);
^
BannerSample.java:34: error: package R does not exist
LinearLayout layout = (LinearLayout) findViewById(R.id.linearLayout);
^
2 errors
I suspect the solution to my answers may be incredibly simple, but I'm not sure where these Rs are suppose to come from and the tutorial doesn't say anything about it. Help?
I am compiling using this javac command:
javac -cp ".;android.jar;google-play-services.jar" BannerSample.java
Every time you compile your Android project (if you are working on eclipse at least) the R package gets deleted and then gets rebuild. This error is pretty common and it means that you have an error in your code that stopped the building process and so also the creation of the R package.
If it worked before then try identifying at which time did it stop working and analyze the code that caused it not to compile so to find the error. Normally the error is in the XML layout file that prevented the application from being built
It may be that your problem is caused by a different reason, but in every case that that I've seen that this problem is present, the cause is always a compilation error.
Happy hunting :)
edit:
Check out this answer, it may contain just the info you need

Admob integration failing thread to work properly on AndEngine based app

I'm building an android game powered by AndEngine game framework.
I'm using the following code to inegrate with Admob:
#Override
protected void onSetContentView() {
mRenderSurfaceView = new RenderSurfaceView(this, mEngine);
mRenderSurfaceView.applyRenderer();
setContentView(R.layout.main);
final FrameLayout frameLayout = new FrameLayout(this);
final FrameLayout.LayoutParams frameLayoutLayoutParams =
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
FrameLayout.LayoutParams.FILL_PARENT);
AdView adView = new AdView(this, AdSize.BANNER, "XXXXXXX");
adView.refreshDrawableState();
adView.setVisibility(AdView.VISIBLE);
final FrameLayout.LayoutParams adViewLayoutParams =
new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM);
AdRequest adRequest = new AdRequest();
adRequest.addTestDevice(AdRequest.TEST_EMULATOR);
adRequest.addTestDevice(Secure.ANDROID_ID);
adView.loadAd(adRequest);
final android.widget.FrameLayout.LayoutParams surfaceViewLayoutParams =
new FrameLayout.LayoutParams(super.createSurfaceViewLayoutParams());
frameLayout.addView(this.mRenderSurfaceView, surfaceViewLayoutParams);
frameLayout.addView(adView, adViewLayoutParams);
this.setContentView(frameLayout, frameLayoutLayoutParams);
}
in the game, when a ball is created it makes a fading-in animation
I made with a thread:
new Thread(new Runnable() {
public void run() {
mBody.setType(BodyType.StaticBody);
mSprite.setAlpha(0.0f);
try {
while(mSprite.getAlpha() < 1.0f) {
mSprite.setAlpha(mSprite.getAlpha() + 0.01f);
Thread.sleep(3);
}
mBody.setType(BodyType.DynamicBody);
mBody.setLinearVelocity(new Vector2(0, 10));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
The problem is:
the animation works perfectly, BUT
when I'm adding the Admob code the Sprite appears for a second
and then, just disappearing.
it seems to me there is a problem between this two "chunks" of code.
but I can't put my finger on the solution or even what causing this problem to occur.
I only know that the animation is not working when the Admob code is combined in my app.
I'd like to know why and how to solve it.
thank you guys
This could be completely unrelated, but I had a problem with randomly disappearing Sprites recently, though not connected with Admob. The problem went away when I added the following line to the place where I set the Engine up:
engineOptions.getRenderOptions().disableExtensionVertexBufferObjects();
I recommend you to use an XML file to put your admin. Its cleaner, easy to use and according to my own tests it is faster than overriding onsetcontentview. In order to achieve that you need to extend LayoutGameActivity (there is also a simple version of that class. SimpleLayoutActivity if I'm not wrong)
I'll improve the answer when I get a computer.

Android - How to run intent from JavaScript

I am new to Android and Java. I have constructed an app using HTML/Javascript that is working great.
I now need to create an activity that launches the email client, fills in subject and body, and (the tough part) adds a file attachment. I have not been able to do this from within JavaScript, mailto: will not attach the file.
So I need to accomplish this through Java and execute it from JavaScript. I think this can be done by using addJavaScriptInterface but I cannot find any detailed documentation or examples to go off of.
How could I do this?
Here is what I have so far after reading the documentation:
2nd update to code:
MainActivity.java
public class MainActivity extends DroidGap {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setIntegerProperty( "splashscreen", R.drawable.splash );
super.loadUrl("file:///android_asset/www/index.html", 1000);
WebView mWebView;
mWebView = (WebView)findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new JavaScriptInterface(), "Android");
}
}
JavaScriptInterface.java
public class JavaScriptInterface {
public void doEmail(){
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/html");
sendIntent.putExtra(android.content.Intent.EXTRA_TEXT,"test text");
sendIntent.putExtra(Intent.EXTRA_SUBJECT,"test subject");
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.putExtra(Intent.EXTRA_STREAM,Uri.parse("file://test co.html"));
startActivity(Intent.createChooser(sendIntent, "Send email..."));
}
}
Then I would reference the intent through JavaScript by using Android.doEmail().
With the above code I am getting 2 errors in Eclipse
1. The method startActivity(Intent) is undefined for the type - JavaScriptInterface
2. webview cannot be resolved or is not a field - MainActivity
What am I doing wrong?
This documentation tells you exactly how to do it.
It looks like there are three main steps:
Create your 'interface' class in Android
Add an instance of this 'interface' to the WebView you are using.
Call the interface from your JavaScript.
public class MainActivity extends DroidGap {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setIntegerProperty( "splashscreen", R.drawable.splash );
JavaScriptInterface jsi = new JavaScriptInterface(this, appView);
appView.addJavascriptInterface(jsi, "Android");
super.loadUrl("file:///android_asset/www/index.html", 1000);
}
}
and
public class JavaScriptInterface {
private WebView mAppView;
private DroidGap mGap
public JavaScriptInterface (DroidGap gap, WebView view)
{
mAppView = view;
mGap = gap;
}
public void doEmail(){
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/html");
sendIntent.putExtra(android.content.Intent.EXTRA_TEXT,"test text");
sendIntent.putExtra(Intent.EXTRA_SUBJECT,"test subject");
sendIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.putExtra(Intent.EXTRA_STREAM,Uri.parse("file://test co.html"));
startActivity(Intent.createChooser(sendIntent, "Send email..."));
}
}
Using addJavaScriptInterface will extend the DOM inside the embedded browser, and allow JS to access a Java object, which is exactly what you want.
There are too many steps to outline here, that have already been documented. This link has a good overview.
I used WebIntents from Boris Smus (http://smus.com/android-phonegap-plugins) and it works like a charm. You can also peruse his code a little to understand better the approach he took with plugins.
NOTE: you do need to update the code provided as is a little (see comments) and the plugin architecture has changed a little.

Categories