Showing posts with label Android. Show all posts
Showing posts with label Android. Show all posts
0

How can I use external JARs in an Android project?

I have created an Android project and added an external JAR (hessian-4.0.1.jar) to my project. I then add the JAR to the buildpath and check it off in Order and Export.
Order and Export is ignored it seems, and all classes from the external JAR are missing in runtime.
Is there a trick to properly include the needed classes from an external JAR when building an Android application using the Eclipse Plug-In. I do not want to use ant or Maven.
Read
0

How to programatically take a screenshot on Android?

I just recently did something similar to use for sharing with social media. Here is the code that allowed my screen shot to be stored on sd card and used later for whatever your needs are:
// image naming and path  to include sd card  appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + ACCUWX.IMAGE_APPEND;   

// create bitmap screen capture
Bitmap bitmap;
View v1 = mCurrentUrlMask.getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);

OutputStream fout = null;
imageFile = new File(mPath);

try {
    fout = new FileOutputStream(imageFile);
    bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
    fout.flush();
    fout.close();

} catch (FileNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
Then, when you need to access use something like this:
Uri uri = Uri.fromFile(new File(mPath));
Read
0

How to check visibility of software keyboard in Android?

NEW ANSWER added Jan 25th 2012
Since writing the below answer, someone clued me in to the existence of ViewTreeObserver and friends, APIs which have been lurking in the SDK since version 1.
Rather than requiring a custom Layout type, a much simpler solution is to give your activity's root view a known ID, say '@+id/activityRoot', hook a GlobalLayoutListener into the ViewTreeObserver, and from there calculate the size diff between your activity's view root and the window size:
final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        int heightDiff = activityRootView.getRootView().getHeight() - activityRootView.getHeight();
        if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
            ... do something here
        }
     }
});
Easy!
ORIGINAL ANSWER
Yes it's possible, but it's far harder than it ought to be.
If I need to care about when the keyboard appears and disappears (which is quite often) then what I do is customize my top-level layout class into one which overrides onMeasure(). The basic logic is that if the layout finds itself filling significantly less than the total area of the window, then a soft keyboard is probably showing.
import android.app.Activity;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.LinearLayout;

/*
 * LinearLayoutThatDetectsSoftKeyboard - a variant of LinearLayout that can detect when 
 * the soft keyboard is shown and hidden (something Android can't tell you, weirdly). 
 */

public class LinearLayoutThatDetectsSoftKeyboard extends LinearLayout {

    public LinearLayoutThatDetectsSoftKeyboard(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public interface Listener {
        public void onSoftKeyboardShown(boolean isShowing);
    }
    private Listener listener;
    public void setListener(Listener listener) {
        this.listener = listener;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int height = MeasureSpec.getSize(heightMeasureSpec);
        Activity activity = (Activity)getContext();
        Rect rect = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top;
        int screenHeight = activity.getWindowManager().getDefaultDisplay().getHeight();
        int diff = (screenHeight - statusBarHeight) - height;
        if (listener != null) {
            listener.onSoftKeyboardShown(diff>128); // assume all soft keyboards are at least 128 pixels high
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);       
    }

    }
Then in your Activity class...
public class MyActivity extends Activity implements LinearLayoutThatDetectsSoftKeyboard.Listener {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        LinearLayoutThatDetectsSoftKeyboard mainLayout = (LinearLayoutThatDetectsSoftKeyboard)findViewById(R.id.main);
        mainLayout.setListener(this);
        ...
    }


    @Override
    public void onSoftKeyboardShown(boolean isShowing) {
        // do whatever you need to do here
    }

    ...
}
Read
0

How can I get zoom functionality for images?

