Tuesday, April 15, 2014

How to select devices for testing your first Android App

The are two main sources which can help you to select most popular devices:

Here is rather old statistics but still it shows main devices for testing:
http://opensignal.com/reports/fragmentation-2013/

This is best source of android devices fragmentation which i found:
http://www.appbrain.com/stats/top-android-phones

You can see that most important is to test your app on Samsung devices. And i faced this myself when with no reason on Samsung devices some features doesn't work well. In same time this features work even on old devices like nexus one.

For me the best set of test devices for now is:

  • Samsung Galaxy S3
  • Samsung Galaxy S4
  • Samsung Galaxy S Duos
  • Nexus 4
  • Nexus 5
  • Nexus 7
  • Samsung Galaxy Note 2
  • Samsung Galaxy Tab 3

Cute Floppy Bird now is in the Google Play


Finally i have published Cute Floppy Bird in the Google Play.
Yes, this is another copy of famous Flappy Bird.
But in this copy i've added some good features.

Used technologies: QML, Box2D, Javascript, Java, C++.

Test devices:

  • Motorola Droid Razr
  • Nexus One
  • Samsung Galaxy S Duos
  • Nexus s
  • Nexus 7 1st gen
  • Nexus 7 2nd gen
  • Nexus 5
  • Sone Xperia Ray
  • Samsung Galaxy S3
  • Nexus 4
  • Acer Iconia Tab A510
  • Galaxy S Plus
  • Alcatel OneTouch M'POP 5020D
  • Samsung Galaxy Fame GT-S6810
  • ASUS Transformer Pad TF300TG


Features:

  • Very simple game control like in original Flappy Bird
  • No annoying menu at start of the game, you can start play just after game is loaded
  • Landscape and portrait game mode, just rotate your device before your first tap
  • Beautiful graphics
  • The flight has been set to be realistic and gives you a great playability
  • Very good collision detection
  • Designed for Tablet & Phone

Problems:


  • Lags on Samsung devices.
  • No AdMob plugin for QT
  • Problem with sound effects in qml
  • Not working volume up/down buttons in QT apps on android



Screens:





Solutions:

Lags on Samsung devices:

I faced most of problems with game on Samsung Galaxy S3 and  Samsung Galaxy S Duos.

Lag at first play of sound:
When game starts, the first sound will be wings sound or hit sound. That first play cause lag on Samsung devices especially on Samsung Galaxy S3. It was very annoying bug.
Solution was to play empty sound at game start, so after that no lags with sound playing.

Lag at "Play Again" press:
It was for about a second on Samsung Galaxy S3. I use box2d and at first i delete all object at "Play Again" and create new scene. In QML i do it dynamically. And this object has box2d qml objects inside and this i think the main problem. This is why in future i planing upgrade box2dqml plugin.
Solved by just moving all object to start positions on "Play Again". Now all object creates only at start of the game.


No AdMob plugin for QT

This problem took week to solve. I described it in my previous post http://xanm.blogspot.com/2014/03/admob-in-qt.html

Showing/Hiding AdMob banner from QML

I needed to hide ad when game start and show it again when game over. So i added this two functions in my Activity.

   public static void showAd()  
   {  
     _instance.runOnUiThread(new Runnable() {  
       public void run() {  
         mAdView.setVisibility(Button.VISIBLE);  
       }  
     });  
   }  
   public static void hideAd()  
   {  
     _instance.runOnUiThread(new Runnable() {  
       public void run() {  
         mAdView.setVisibility(Button.INVISIBLE);  
       }  
     });  
   }  

To call them from QML i use jni
 void BirdActivity::showAd()  
 {  
   QAndroidJniObject::callStaticMethod<void>("org/qtproject/xanm/birdgame/BirdGameActivity", "showAd");  
 }  
 void BirdActivity::hideAd()  
 {  
   QAndroidJniObject::callStaticMethod<void>("org/qtproject/xanm/birdgame/BirdGameActivity", "hideAd");  
 }  

Problem with sound effects in qml

Disappearing of sound:
Lag at first play sound in the game:
For sound playing such as wings sound, new point sound i use QML SoundEffect.
First problem with it was disappearing of sound when player taps very fast to get from bottom to top of game scene. At some moment sound disappear until next (point sound or hit sound will play).
This was solved by creating 2 SoundEffects and playing them sequentially.

