Archive July 2014

android apk NoClassDefFoundError (gradle build)

My android application is build with gradle and my apk is generated and works correctly.
After some developpement iterations, i include android-support-v4.jar library to ide project and gradle build file like following:

compile files('libs/android-support-v4.jar')

Build with gradle and install apk on avd ==> NoClassDefFoundError (class which extends class located in android-support-v4.jar library)

Solution:

./gradlew clean

And it works again

onSwipe listener without using Swipe Views

1. create SimpleGestureFilter class containing interface SimpleGestureListener

package net.witr.swipe.ui;

import android.app.Activity;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;

public class SimpleGestureFilter extends SimpleOnGestureListener{

    public final static int SWIPE_UP    = 1;
    public final static int SWIPE_DOWN  = 2;
    public final static int SWIPE_LEFT  = 3;
    public final static int SWIPE_RIGHT = 4;

    public final static int MODE_TRANSPARENT = 0;
    public final static int MODE_SOLID       = 1;
    public final static int MODE_DYNAMIC     = 2;

    private final static int ACTION_FAKE = -13; //just an unlikely number
    private int swipe_Min_Distance = 100;
    private int swipe_Max_Distance = 1000;
    private int swipe_Min_Velocity = 0;

    private int mode             = MODE_DYNAMIC;
    private boolean running      = true;
    private boolean tapIndicator = false;

    private Activity context;
    private GestureDetector detector;
    private SimpleGestureListener listener;

    public SimpleGestureFilter(Activity context,SimpleGestureListener sgl) {

        this.context = context;
        this.detector = new GestureDetector(context, this);
        this.listener = sgl;
    }

    public void onTouchEvent(MotionEvent event){

        if(!this.running)
            return;

        boolean result = this.detector.onTouchEvent(event);

        if(this.mode == MODE_SOLID)
            event.setAction(MotionEvent.ACTION_CANCEL);
        else if (this.mode == MODE_DYNAMIC) {

            if(event.getAction() == ACTION_FAKE)
                event.setAction(MotionEvent.ACTION_UP);
            else if (result)
                event.setAction(MotionEvent.ACTION_CANCEL);
            else if(this.tapIndicator){
                event.setAction(MotionEvent.ACTION_DOWN);
                this.tapIndicator = false;
            }

        }
        //else just do nothing, it's Transparent
    }

    public void setMode(int m){
        this.mode = m;
    }

    public int getMode(){
        return this.mode;
    }

    public void setEnabled(boolean status){
        this.running = status;
    }

    public void setSwipeMaxDistance(int distance){
        this.swipe_Max_Distance = distance;
    }

    public void setSwipeMinDistance(int distance){
        this.swipe_Min_Distance = distance;
    }

    public void setSwipeMinVelocity(int distance){
        this.swipe_Min_Velocity = distance;
    }

    public int getSwipeMaxDistance(){
        return this.swipe_Max_Distance;
    }

    public int getSwipeMinDistance(){
        return this.swipe_Min_Distance;
    }

    public int getSwipeMinVelocity(){
        return this.swipe_Min_Velocity;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                           float velocityY) {

        final float xDistance = Math.abs(e1.getX() - e2.getX());
        final float yDistance = Math.abs(e1.getY() - e2.getY());

        if(xDistance > this.swipe_Max_Distance || yDistance > this.swipe_Max_Distance)
            return false;

        velocityX = Math.abs(velocityX);
        velocityY = Math.abs(velocityY);
        boolean result = false;

        if(velocityX > this.swipe_Min_Velocity && xDistance > this.swipe_Min_Distance){
            if(e1.getX() > e2.getX()) // right to left
                this.listener.onSwipe(SWIPE_LEFT);
            else
                this.listener.onSwipe(SWIPE_RIGHT);

            result = true;
        }
        else if(velocityY > this.swipe_Min_Velocity && yDistance > this.swipe_Min_Distance){
            if(e1.getY() > e2.getY()) // bottom to up
                this.listener.onSwipe(SWIPE_UP);
            else
                this.listener.onSwipe(SWIPE_DOWN);

            result = true;
        }

        return result;
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        this.tapIndicator = true;
        return false;
    }