Is there a common way to show a big image and enable the user to zoom in and out and pan the image?
Until now I found two ways:
  1. overwriting ImageView, that seems a little bit too much for such a common problem.
  2. using a webview but with less control over the overall layout etc.
  3. I adapted some code to create a TouchImageView that supports multitouch (>2.1). It is inspired by the book Hello, Android! (3rd edition)
    It is contained within the following 3 files TouchImageView.java WrapMotionEvent.java EclairMotionEvent.java
    TouchImageView.java
    import se.robertfoss.ChanImageBrowser.Viewer;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.Matrix;
    import android.graphics.PointF;
    import android.util.FloatMath;
    import android.util.Log;
    import android.view.MotionEvent;
    import android.view.View;
    import android.widget.ImageView;
    
    public class TouchImageView extends ImageView {
    
        private static final String TAG = "Touch";
        // These matrices will be used to move and zoom image
        Matrix matrix = new Matrix();
        Matrix savedMatrix = new Matrix();
    
        // We can be in one of these 3 states
        static final int NONE = 0;
        static final int DRAG = 1;
        static final int ZOOM = 2;
        int mode = NONE;
    
        // Remember some things for zooming
        PointF start = new PointF();
        PointF mid = new PointF();
        float oldDist = 1f;
    
        Context context;
    
    
        public TouchImageView(Context context) {
            super(context);
            super.setClickable(true);
            this.context = context;
    
            matrix.setTranslate(1f, 1f);
            setImageMatrix(matrix);
            setScaleType(ScaleType.MATRIX);
    
            setOnTouchListener(new OnTouchListener() {
    
                @Override
                public boolean onTouch(View v, MotionEvent rawEvent) {
                    WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent);
    
                    // Dump touch event to log
                    if (Viewer.isDebug == true){
                        dumpEvent(event);
                    }
    
                    // Handle touch events here...
                    switch (event.getAction() & MotionEvent.ACTION_MASK) {
                    case MotionEvent.ACTION_DOWN:
                        savedMatrix.set(matrix);
                        start.set(event.getX(), event.getY());
                        Log.d(TAG, "mode=DRAG");
                        mode = DRAG;
                        break;
                    case MotionEvent.ACTION_POINTER_DOWN:
                        oldDist = spacing(event);
                        Log.d(TAG, "oldDist=" + oldDist);
                        if (oldDist > 10f) {
                            savedMatrix.set(matrix);
                            midPoint(mid, event);
                            mode = ZOOM;
                            Log.d(TAG, "mode=ZOOM");
                        }
                        break;
                    case MotionEvent.ACTION_UP:
                        int xDiff = (int) Math.abs(event.getX() - start.x);
                        int yDiff = (int) Math.abs(event.getY() - start.y);
                        if (xDiff < 8 && yDiff < 8){
                            performClick();
                        }
                    case MotionEvent.ACTION_POINTER_UP:
                        mode = NONE;
                        Log.d(TAG, "mode=NONE");
                        break;
                    case MotionEvent.ACTION_MOVE:
                        if (mode == DRAG) {
                            // ...
                            matrix.set(savedMatrix);
                            matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
                        } else if (mode == ZOOM) {
                            float newDist = spacing(event);
                            Log.d(TAG, "newDist=" + newDist);
                            if (newDist > 10f) {
                                matrix.set(savedMatrix);
                                float scale = newDist / oldDist;
                                matrix.postScale(scale, scale, mid.x, mid.y);
                            }
                        }
                        break;
                    }
    
                    setImageMatrix(matrix);
                    return true; // indicate event was handled
                }
    
            });
        }
    
    
        public void setImage(Bitmap bm, int displayWidth, int displayHeight) { 
            super.setImageBitmap(bm);
    
            //Fit to screen.
            float scale;
            if ((displayHeight / bm.getHeight()) >= (displayWidth / bm.getWidth())){
                scale =  (float)displayWidth / (float)bm.getWidth();
            } else {
                scale = (float)displayHeight / (float)bm.getHeight();
            }
    
            savedMatrix.set(matrix);
            matrix.set(savedMatrix);
            matrix.postScale(scale, scale, mid.x, mid.y);
            setImageMatrix(matrix);
    
    
            // Center the image
            float redundantYSpace = (float)displayHeight - (scale * (float)bm.getHeight()) ;
            float redundantXSpace = (float)displayWidth - (scale * (float)bm.getWidth());
    
            redundantYSpace /= (float)2;
            redundantXSpace /= (float)2;
    
    
            savedMatrix.set(matrix);
            matrix.set(savedMatrix);
            matrix.postTranslate(redundantXSpace, redundantYSpace);
            setImageMatrix(matrix);
        }
    
    
        /** Show an event in the LogCat view, for debugging */
        private void dumpEvent(WrapMotionEvent event) {
            // ...
            String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE",
                "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };
            StringBuilder sb = new StringBuilder();
            int action = event.getAction();
            int actionCode = action & MotionEvent.ACTION_MASK;
            sb.append("event ACTION_").append(names[actionCode]);
            if (actionCode == MotionEvent.ACTION_POINTER_DOWN
                    || actionCode == MotionEvent.ACTION_POINTER_UP) {
                sb.append("(pid ").append(
                        action >> MotionEvent.ACTION_POINTER_ID_SHIFT);
                sb.append(")");
            }
            sb.append("[");
            for (int i = 0; i < event.getPointerCount(); i++) {
                sb.append("#").append(i);
                sb.append("(pid ").append(event.getPointerId(i));
                sb.append(")=").append((int) event.getX(i));
                sb.append(",").append((int) event.getY(i));
                if (i + 1 < event.getPointerCount())
                sb.append(";");
            }
            sb.append("]");
            Log.d(TAG, sb.toString());
        }
    
        /** Determine the space between the first two fingers */
        private float spacing(WrapMotionEvent event) {
            // ...
            float x = event.getX(0) - event.getX(1);
            float y = event.getY(0) - event.getY(1);
            return FloatMath.sqrt(x * x + y * y);
        }
    
        /** Calculate the mid point of the first two fingers */
        private void midPoint(PointF point, WrapMotionEvent event) {
            // ...
            float x = event.getX(0) + event.getX(1);
            float y = event.getY(0) + event.getY(1);
            point.set(x / 2, y / 2);
        }
    }
    WrapMotionEvent.java
    import android.view.MotionEvent;
    
    public class WrapMotionEvent {
    protected MotionEvent event;
    
    
    
    
        protected WrapMotionEvent(MotionEvent event) {
            this.event = event;
        }
    
        static public WrapMotionEvent wrap(MotionEvent event) {
                try {
                    return new EclairMotionEvent(event);
                } catch (VerifyError e) {
                    return new WrapMotionEvent(event);
                }
        }
    
    
    
        public int getAction() {
                return event.getAction();
        }
    
        public float getX() {
                return event.getX();
        }
    
        public float getX(int pointerIndex) {
                verifyPointerIndex(pointerIndex);
                return getX();
        }
    
        public float getY() {
                return event.getY();
        }
    
        public float getY(int pointerIndex) {
                verifyPointerIndex(pointerIndex);
                return getY();
        }
    
        public int getPointerCount() {
                return 1;
        }
    
        public int getPointerId(int pointerIndex) {
                verifyPointerIndex(pointerIndex);
                return 0;
        }
    
        private void verifyPointerIndex(int pointerIndex) {
                if (pointerIndex > 0) {
                    throw new IllegalArgumentException(
                        "Invalid pointer index for Donut/Cupcake");
                }
        }
    
    }
    EclairMotionEvent.java
    import android.view.MotionEvent;
    
    public class EclairMotionEvent extends WrapMotionEvent {
    
        protected EclairMotionEvent(MotionEvent event) {
                super(event);
        }
    
        public float getX(int pointerIndex) {
                return event.getX(pointerIndex);
        }
    
        public float getY(int pointerIndex) {
                return event.getY(pointerIndex);
        }
    
        public int getPointerCount() {
                return event.getPointerCount();
        }
    
        public int getPointerId(int pointerIndex) {
                return event.getPointerId(pointerIndex);
        }
    }
Read