I added admob to my libgdx project without any problem but How can I disable admob in game. I have 2 screen(MainMenu and PlayScreen) and I want to ads to be shown only at MainMenu.
I have found an article about conntrolling ads in libgdx but the problem is this article is for Desktop not Android.
https://code.google.com/p/libgdx/wiki/AdMobInLibgdx (Note: question arises in part from using deprecated document, newer version available at https://github.com/libgdx/libgdx/wiki/Admob-in-libgdx)
Take a look at the #control at the new wiki. There are 2 Final static values inside of your Android Project:
public class HelloWorldAndroid extends AndroidApplication {
private final int SHOW_ADS = 1;
private final int HIDE_ADS = 0;
protected Handler handler = new Handler()
{
#Override
public void handleMessage(Message msg) {
switch(msg.what) {
case SHOW_ADS:
{
adView.setVisibility(View.VISIBLE); //change to visible
break;
}
case HIDE_ADS:
{
adView.setVisibility(View.GONE);//change to not visible
// you should also disable the ad fetching here!
break;
}
}
}
};
So if you call the method: (which is parsed as interface to the core project)
public interface IActivityRequestHandler {
public void showAds(boolean show);
}
public class HelloWorldAndroid extends AndroidApplication implements IActivityRequestHandler {
...
// This is the callback that posts a message for the handler
#Override
public void showAds(boolean show) {
handler.sendEmptyMessage(show ? SHOW_ADS : HIDE_ADS);
}
it sends an message to the handler which activates or disable the admob. The interface for showAds is passed to the core project so you can hold an reference to it and use it. To see how this works take a look at the article of interfacing plattformspec code.
Just to show this here:
View gameView = initializeForView(new HelloWorld(this), false); // and "this" is the mainclass of the android project which implements the IActivityRequestHandler interface shown above
//the HelloWorld(this) is the core project where you now can save the `IActivityRequestHandler` as referance and call the showAds(bool)
But in the end if you would have read the aticle you should have know this all.
Related
I am planning to add Otto event bus to decouple my communications. One of the things I want use event bus for is to communicate between a button click handler and the activity.
The idea is that the button click (from my custom view) would generate a text submission event which would notify the activity. The activity would then decide what to do with it. If the activity deems it proper, it would send the text to a service for upload or whatever.
Is this a proper way to use an event bus?
Also, what are some good practices when using event buses?
I still think this question should be closed as not proper for the StackOverflow model.
But for anyone looking on how on can organize user events around a Bus, that's kinda of how we've done on the place I work.
Remember, that type of structure only makes sense if you're creating a big project where achieving a high level of separation makes the life of a team of developers easier. For small, quick projects or test apps that's too much effort.
PS.: all the code below is typed 100% by heart without checking any real code, so there will be typos and small errors, but should be enough to get an idea of the approach. I also didn't write any annotation like #override, too lazy for it.
First: Activity overrides getSystemService to supply a Bus via Context and register/unregister event handlers as needed.
public MyActivity extends AppCompatActivity {
private static final String BUS_SERVICE = "bus_service";
private List<EventHandler> eventHandlers = new ArrayList();
private Bus bus = new Bus();
public void onCreate(Bundle savedState){
super.onCreate(savedState);
.... layout creation, etc, etc, etc
if(isLoggedIn()) {
eventHandlers.add(new LoggedUserNavigationHandler());
eventHandlers.add(new RestPostRequestHandler());
} else{
eventHandlers.add(new GuestUserNavigation());
}
eventHandlers.add(new AnalyticsTrackingHandler());
if(DEBUG) {
// log all events in debug mode
eventHandlers.add(new EventHandler(){
#Subscribe
public void onEvent(Object o){
Log.d(TAG, "Event: " + o.toString);
}
});
}
}
}
public Object getSystemService(String name){
if(BUS_SERVICE.equals(name)) return bus;
else return super.getSystemService(name);
}
public void onStart(){
super.onStart();
for(int i=0, size=eventHandlers.size(); i<size; i++) {
eventHandlers.get(i).activity = this; // pass reference, might be usefull
bus.register(eventHandlers.get(i));
}
}
public void onStop(){
for(int i=0, size=eventHandlers.size(); i<size; i++) {
bus.unregister(eventHandlers.get(i));
eventHandlers.get(i).activity = null;
}
super.onStop();
}
}
Then: You have all the RecyclerView.ViewHolder (or custom widget) to be the click listener and dispatch appropriate events. For example in a ViewHolder for a photo item.
public class PhotoHolder extends ViewHolder implements OnClickListener {
TextView user;
ImageButton like;
ImageView photo;
Photo data; // assume this was set during `bindViewHolder`
public PhotoHolder(View itemView) {
super(itemView);
user = (TextView) itemView.findViewById(...
like = (ImageButton) itemView.findViewById(...
photo = (ImageView) itemView.findViewById(...
user.setOnClickListener(this);
like.setOnClickListener(this);
photo.setOnClickListener(this);
}
public void onClick(View view){
switch(view.getId()){
case R.id.user:
((Bus)view.getSystemService(BUS_SERVICE))
.post(new Event.PhotoEvent.UserTap(data);
break;
case R.id.like:
((Bus)view.getSystemService(BUS_SERVICE))
.post(new Event.PhotoEvent.LikeUnlike(data);
break;
case R.id.photo:
((Bus)view.getSystemService(BUS_SERVICE))
.post(new Event.PhotoEvent.PhotoTap(data);
break;
}
}
}
and the last of course: is to create those events objects and add all the events to your appropriate handlers.
// add all the app events under this class, or maybe create a `Event` package and then all the events in that package
public final class Event {
public static class PhotoEvent {
public final Photo data;
public Photo(Photo data){
this.data=data;
}
public static class UserTap extends PhotoEvent{
// copy matching constructor
}
public static class LikeUnlike extends PhotoEvent{
// copy matching constructor
}
public static class PhotoTap extends PhotoEvent{
// copy matching constructor
}
}
}
finally, handling events
public class RestPostRequestHandler {
#Subscribe
public void onPhotoLikeUnlike(Event.Photo.LikeUnlike event){
// make your POST request here
}
}
a handler for navigating:
public class LoggedUserNavigationHandler extends EventHandler{
#Subscribe
public void on(Event.Photo.UserTap event){
Intent i = new Intent( ... create here intent for the "user profile"
// activity reference was passed during onStart
activity.startActivity(i);
}
}
a handler for analitics:
public class AnalyticsTrack {
#Subscribe
public void on(Event.Photo.UserTap event){
// send event "user tap" ?
}
}
I agree with some of the comments that it's possible to create a huge, weird spaghetti code when having "tap" events going through the bus. But if from the start a good structured approach is defined and all the developers follow it, you can achieve a project that is easy to follow and with a very clear separation of responsibilities.
I am looking to make a game and I need to involve native android sdk features such as toast, dialog, in app billing, other google Api, gcm ..etc
I am pretty experienced with android sdk when I built tools apps and I used animations and very briefly surface view.
However I have looked into libdgx and looks promising but the only downside I find is the "not so easy integration with Android native sdk". Ie, I can't just start my own activity or call native api unless I am missing it
So I was wondering, should I go with libgdx in this case or should I go with the native route?
Thank you
If you're sure you're not going to target other platforms, you can just move your code from the default core project into your Android project and work from there, calling any API as you please. But you would lose the ability to test on desktop.
To maintain portability to other platforms and ability to test on desktop, you can create an interface listing all the Android API methods you would like to call. Pass an instance of this interface into your game's constructor in your Android project, so your game can indirectly call them. Your desktop project can pass in an instance of this interface with empty or system logging methods.
Example:
public class MyGdxGame extends ApplicationAdapter {
public interface AndroidAPIAdapter {
public void makeToast(String msg);
public void startActivity(int activityNumber);
}
AndroidAPIAdapter androidAPIAdapter;
public MyGdxGame (AndroidAPIAdapter androidAPIAdapter){
this.androidAPIAdapter = androidAPIAdapter;
}
//Call this from game code in core project as needed
public void makeToast(String msg){
if (androidAPIAdapter!=null)
androidAPIAdapter.makeToast(msg);
}
//Call thisfrom game code in core project as needed
public void startActivity(int activityNumber){
if (androidAPIAdapter!=null)
androidAPIAdapter.startActivity(activityNumber);
}
//...
}
with:
public class MyGameActivity extends AndroidApplication implements AndroidAPIAdapter {
public static final int ACTIVITY_SETTINGS = 0;
public static final int ACTIVITY_ABOUT = 1;
//etc.
public void onCreate (Bundle bundle) {
super.onCreate(bundle);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
config.useImmersiveMode = true;
initialize(new MyGdxGame(this), config);
}
#Override
public void makeToast(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT);
}
#Override
public void startActivity(int activityNumber) {
switch (activityNumber){
case ACTIVITY_SETTINGS:
startActivity(this, MySettingsActivity.class);
break;
case ACTIVITY_ABOUT:
startActivity(this, MyAboutActivity.class);
break;
}
}
}
I need to determine in runtime from code if the application is run under TestInstrumentation.
I could initialize the test environment with some env/system variable, but Eclipse ADK launch configuration would not allow me to do that.
Default Android system properties and environment do not to have any data about it. Moreover, they are identically same, whether the application is started regularly or under test.
This one could be a solution: Is it possible to find out if an Android application runs as part of an instrumentation test but since I do not test activities, all proposed methods there won't work. The ActivityManager.isRunningInTestHarness() method uses this under the hood:
SystemProperties.getBoolean("ro.test_harness")
which always returns false in my case. (To work with the hidden android.os.SystemProperties class I use reflection).
What else can I do to try to determine from inside the application if it's under test?
I have found one hacky solution: out of the application one can try to load a class from the testing package. The appication classloader surprisingly can load classes by name from the testing project if it was run under test. In other case the class is not found.
private static boolean isTestMode() {
boolean result;
try {
application.getClassLoader().loadClass("foo.bar.test.SomeTest");
// alternatively (see the comment below):
// Class.forName("foo.bar.test.SomeTest");
result = true;
} catch (final Exception e) {
result = false;
}
return result;
}
I admit this is not elegant but it works. Will be grateful for the proper solution.
The isTestMode() solution did not work for me on Android Studio 1.2.1.1. Almighty Krzysztof from our company tweaked your method by using:
Class.forName("foo.bar.test.SomeTest");
instead of getClassLoader(). Thanks for Krzysztof!
We created a solution to pass parameters to the MainActivity and use it inside the onCreate method, enabling you to define how the Activity will be created.
In MainActivity class, we created some constants, which could also be an enum. We created a static attribute too.
public class MainActivity {
public static final int APPLICATION_MODE = 5;
public static final int UNIT_TEST_MODE = 10;
public static final int OTHER_MODE = 15;
public static int activityMode = APPLICATION_MODE;
(...)
#Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
switch (activityMode) {
case OTHER_MODE:
(...)
break;
case UNIT_TEST_MODE:
Log.d(TAG, "Is in Test Mode!");
break;
case APPLICATION_MODE:
(...)
break;
}
(...)
}
(...)
}
We made MainActivityTest class abstract, created a setApplicationMode and called this method inside the setUp() method, before calling the super.setUp() method.
public abstract class MainActivityTest extends ActivityInstrumentationTestCase2<MainActivity> {
protected void setUp() throws Exception {
setApplicationMode(); // <=====
super.setUp();
getActivity();
(...)
}
(...)
public void setApplicationMode() {
MainActivity.activityMode = MainActivity.UNIT_TEST_MODE;
}
}
All other test classes inherit from MainActivityTest, if we want it to have another behaviour, we can simply override the setApplicationMode method.
public class OtherMainActivityTest extends MainActivityTest {
(...)
#Override
public void setApplicationMode() {
MainActivity.activityMode = MainActivity.OTHER_MODE;
}
}
The user nathan-almeida is the friend that is co-author of this solution.
I have to make a Android Junit Test.
And the source just like this way:
public class A extends Activity{
private classB mB;
private int mType = 2;
somebutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mB.showDialog(
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
//next line is the modified and I have to make test file
mB.setType(mType);
}
}
)
}
}
}
And I could let the test click button and prepare all other needed things, but I want to how to assertTrue? And there is no "getType()" and the "Type" in "mB" is private.
Thank you for your time.
Unit-Testing is diffucult on android because all the SDK classes are stubbed out and are good only for compiling agains them, and running unit tests on device or emulator is PITA
Alternative is mocking. [Most] Suitable mock framework is JMockit ( it can mock final private static - also everything you can dream of)
Here is small example showcasing using of jmockit against android classes:
/**
* shall inject assignable views into
*/
#Test
public void testSimpleInjection(#Mocked final WithInjectableViews injectable,
#Mocked final TextView textView,
#Mocked final Button button) {
new Expectations() {
{
injectable.findViewById(239);
returns(textView);
injectable.findViewById(555);
returns(button);
}
};
ViewInjector.startActivity(injectable);
assertEquals(textView, Deencapsulation.getField(injectable, "asView"));
assertEquals(button, Deencapsulation.getField(injectable, "button"));
assertNull(Deencapsulation.getField(injectable, "notInjected"));
}
class WithInjectableViews extends Activity {
// shall be injected
#InjectView(id = 239)
private android.view.View asView;
#InjectView(id = 555)
private Button button;
// shall be left alone
private View notInjected = null;
}
(full source: https://github.com/ko5tik/andject/blob/master/src/test/java/de/pribluda/android/andject/ViewInjectionTest.java)
However, it is diffucult to mock up anonymous inner classes, so you may have to refactor somehow. As to access to provate fields and mewthods - jmockit provides untility class Deencalsulation - it ignores almost all access constraints.
I've read well enough on the subject to get well and thoroughly confused. I'm doing a workout tracker app such as RunKeeper, which tracks how long and how far the user has been say, running. I'm in the process of programming the main interface of this "workout" which shows a stopwatch-like layout which includes both a timer showing the time which is updated every second, and a counter showing how far he's run so far.
My problem is updating the interface. I have a stopwatch class keeping track of the time, and I calculate the distance based on gps locations, but I'm at a loss to find the recommended way to run a continuous thread in the background that updates the ui on a fixed time rate.
As far as I've been able to tell, I should either be implementing the Handler.Callback interface in the activity class, or have a separate Callback object together with a Thread, but I'm sort of at a loss on how to get it all to work together. I both need to update the time shown that I get from my stopwatch class (simple start/stop time calculation, nothing thread-related), and the distance calculated based on the locations received in onLocationChanged().
Here's a stripped down version of my Activity code:
public class WorkoutActivity extends Activity implements OnClickListener, LocationListener
{
private LocationManager locManager;
private boolean workoutStarted = false;
// The TextViews to update
private TextView timeLabel;
private TextView distanceLabel;
private Stopwatch stopwatch;
#Override
public void onCreate(Bundle savedInstanceState)
{
/*
... Interface initialisation
*/
stopwatch = new Stopwatch();
}
private void startWorkout() {/* ...*/}
private void stopWorkout() {/* ...*/}
private void pauseWorkout() {/* ...*/}
private void resumeWorkout(){/* ...*/}
public void onClick(View v) {/* ...*/}
public void onLocationChanged(Location location){/* ...*/}
}
According to most answers I've read around here I should use a Handler object extending the handleMessage method, but nowadays (at least according to the warning in Lint) you have to make such objects static to avoid memory leaks. That however, makes it a bit strange to directly access and change the other private objects in the activity class from within the Handler. I suppose you could solve this by making the objects you need to affect parameters in a class extending Handler, but I dunno, it feels like a bit of a "hack" (nested class within WorkoutActivity):
static class TimeHandler extends Handler
{
static final int MSG_START_TIMER = 1;
static final int MSG_UPDATE_TIMER = 2;
static final int MSG_STOP_TIMER = 3;
private static final int REFRESH_RATE = 1000;
private Stopwatch stopwatch;
private TextView timeLabel;
public TimeHandler(Stopwatch stopwatch, TextView label)
{
this.stopwatch = stopwatch;
this.timeLabel = label;
}
#Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
switch(msg.what)
{
case MSG_START_TIMER:
stopwatch.start();
this.sendEmptyMessage(MSG_UPDATE_TIMER);
break;
case MSG_UPDATE_TIMER:
timeLabel.setText(stopwatch.getElapsedTimeString());
this.sendEmptyMessageDelayed(MSG_UPDATE_TIMER, REFRESH_RATE);
break;
case MSG_STOP_TIMER:
this.removeMessages(MSG_UPDATE_TIMER);
stopwatch.stop();
timeLabel.setText(stopwatch.getElapsedTimeString());
break;
}
}
So, could anyone please explain the "standard" way of updating the UI from a continuous background thread? Oh, and sorry for the long question, just wanted to be thorough.
Use runOnUiThread().
Define a Runnable:
private Runnable mRunnable = new Runnable() {
#Override
public void run() {
mTextViewOne.setText("10 miles!");
mTextViewTwo.setText("40 minutes!");
}
};
Inside your continuous thread:
runOnUiThread(mRunnable);
USe the following thread in AsyncTask... I hope this will work for you ....
Handler mHandler;
private final Runnable mRunnable = new Runnable() {
public void run() {
Call your AsyncTask Class;;;;
mHandler.postDelayed(mRunnable, 1000);
}
};