    @Override
    public boolean onDoubleTap(MotionEvent arg) {
        this.listener.onDoubleTap();;
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent arg) {
        return true;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent arg) {

        if(this.mode == MODE_DYNAMIC){        // we owe an ACTION_UP, so we fake an
            arg.setAction(ACTION_FAKE);      //action which will be converted to an ACTION_UP later.
            this.context.dispatchTouchEvent(arg);
        }

        return false;
    }

    static interface SimpleGestureListener{
        void onSwipe(int direction);
        void onDoubleTap();
    }

}

And then, your Activity must implement SimpleGestureListener interface like following

import com.android.swipe.R;
import net.witr.swipe.SimpleGestureFilter.SimpleGestureListener;
import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.Toast;
 
public class WitrActivity extends Activity implements SimpleGestureListener{

    private SimpleGestureFilter detector;
          
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.witr);
          
        // Detect touched area 
        detector = new SimpleGestureFilter(this,this);
    }
          
    @Override
    public boolean dispatchTouchEvent(MotionEvent me){
        // Call onTouchEvent of SimpleGestureFilter class
         this.detector.onTouchEvent(me);
       return super.dispatchTouchEvent(me);
    }

    @Override
    public void onSwipe(int direction) {

      String str = "";
      
      switch (direction) {
      
      case SimpleGestureFilter.SWIPE_RIGHT :
          str = "Swipe Right";
          break;
      case SimpleGestureFilter.SWIPE_LEFT :
          str = "Swipe Left";
          break;
      case SimpleGestureFilter.SWIPE_DOWN :
          str = "Swipe Down";
          break;
      case SimpleGestureFilter.SWIPE_UP :
          str = "Swipe Up";
          break;      
      }

      Toast.makeText(this, str, Toast.LENGTH_SHORT).show();

    }
      
    @Override
    public void onDoubleTap() {
        Toast.makeText(this, "Double Tap", Toast.LENGTH_SHORT).show();
    }
          
}

Reference : here

play your apk file on android emulator

you have already installed android studio or android sdk.
you have already configure your avd (android virtual device)

1. list your AVDs

> cd $ANDROID_SDK_HOME
> ./tools/android list avds

result looks like

Available Android Virtual Devices:
Name: AVD_for_Nexus_S_by_Google
Path: /home/witr/.android/avd/AVD_for_Nexus_S_by_Google.avd
Target: Android 4.2.2 (API level 17)
ABI: armeabi-v7a
Skin: 480×800
———
Name: AVD_for_Galaxy_Nexus_by_Google
Path: /home/witr/.android/avd/AVD_for_Galaxy_Nexus_by_Google.avd
Target: Android 4.2.2 (API level 17)
ABI: armeabi-v7a
Skin: 720×1280

2. start emulator of @AVD_for_Galaxy_Nexus_by_Google

> ./tools/emulator @AVD_for_Galaxy_Nexus_by_Google

or

> ./tools/android avd

Then select your avd and click start

3. install your apk file
copy your apk file (e.g. myApplication.apk) in $ANDROID_SDK_HOME/platform-tools/
Once avd started, open new terminal and type

> cd $ANDROID_SDK_HOME/platform-tools
> ./adb install myApplication.apk

If install succeed you will have

* daemon not running. starting it now on port 5037 *
* daemon started successfully *
2594 KB/s (326422 bytes in 0.122s)
pkg: /data/local/tmp/myApplication.apk
Success

4. launch your application in avd
go to your avd emulator and launch myApplication

import many versions of project to svn repository

I have traditionally versionning my project by copying my project folder, rename the copy and continue work on it.

Now, I have several versions of my project in different folders: myproj_v1, myproj_v2, …
I want to import my project version by version. So, I’ll have change log.

To import like so (e.g. to http://svn.witr.net/repos/myproj), we have to type following commands:
1. copy first version in different folder

[witr@localhost] cp -r myproj_v1 myproj

2. import to svn

[witr@localhost] svn import -m "first import v1" ./myproj http://svn.witr.net/repos/myproj

3. rsync the second version

[witr@localhost] rsync -ah myproj_v2 myproj

4. force add unversionned elements

[witr@localhost] cd myproj
[witr@localhost] svn add --force * --auto-props --parents --depth infinity -q

5. commit second version

[witr@localhost] svn ci -m "commit v2"

==> repeat steps 3, 4, 5 to continue with next versions folders