Android resize a bitmap

Here is a snippet to scale down a bitmap – the original bitmap still needs to fit on memory though

InputStream bitmap = mContext.getAssets().open("image.file");
Bitmap scaledBitmap= Bitmap.createScaledBitmap(BitmapFactory.decodeStream(bitmap), 120, 120, false);
bitmap.

Android set background color of ActionBar

Here is a snipet that will set the background color of a ActionBar to a hexcolor.

final ActionBar bar = getActionBar();
 
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#000000")));

Color.parseColor will take any hexstring of a color and make it into a int.

Android: Suppressing the warning about using px in layout xml

When working with for instance the Sony SmartWatch there is a need to specify layout for the Watch in pixels (not device pixels) – as the SmartWatch is a fixed size and not dependent of the device it is connected to. When this is done the lint verification will warn about this being a bad idea, but it is possible to suppress this warning by adding the following to the xml file:

  1. add the namespace xmlns:tools=”http://schemas.android.com/tools”
  2. and then then you can disable the px-warnings by including this in your view: tools:ignore=”PxUsage”.

Example:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:background="@drawable/background"
>
 
    <View
        tools:ignore="PxUsage"
        android:id="@+id/smartWatchView"
        android:layout_width="128px"
        android:layout_height="128px"
        android:visibility="visible"
        android:layout_centerInParent="true" 
    />
 
</RelativeLayout>

Android garbage collection types

We are all used to seeing lines like “D/dalvikvm( 8285): GC_CONCURRENT freed 494K, 9% free 14648K/16071K, paused 2ms+2ms” in the logcat, but what does the types mean (why is the device Garbage collecting just then)?

From the sources “dalvik/vm/alloc/Heap.h” we find that

typedef enum {
    /* Not enough space for an "ordinary" Object to be allocated. */
    GC_FOR_MALLOC,
    /* Automatic GC triggered by exceeding a heap occupancy threshold. */
    GC_CONCURRENT,
    /* Explicit GC via Runtime.gc(), VMRuntime.gc(), or SIGUSR1. */
    GC_EXPLICIT,
    /* GC to try to reduce heap footprint to allow more non-GC'ed memory. */
    GC_EXTERNAL_ALLOC,
    /* GC to dump heap contents to a file, only used under WITH_HPROF */
    GC_HPROF_DUMP_HEAP
} GcReason;

And a slightly more expanded explanation is:
GC_FOR_MALLOC was triggered because there wasn’t enough memory left on the heap to perform an allocation.

GC_EXPLICIT means that the garbage collector has been explicitly asked to collect.

GC_CONCURRENT Is triggered when the heap has reached a certain amount of objects to collect.

GC_EXTERNAL_ALLOC is triggered when the VM is trying to reduce the amount of memory used for collectable objects, to make room for more non-collectable.

Sony Smart Extras (Smartwatch) Keeping the screen on – controlling the screen state

In the utils package there is a function that can be used to control the screen state.

    /**
     * Set the accessory screens state.
     *
     * @see Control.Intents#SCREEN_STATE_AUTO
     * @see Control.Intents#SCREEN_STATE_DIM
     * @see Control.Intents#SCREEN_STATE_OFF
     * @see Control.Intents#SCREEN_STATE_ON
     *
     * @param state The screen state.
     */
    protected void setScreenState(final int state) {
        if (Dbg.DEBUG) {
            Dbg.d("setScreenState: " + state);
        }
        Intent intent = new Intent(Control.Intents.CONTROL_SET_SCREEN_STATE_INTENT);
        intent.putExtra(Control.Intents.EXTRA_SCREEN_STATE, state);
        sendToHostApp(intent);
    }

So all we need to do in order to control the screen state is to call this with the correct screen state intent. The following example will keep the screen on

 setScreenState(Intents.SCREEN_STATE_ON);

Android: Rotate a bitmap

Here is a small sample that will rotate a bitmap.

Bitmap animation = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.eye_rotate, mBitmapOptions);
 
Bitmap bitmap = Bitmap.createBitmap(animation.getWidth(), animation.getHeight(), BITMAP_CONFIG);
bitmap.setDensity(DisplayMetrics.DENSITY_DEFAULT);
 
Matrix matrix = new Matrix();
matrix.reset();
matrix.setTranslate(0, 0);
matrix.postRotate(degrees, (animation.getWidth()/2), (animation.getHeight()/2));        	
 
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
int xPos = 0;
int yPos = 0;
Rect src = new Rect(xPos, yPos, xPos + animation.getWidth(), yPos + animation.getHeight());
Rect dst = new Rect(0, 0, animation.getWidth(), animation.getHeight());
 
canvas.drawBitmap(mBackground, src, dst, paint);
canvas.drawBitmap(animation, matrix, null);

Sony Smart Extras (Smartwatch) When using an .xml file to specify the layout of an accessory, remember the following

  • All sizes should be expressed in px. This to avoid scaling based on the phone density.
  • If an ImageView is used to show an image, we recommend that you specify layout_width and layout_height in px to avoid scaling based on the phone density.

Note: This is since the phone density is based on the phone (or tablet) you have connected the smart extension to, not the smart extension itself.

Sony Smartwatch Accelerometer sensor when is a axis positive (witch side is up)?

For the axis the values are:

  Positive value Negative value
x: The button is up The button is down
y: The Sony label is up The Sony label is down
z: The Screen is down The screen is up

Also a interesting thing to note, no matter how we all try to (when having the accelerometer using the SENSOR_STATUS_ACCURACY_HIGH) we can not get it to go past 78,15m/s^2.

Android custom dialog

This will create a custom dialog.

AlertDialog.Builder builder;
AlertDialog alertDialog;
 
Context mContext = this;
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.help_dialog, (ViewGroup) findViewById(R.id.layout_root));
 
TextView text = (TextView) layout.findViewById(R.id.text);
text.setText(getString(R.string.help_string));
 
builder = new AlertDialog.Builder(mContext);
builder.setView(layout);
alertDialog = builder.create();
 
alertDialog.show();

And create a “help_dialog.xml” this name is from the inflater

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout_root"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    >
    <TextView android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:textColor="#FFF"
        />
</LinearLayout>

LayoutInflater at android dev

Android getString(R.string.text) in a static method

Sometimes there is a need to access recourses from static methods.
In order to do this we need to pass along the Context to the method and use getString from that Context.

Example:

package com.f15ijp.android.test;
 
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.view.WindowManager;
 
public class Help {
	public static AlertDialog helpDialog(Context theContext, String helpMessage){
	AlertDialog alertDialog = new AlertDialog.Builder(theContext).create();            	
    	alertDialog.setTitle("Help");
    	alertDialog.setMessage(helpMessage);
    	alertDialog.setButton(theContext.getString(R.string.close_help_btn), new DialogInterface.OnClickListener() {
	    @Override
	    public void onClick(DialogInterface dialog, int which) {
		return;						
	    }
	});
    	WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
        lp.copyFrom(alertDialog.getWindow().getAttributes());
        lp.width = WindowManager.LayoutParams.FILL_PARENT;
        lp.height = WindowManager.LayoutParams.FILL_PARENT;
        /*by calling alertDialog.show() now and then again after setAttributes the background
         * the background activity is replaced by a black box. 
         * If this first alertDialog.show() is removed then the (current) acitivity is used as a background. 
         */
        alertDialog.show();
        alertDialog.getWindow().setAttributes(lp);
        return alertDialog;
    }
}