Not working volume up/down buttons in QT apps on android

This is big problem in QT5.2. I solved it by explicit capturing volume up/down buttons in my main Activity.

   @Override  
   public boolean onKeyDown(int keyCode, KeyEvent event)  
   {  
     if ( keyCode == KeyEvent.KEYCODE_VOLUME_UP) {  
         AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);  
         int index = am.getStreamVolume( AudioManager.STREAM_MUSIC) + 1;  
         if( index <= am.getStreamMaxVolume( AudioManager.STREAM_MUSIC))  
             am.setStreamVolume( AudioManager.STREAM_MUSIC, index, 0);  
     }  
     if( keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){  
         AudioManager am = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);  
         int index = am.getStreamVolume( AudioManager.STREAM_MUSIC) - 1;  
         if( index >= 0)  
             am.setStreamVolume( AudioManager.STREAM_MUSIC, index, 0);  
     }  
     return super.onKeyDown(keyCode, event);  
   }  


Get it on Google Play

Monday, March 31, 2014

AdMob In Qt

Hello!

When for the first time my friend told me about new qt5.2 where it is possible to develop app for android and  ios, i thought that this is the time to go to google play and app store. I know qt for a long time and love it. And i like QML which helps to develop very nice ui interfaces very fast. I developed my first game in qt rather fast, and faced big problem.
Qt 5 is rather new, so there is no plugin to add AdMob or many other monetisation services. So i have game but can't earn on it. Even it is not the great game and probably it won't be in the top :) i have a lot of good ideas.
So, i started to search for a solution!

First what i found:

  • V-play AdMob plugin - old qt, not free - so NO
  • qadmob - old qt, and old AdMob API - so NO

And after a week of searching in the internet and looking in Android documentation, Qt and Necessities  source codes, i did it.

So, let's start.
First you need to add Google Play Service (for now it contains admob java api for android) as reference project to you qt project, and this is not so easy.

Step 1
Add project.properties file to folder with your android files for qt project, and set up a reference to the library project in it:
  • android.library.reference.1=./relative/path/to/google-play-services_lib
I used relative path because with absolute i got errors.
Step 2
Run these commands inside the google-play-services_lib folder ( /path_to_android_sdk/extras/google/google_play_services/libproject/google-play-services_lib/):
  • android update lib-project --path .
  • ant clean
  • ant release

Step 3

Then you need to modify AndroidManifest.xml


add permissions to load ad:

 <uses-permission android:name="android.permission.INTERNET"/>  
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>  


add meta-data to application section:
 <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>  

add your activity to application section 
 <activity android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" android:name="com.google.android.gms.ads.AdActivity"/>  

Second you have to implement your Activity,  inherit it from  QtActivity, and add AdView
 package org.qtproject.example.admobqt;  
 import com.google.android.gms.ads.AdRequest;  
 import com.google.android.gms.ads.AdSize;  
 import com.google.android.gms.ads.AdView;  
 import com.google.android.gms.ads.AdListener;  
 import android.os.Bundle;  
 import android.view.View;  
 import android.view.ViewGroup;  
 import android.widget.Button;  
 import android.widget.RelativeLayout;  
 public class AdMobQtActivity extends org.qtproject.qt5.android.bindings.QtActivity  
 {  
   private static ViewGroup viewGroup;  
   private AdView mAdView;  
   private boolean adAdded = false;  
   @Override  
   public void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     mAdView = new AdView(this);  
     mAdView.setAdUnitId("YOUR_ADMOB_ID_HERE");  
     mAdView.setAdSize(AdSize.BANNER);  
     View view = getWindow().getDecorView().getRootView();  
     if (view instanceof ViewGroup) {  
       viewGroup = (ViewGroup) view;  
       ViewGroup.LayoutParams ad_layout_params = new ViewGroup.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, 150);  
       mAdView.setLayoutParams(ad_layout_params);  
       mAdView.setAdListener( new AdListener() {  
         public void onAdLoaded(){  
           if( adAdded)  
             return;  
           adAdded = true;  
           viewGroup.addView( mAdView);  
         }  
       });  
       AdRequest adRequest = new AdRequest.Builder()  
         .addTestDevice(AdRequest.DEVICE_ID_EMULATOR)  
         //.addTestDevice("INSERT_YOUR_HASHED_DEVICE_ID_HERE")  
         .build();  
       mAdView.loadAd( adRequest);  
     }  
   }  
   @Override  
   public void onPause() {  
     mAdView.pause();  
     super.onPause();  
   }  
   @Override  
   public void onResume() {  
     super.onResume();  
     mAdView.resume();  
   }  
   @Override  
   public void onDestroy() {  
     mAdView.destroy();  
     super.onDestroy();  
   }  
 }  
