I found few topics describing similar problems, but not found a solution for memory leaks being created by pretty simple Android app:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cz.reloecc.testBackground"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="10"/>
<application android:label="#string/app_name"
android:icon="#drawable/ic_launcher">
<activity android:name="TestBackgroundActivity"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/ui">
</LinearLayout>
TestBackgroundActivity.java:
public class TestBackgroundActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
While changing an orientation of my device (nvidia Tegra Note 7) logcat is noting:
cz.reloecc.testBackground I/dalvikvm-heap﹕ Grow heap (frag case) to 35.625MB for 12904976-byte allocation
with roughly 13MB addition on every turnaround (for biggest version of image)
up to my heap max (64MB):
cz.reloecc.testBackground E/dalvikvm-heap﹕ Out of memory on a 12904976-byte allocation.
cz.reloecc.testBackground I/dalvikvm﹕ at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
..
cz.reloecc.testBackground I/dalvikvm﹕ at cz.reloecc.testBackground.TestBackgroundActivity.onCreate(TestBackgroundActivity.java:13)
BUT!
problem does not persist when I delete ui.png (which is set as background) from drawable-land-[x|m|l]dpi OR drawable-[x|m|l]dpi folder in res folder..
so if I have only one version of background image, I can turn device for a long week..
And here is my question: How to handle multiple versions of drawables (set as background) to avoid memory leaks?
//EDIT: I managed few tries of disposing, recycling, destroying, nulling resources or their holders, the last one is based on Aeshang's suggestion:
=== version 2.0 ===
Resources.java:
public class Resources {
public Resources(Context context){
this.context = context;
}
public Drawable getImage(int id){
if(images.indexOfKey(id) < 0){
Drawable drawable = context.getResources().getDrawable(id);
images.put(id, drawable);
}
return images.get(id);
}
public void disposeImages(){
int key;
for(int i = 0; i < images.size(); i++) {
key = images.keyAt(i);
Drawable drawable = images.get(key);
if(drawable instanceof BitmapDrawable){
if(drawable instanceof BitmapDrawable){
Log.i(TestBackgroundActivity.LOG_TAG, "Recycling image " + key);
((BitmapDrawable)drawable).getBitmap().recycle();
}
}
}
}
public void disposeAll(){
disposeImages();
images.clear();
}
private SparseArray<Drawable> images = new SparseArray<Drawable>();
private Context context;
}
TestBackgroundActivity.java:
public class TestBackgroundActivity extends Activity {
public static String LOG_TAG = "[TestBG]";
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
resources = new Resources(getApplicationContext());
LinearLayout mainLayout = (LinearLayout)findViewById(R.id.mainLayout);
mainLayout.setBackgroundDrawable(resources.getImage(R.drawable.ui));
}
#Override
protected void onDestroy(){
resources.disposeAll();
super.onDestroy();
}
private Resources resources;
}
Use third party libraries to load the drawables
like Picasso or Universal Image Loader
They will automatically handle large bitmaps
And coming to drawables
User 1920X1080 resolution images and put them drawable-xxhdpi folder every thing works fine
Ok,
this should definitely work. Tested in on two other devices, and altrough app is complaining about high memory heap grow. It is gc'ing right after.
My tegra note 7 is THE pain. I will have to find out the right source of this hell.
//edit:
fine, calling
System.gc();
in onDestroy() of MainActivity
and app lasts forever.. who knows why?
Related
I need some help for my app that I'm developing. Current code that I'm using, on long press it launches app info. I want to change that to launch an activity of my app.
The Quick.java class.
#TargetApi(24)
public class Quick extends TileService {
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onTileAdded() {
super.onTileAdded();
}
#Override
public void onTileRemoved() {
super.onTileRemoved();
}
#Override
public void onStartListening() {
super.onStartListening();
}
#Override
public void onStopListening() {
super.onStopListening();
}
#Override
public void onClick() {
super.onClick();
startActivity(Main);
}
}
Just need a onLongClick() method on this code.
In my manifest under <application> tag.
<service
android:name=".Quick"
android:icon="#drawable/ic_quick"
android:label="#string/quick_title"
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
Caution : It's 100% possible to do that in android N and O, for an example take look at this app
Ok I get yes you can implement the Long click listner but here is a issue
Long clicking on your quick settings tile will, by default, go to your app’s info screen. You can override that behavior by adding an intent-filter to one of your activities like so:
<intent-filter>
<action android:name="android.service.quicksettings.action.QS_TILE_PREFERENCES"/>
</intent-filter>
As you have done in your manifest file here a link that might be helpfull look very closely long press quick setting tile in android
I have an Android App, which shows a "Splash Screen" for 3 seconds. After that, the MainActivity gets loaded.
Unfortunately the MainActivity takes additional ~4 seconds to load. On first startup even longer. However when the App is loaded, everything runs smooth.
Now how can I achieve it, that the MainActivity gets loaded, during the display of the Splash Screen? It just should display an image until the whole thing loaded completely.
I have read about Async-Task, but I'm not sure where to put it and how to use it properly. Can someone help me please?
SplashScreen.java
public class SplashScreen extends Activity {
private static int SPLASH_TIME_OUT = 3000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_startup);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(SplashScreen.this, MainActivity.class);
startActivity(i);
finish();
}
}, SPLASH_TIME_OUT);
}
}
MainActivity.java
public class MainActivity extends Activity implements OnClickListener, MediaController.MediaPlayerControl {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Some heavy processing
//starting services
//starting Google Text to Speech
//and so on...
}
}
You should not be creating a new thread on startup, instead you should create a view that does not have to wait for your resources to load, as detailed in this article: Splash Screens the Right Way.
As stated in the article, you should create a layer-list drawable instead of a layout XML file:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Fill the background with a solid color -->
<item android:drawable="#color/gray"/>
<!-- Place your bitmap in the center -->
<item>
<bitmap
android:gravity="center"
android:src="#mipmap/ic_launcher"/>
</item>
</layer-list>
Then create a theme using the drawable file as a background. I use the background attribute instead of the windowBackground attribute as suggested in the article, because background takes the status and navigation bars into account, centering the drawable better. I also set windowAnimationStyle to null so that the splash screen does not animate the transition to the MainActivity:
<resources>
<!-- Base application theme -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
<!-- Splash Screen theme -->
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:background">#drawable/background_splash</item>
<item name="android:windowAnimationStyle">#null</item>
</style>
</resources>
Then declare your theme in the manifest for your SplashActivity:
<activity android:name=".SplashActivity"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
And finally all you have to do in your SplashActivity is start your MainActivity, and the splash screen will only show for as long as it takes for your app to configure:
public class SplashActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
}
}
If there are no specific constraints about the time the splash screen should be shown, you could use the AsyncTask in the following way:
public class SplashScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_startup);
startHeavyProcessing();
}
private void startHeavyProcessing(){
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
//some heavy processing resulting in a Data String
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "whatever result you have";
}
#Override
protected void onPostExecute(String result) {
Intent i = new Intent(SplashScreen.this, MainActivity.class);
i.putExtra("data", result);
startActivity(i);
finish();
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
}
If the resulting data if of another nature than a String you could put a Parcelable Object as an extra to your activity. In onCreate you can retrieve the data with:
getIntent().getExtras.getString('data');
How about, in the interest of simplicity, you combine your splash activity with your main activity? That way you get the best of both worlds, namely a splash screen while your data is preparing the first time, and a quick startup when it's been prepared previously. Making the user wait for nothing is not really good form...
Something like:
public class MainActivity extends Activity implements OnClickListener, MediaController.MediaPlayerControl {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initially shows splash screen, the main UI is not visible
setContentView(R.layout.activity_main);
// Start an async task to prepare the data. When it finishes, in
// onPostExecute() get it to call back dataReady()
new PrepareDataAsyncTask(this).execute();
}
public void dataReady() {
// Hide splash screen
// Show real UI
}
}
your splash screen code works fine but when you call next activity then in onCreate() use Asynctask for your heavy tasks...
I have had similar problem. There was a blank loading screen (not even toolbar). Mu culprit was in the manifest in the MainActivity:
android:launchMode="singleInstance"
Just do like in this article:
1 - create a XML layout like this for the splash screen. I called it "background_splash.xml"
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="#color/cardview_light_background"/>
<item>
<bitmap
android:gravity="center"
android:src="#drawable/kiss_com_sub_logo"/>
</item>
</layer-list>
2 - Then, go to the styles.xml and write a style like this:
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">#drawable/background_splash</item>
</style>
3 - Write an activity to your splash. I called it SplashActivity.kt
class SplashActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val intent = Intent(this, MainActivity::class.java)
startActivity(intent)
finish()
}
}
4 - Finally, go to you AndroidManifest.xml and add your activity splash: (Note: don't remove anything in the AndroidManifest, just add this before the Main activity).
<activity
android:name=".SplashActivity"
android:label="Kiss"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
This is done. You don't need to worry about the time that your application will demand to start, the splash will be there just for enough time. When your MainActivity is ready, it will be showed.
I'm kind of a noob android developer, and I hit a few bumps while trying to create a button that opens a new layout. While I was doing that, I got a few errors that would not go away no matter what I tried. In response, I copied most of the xml files and java files that I had changed from the original structure, and I added them to a new project, thinking all my errors would go away. I really need some help, I can't tell you how long I have been stuck on this small error. I have attached the main FullScreenActivity.java, activity_main.xml, the Android Manifest, and the error messages. Thank you in advance for the help guys, I really do appreciate it! c:
FullScreenActivity.java ~
package sehej.android.doge;
import sehej.android.doge.util.SystemUiHider;
import sehej.android.doge.R;
import android.annotation.TargetApi;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
public class FullscreenActivity extends Activity {
/**
* Whether or not the system UI should be auto-hidden after
* {#link #AUTO_HIDE_DELAY_MILLIS} milliseconds.
*/
private static final boolean AUTO_HIDE = true;
/**
* If {#link #AUTO_HIDE} is set, the number of milliseconds to wait after
* user interaction before hiding the system UI.
*/
private static final int AUTO_HIDE_DELAY_MILLIS = 3000;
/**
* If set, will toggle the system UI visibility upon interaction. Otherwise,
* will show the system UI visibility upon interaction.
*/
private static final boolean TOGGLE_ON_CLICK = true;
/**
* The flags to pass to {#link SystemUiHider#getInstance}.
*/
private static final int HIDER_FLAGS = SystemUiHider.FLAG_HIDE_NAVIGATION;
/**
* The instance of the {#link SystemUiHider} for this activity.
*/
private SystemUiHider mSystemUiHider;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
**** final View controlsView = findViewById(R.id.fullscreen_content_controls);
**** final View contentView = findViewById(R.id.fullscreen_content);
// Set up an instance of SystemUiHider to control the system UI for
// this activity.
mSystemUiHider = SystemUiHider.getInstance(this, contentView,
HIDER_FLAGS);
mSystemUiHider.setup();
mSystemUiHider
.setOnVisibilityChangeListener(new SystemUiHider.OnVisibilityChangeListener() {
// Cached values.
int mControlsHeight;
int mShortAnimTime;
#Override
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public void onVisibilityChange(boolean visible) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
// If the ViewPropertyAnimator API is available
// (Honeycomb MR2 and later), use it to animate the
// in-layout UI controls at the bottom of the
// screen.
if (mControlsHeight == 0) {
mControlsHeight = controlsView.getHeight();
}
if (mShortAnimTime == 0) {
mShortAnimTime = getResources().getInteger(
android.R.integer.config_shortAnimTime);
}
controlsView
.animate()
.translationY(visible ? 0 : mControlsHeight)
.setDuration(mShortAnimTime);
} else {
// If the ViewPropertyAnimator APIs aren't
// available, simply show or hide the in-layout UI
// controls.
controlsView.setVisibility(visible ? View.VISIBLE
: View.GONE);
}
if (visible && AUTO_HIDE) {
// Schedule a hide().
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
}
});
// Set up the user interaction to manually show or hide the system UI.
contentView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (TOGGLE_ON_CLICK) {
mSystemUiHider.toggle();
} else {
mSystemUiHider.show();
}
}
});
};
// Upon interacting with UI controls, delay any scheduled hide()
// operations to prevent the jarring behavior of controls going away
// while interacting with the UI.
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Trigger the initial hide() shortly after the activity has been
// created, to briefly hint to the user that UI controls
// are available.
delayedHide(100);
}
/**
* Touch listener to use for in-layout UI controls to delay hiding the
* system UI. This is to prevent the jarring behavior of controls going away
* while interacting with activity UI.
*/
View.OnTouchListener mDelayHideTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (AUTO_HIDE) {
delayedHide(AUTO_HIDE_DELAY_MILLIS);
}
return false;
}
};
Handler mHideHandler = new Handler();
Runnable mHideRunnable = new Runnable() {
#Override
public void run() {
mSystemUiHider.hide();
}
};
/**
* Schedules a call to hide() in [delay] milliseconds, canceling any
* previously scheduled calls.
*/
private void delayedHide(int delayMillis) {
mHideHandler.removeCallbacks(mHideRunnable);
mHideHandler.postDelayed(mHideRunnable, delayMillis);
}
}
activity_main.xml ~
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/grass"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:padding="20sp"
app:textAlignment="center"
tools:context=".MainActivity" >
<requestFocus
app:layout_width="wrap_content"
app:layout_height="wrap_content" />
<Button
app:id="#+id/button2"
style="#style/ButtonBar"
app:layout_width="150dp"
app:layout_height="wrap_content"
app:layout_below="#+id/button1"
app:layout_centerHorizontal="true"
app:layout_marginTop="65dp"
app:text="#string/button2"
app:typeface="sans" />
<Button
app:id="#+id/button3"
style="#style/ButtonBar"
app:layout_width="150dp"
app:layout_height="wrap_content"
app:layout_alignLeft="#+id/button1"
app:layout_below="#+id/button2"
app:layout_marginTop="65dp"
app:text="#string/button3"
app:typeface="sans" />
<Button
app:id="#+id/button1"
style="#style/ButtonBar"
app:layout_width="150dp"
app:layout_height="wrap_content"
app:layout_alignLeft="#+id/button2"
app:layout_below="#+id/textView1"
app:layout_marginTop="22dp"
app:onClick="whenClicked"
app:text="#string/button1"
app:typeface="sans" />
<TextView
app:id="#+id/textView1"
app:layout_width="wrap_content"
app:layout_height="wrap_content"
app:layout_alignParentTop="true"
app:layout_centerHorizontal="true"
app:layout_marginTop="39dp"
app:paddingBottom="30sp"
app:text="#string/title"
app:textColor="#color/blue"
app:textSize="60sp"
app:textStyle="bold"
app:typeface="sans" />
Android Manifest ~
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="sehej.android.doge"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="sehej.android.doge.FullscreenActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name"
android:theme="#style/FullscreenTheme" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Error messages from problems view ~
fullscreen_content_controls cannot be resolved or is not a field FullscreenActivity.java /???/src/sehej/android/doge
line 54 Java Problem
fullscreen_content cannot be resolved or is not a field FullscreenActivity.java /???/src/sehej/android/doge
line 55 Java Problem
~~~~??? is the project/application name
~~~~I have marked the section that received the errors with '***'s
You have not defined
fullscreen_content_controls
fullscreen_content
The above id in your activity_main.xml Thats why you are getting
fullscreen_content_controls cannot be resolved or is not a field FullscreenActivity.java .
As looking at your code you have not declare any View with the id
fullscreen_content_controls
fullscreen_content in your activity_main.xml.
If you want to get rid of this problem you have to define two Views with the id you are mentioning in your code.
Edit
you will usually call setContentView(int) with a layout resource defining your UI, and using findViewById(int) to retrieve the widgets in that UI So whatever view you have declared in your Ui Xml you can get those.
Like in your case you have defined button so something like
Button someButton = (Button) findViewById(R.id.button2);
will work for you now you can use this widget in your application.
This is what I did to solve this problem I faced. It happens when you press ctrl+shift+O to auto import.
the solution is to
Replace import android.R with .R in your activity java file.
I have a game I'm working on, that uses AndEngine.
AndEngine has a "BaseGameActivity" and so does Google Play Game Service. I had to rename BaseGameActivity from AndEngine to AEBaseGameActivity and have it as a parent class BaseGameActivity instead of Activity.
But it is giving me this error:
Caused by: android.util.AndroidRuntimeException: requestFeature() must be called before adding content
at com.android.internal.policy.impl.PhoneWindow.requestFeature(PhoneWindow.java:226)
at org.andengine.util.ActivityUtils.requestFullscreen(ActivityUtils.java:56)
at org.andengine.ui.activity.AEBaseGameActivity.applyEngineOptions(AEBaseGameActivity.java:427)
at org.andengine.ui.activity.AEBaseGameActivity.onCreate(AEBaseGameActivity.java:83)
Now AndEngine has this piece of code:
public static void requestFullscreen(final Activity pActivity) {
final Window window = pActivity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
window.requestFeature(Window.FEATURE_NO_TITLE);
}
if I comment the requestFeature line, my projects runs! But it has an ugly title bar.
Does anyone please know a fix for this ?
EDIT, HERE IS SOME MORE CODE:
PS: AEBaseGameActivity.php extends BaseActivity which extends BaseGameActivity (previously just activity)
AEBaseGameActivity.php
public abstract class AEBaseGameActivity extends BaseActivity implements IGameInterface, IRendererListener {
#Override
protected void onCreate(final Bundle pSavedInstanceState) {
if(BuildConfig.DEBUG) {
Debug.d(this.getClass().getSimpleName() + ".onCreate" + " #(Thread: '" + Thread.currentThread().getName() + "')");
}
super.onCreate(pSavedInstanceState);
this.mGamePaused = true;
this.mEngine = this.onCreateEngine(this.onCreateEngineOptions());
this.mEngine.startUpdateThread();
this.applyEngineOptions(); //REQUEST FULLSCREEN
this.onSetContentView(); //SET CONTENT VIEW
}
...
private void applyEngineOptions() {
final EngineOptions engineOptions = this.mEngine.getEngineOptions();
if(engineOptions.isFullscreen()) {
ActivityUtils.requestFullscreen(this); //ACTIVITY UTIL SHOWN LATER
}
...
}
...
protected void onSetContentView() {
this.mRenderSurfaceView = new RenderSurfaceView(this);
this.mRenderSurfaceView.setRenderer(this.mEngine, this);
this.setContentView(this.mRenderSurfaceView, AEBaseGameActivity.createSurfaceViewLayoutParams());
}
}
ActivityUtils.java
public class ActivityUtils {
public static void requestFullscreen(final Activity pActivity) {
final Window window = pActivity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
window.requestFeature(Window.FEATURE_NO_TITLE); //IF COMMENTING THIS, THE GAME IS RUNNING
}
...
}
EDIT2:
The code is basically only AndEngine, here is the original code:
https://github.com/nicolasgramlich/AndEngine/tree/GLES2/src/org/andengine/ui/activity
My changes:
renamed BaseGameActivity to AEBaseGameActivity
BaseActivity extends BaseGameActivity (taken from Google Play Game Service) instead of Activity
BaseGameActivity and GameHelper.java taken from BaseGameUtils from Google Play Game Service.
Ok so this is what I did:
I commented out the line that is causing the problem (ActivityUtils.java line 56 of AndEngine)
I added this in my activity to the Android Manifest:
android:theme="#android:style/Theme.NoTitleBar"
It ends up looking something like:
<activity
android:name=".GameActivity"
android:theme="#android:style/Theme.NoTitleBar"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Exception requestFeature() must be called before adding content telling everything
call requestFullscreen() before setContenview()
Edit
try REQUEST FULLSCREEN after super.onCreate()
#Override
protected void onCreate(final Bundle pSavedInstanceState) {
super.onCreate(pSavedInstanceState);
this.applyEngineOptions(); //REQUEST FULLSCREEN
Hello
I try to make some example program showing ads on Android phone, and I try to test it on Emulator of v2.2
Everything in code seems to be fine, but AdListener in debugger says that:
Response message is zero or null;
onFailedToReceiveAd( No ad to show).
Is there any way for it to be my fault? Did anyone encounter same problem?
Heres the code
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.AdTest"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".AdTest"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- AdMobActivity definition -->
<activity android:name="com.google.ads.AdActivity"
android:configChanges="orientation|keyboard|keyboardHidden" />
</application>
<uses-sdk android:minSdkVersion="7"></uses-sdk>
<!-- AdMob SDK requires Internet permission -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Layout xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/main"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
/>
</LinearLayout>
and Activity code
package com.AdTest;
import com.google.ads.*;
import com.google.ads.AdRequest.ErrorCode;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.LinearLayout;
public class AdTest extends Activity implements AdListener{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout layout = (LinearLayout)findViewById(R.id.main);
AdView adView = new AdView(this, AdSize.BANNER, "anonymouse");
// Unit ID is correct, I changed it on purpose while pasting here
adView.setAdListener(this);
layout.addView(adView);
AdRequest request= new AdRequest();
adView.loadAd(request);
}
public void onFailedToReceiveAd(AdView adView)
{
Log.d("AdListener", "onFailedToReceiveAd");
}
public void onFailedToReceiveRefreshedAd(AdView adView)
{
Log.d("AdListener", "onFailedToReceiveRefreshedAd");
}
public void onReceiveAd(AdView adView)
{
Log.d("AdListener", "onReceiveAd");
}
public void onReceiveRefreshedAd(AdView adView)
{
Log.d("AdListener", "onReceiveRefreshedAd");
}
#Override
public void onDismissScreen(Ad arg0) {
// TODO Auto-generated method stub
}
#Override
public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) {
Log.d("AdListener", "onFailedToReceiveAD");
}
#Override
public void onLeaveApplication(Ad arg0) {
// TODO Auto-generated method stub
}
#Override
public void onPresentScreen(Ad arg0) {
// TODO Auto-generated method stub
}
#Override
public void onReceiveAd(Ad arg0) {
Log.d("AdListener", "Received succesfully");
}
}
I have confront the same problem with
onFailedToReceiveAd( No ad to show).
It seems AdMob not sent ad content for our app for some reasons. Even when I in testing mode there's still no ad.
I create my house ad on AdMob to verify my application. It's an easier way in development than testing mode.
I implemented AdListener on my Activity and set it as the AdView listener, then added the following
public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1)
{
Log.d("AdMob", "Failed to receive an Ad. Requesting a new one..." + arg1);
arg0.stopLoading();
arg0.loadAd(new AdRequest());
}
I had the same problem too. So I changed the code to set the test mode true, then the Admob test ad started to show on the emulator. Try this in your OnCreate() method:
LinearLayout layout = (LinearLayout)findViewById(R.id.main);
AdView adView = new AdView(this, AdSize.BANNER, "anonymouse");
// Unit ID is correct, I changed it on purpose while pasting here
adView.setAdListener(this);
AdRequest request = new AdRequest();
request.setTesting(true);
adView.loadAd(request);
If you run this on a real device and still no ad to show, then I guess it might have something to do with Admob fill rate.
Change the test mode to true. Note that ads will not be displayed until at least 3 access attempts are made for the day.
It appears that the latest admob SDK 4.0.4 doesn't display ads on 1.5 devices.
In the emulator it works fine for 1.6+, but not 1.5.
I think its from the new cross-over advertising with AdSense. As far as I can tell the SDK now wraps a webview as the visual component of the view so it can publish the different kinds of ads. A close look at the log shows WebView.multitouch enabled - as 1.5 doesn't support multitouch (for us developers in Java) due to Apple throwing its toys out of the pram and having a dummyspit (I understand they believe only they are allowed to use two fingers at once..) and perhaps enabling multitouch on the webview causes an internal exception and the view never gets created, and thus cannot receive the HTML reply from the admob http server.
Also see this link
1/ get the latest SDK version
2/ try admob demo with your publisher id
3/ try it in test mode (this should work always)
4/ try to add some sample house ads (shown when there is no other ad available)
5/ try to change your keywords
In general, admob prints detailed error to log (ID missing, activity missing in manifest etc).
I had done the admob integration and that is run on device as well as on emulator.
so, please try below code:
I think you have to remove textview from main.xml
and also try this:
1) Create new app on in your admob a/c
2) then simply replace the id of previous app by new one
try it bro.
I also get this problem. You can try to customized the request, before loading. Like this:
AdRequest re = new AdRequest();
//re.setTesting(true);
re.setGender(AdRequest.Gender.FEMALE);
adview.loadAd(re);
I put my example, apk file and source code here, you can try:
Add Google Admob in Android Application