In here we get root View from current activity.
 View view = getWindow().getDecorView().getRootView();  
In Qt project this is QtLayout which is inherits from ViewGroup.




This is just check if something changes in new version of Qt.
 if (view instanceof ViewGroup)  








And we have to add AdView when ad is loaded.
       mAdView.setAdListener( new AdListener() {  
         public void onAdLoaded(){  
           if( adAdded)  
             return;  
           adAdded = true;  
           viewGroup.addView( mAdView);  
         }  
       });  


When AdView added in onCreate function of activity it won't show up when app is loaded.
You will need to minimise and maximise app to see ad in this case.
Looks like there is some problem in Qt java classes.
I think this problem is some where in QtLayout.java or QtSurface.java.

Sample Project:

AdMob-Qt5.2-Example

Usefull links:

http://qt-project.org/doc/qt-5/qtandroidextras-notification-example.html
https://gitorious.org/qadmob
http://blog.qt.digia.com/blog/2013/12/12/implementing-in-app-purchase-on-android/
http://developer.android.com/tools/projects/index.html
http://developer.android.com/tools/projects/projects-cmdline.html

PS: fixed bug with mobile app crush when trying to add mAdView second time.

Thursday, February 7, 2013

Create PDF in PHP

Not so long ago i have task to create PDF file in PHP code.
And i started with search in google.
First what i found was PHP extension libpdf i looked at it and all was ok but one it require to add new module on server. It is not a problem if you work with good skilled company but if work freelance and you communicate with manager how know nothing in PHP it became difficult.
Besides i wanted to find implemetation of this task on pure PHP.

And then i found FPDF http://www.fpdf.org/ i tried it using examples on site and all work pretty good.
But i had problem with utf8 non ASCII symbols. And this lib didn't updated for long time but it works on PHP 5.3.15 pretty well.


Finally i found fork from FPDF called TCPDF http://www.tcpdf.org/ it update rather often and have a lot of examples.
I found quick solution to my problem with non ASCII utf8 symbols.


Monitoring Routing Table in Linux (Ubuntu, Mint, etc)

In one work i our team need console program to monitor routing table in *buntu system!

And i wrote shell script for it!

It also shows MAC address and IP address of interfaces


Code in my GitHub account http://github.com/AlexMarlo/_bash/blob/master/rt.sh
also:

#!/usr/bin/env bash
progress=1
while true; do
if [ $progress -eq 1 ]; then
echo " \\"
fi
if [ $progress -eq 2 ]; then
echo " |"
fi
if [ $progress -eq 3 ]; then
echo " /"
fi
if [ $progress -eq 4 ]; then
echo " -"
progress=0
fi
progress=$[$progress+1]
if_list=`netstat -i | awk '{ if( NR != 1 && NR != 2 && index($0, "lo") == 0) {i = index($0, "\t"); print substr($0,1,5);}}'`
for if in $if_list; do
echo -ne "$if: "
ifconfig $if | grep "inet addr:" | awk '{ i = index($0, "inet addr:"); i+=10; ip = substr($0,i,length($0) - i); i = index( ip, " "); printf "%s - ", substr(ip,1,i); }'
ifconfig | grep $if | awk '{ i = index($0, "HWaddr "); i+=7; printf "%s\n", substr($0,i,length($0) - i);}'
done
echo route -n
sleep 1
clear
done

Tuesday, December 11, 2012

Second functional version of Color Get game

This is puzzle game!

Working name of the game is "Color Get ".

Rules is simple:
Find balls with same colour and tap them to delete, if there is path between them.

This is second version which is containing good functionality to play. But still no adjusting for different screen sizes.




Game written in pure Java, Android SDK.