Posts in the “android” category

How to copy files to an Android emulator’s data directory with ‘adb push’

As an Android developer, you can normally use the adb push command to copy files from your computer’s hard drive to an Android device. However, I just ran into a problem where I couldn’t copy files to my Android emulator’s “data” directory, i.e., the /data/data filesystem. When I tried to copy a file using this command:

$ adb push foo.jpg /data/data/com.alvinalexander.myapp/files

I got this Android error:

Android: How to load an image from a file and set on an ImageView

If you’re working with an Android application, this source code seems to work to load an image from a file:

Bitmap bitmap = BitmapFactory.decodeFile(pathToPicture);

The Bitmap and BitmapFactory classes are located in the android.graphics package:

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

Assuming that your pathToPicture is correct, you can then add this bitmap image to an ImageView like this:

An Android GridView of text quotes (Fragment, layout, and AsyncTask source code)

Before I completely delete this code from my current Android application, I want to make a copy of it here. It was intended to show a series of quotes (text phrases) in a “Grid” (GridView), but (a) I never got it working as desired, and (b) I decided I didn’t want it in my application anyway.

Here’s the source code for the Java controller/fragment class:

XO Play (Android football game)

XO Play is a “thinking man’s” football game that I created for Android devices. It’s for those of us who enjoy thinking about football strategy, of how to take advantage of our strengths and our opponents’ weaknesses, and how to call plays to win games. If you’ve ever watched a football game and thought, “I can call plays better than this guy,” XO Play is for you.

Version 1.4

Version 1.4 introduces four game levels you can choose from:

Android: How to attach an extra to an Intent/PendingIntent in a Notification (solution)

I’m working on a very small Android “notifications” app where I a) display a notification using a background service, b) the user taps the notification, which c) takes them to a view that shows the full text of the notification. To get this to work, I need to send the full text along with the notification. However, this didn’t work easily. The text that was shown by my full view would be updated once, then never again.

After a lot of googling and trial and error, I finally got this approach in my sendNotification method working:

An Android Button click (tap) listener example

Android Button FAQ: How do I add a listener to a Button in Android?

To add a click (tap) listener to a button in Android, just get a reference to the button (typically using findViewById), then call the setOnClickListener method of the button, like this:

How to programmatically set the font size and style of an Android TextView

Android FAQ: How do I programmatically set the font size (and/or font style) for an Android TextView?

Solution: Setting the Android TextView font size programmatically is a simple two-step process. First, define everything about the font that you want to use in a resources file. For example, I put this code in a file named res/values/styles.xml:

Android Room, database I/O, and Java 8 threads

I just started working with the Android Room database persistence library, and since you’re not supposed to run things like database queries on the main thread (the UI thread), I was looking at other ways to run them.

In general, you probably won’t want to run database queries using a Thread, but just to see how Room works, I wrote this Java Thread code, and confirmed that it works as expected:

// works (pre-java8)
Thread t = new Thread() {
    public void run() {
        mAppDatabase.userDao().insert(u);
    }
};
t.start();

Since that code runs in a separate thread, it runs fine even if I enable Android’s StrictMode.

Java 8 Thread syntax

Then I thought, “Hey, if I use the Android Studio 3 Canary Preview, I can use Android’s Java 8 features,” and when I did that I was able to use this Java 8 Thread syntax for the same purpose:

// works (java8)
new Thread(() -> {
    mAppDatabase.userDao().insert(u);
}).start();

That also works, and it’s much easier to read than the old Java Thread syntax.

As a quick summary, if you want to use a Java 8 Thread with Android, I hope that last example is helpful. I don’t often interact with a database without calling back to update the UI, but when I’m writing a little test app, or testing new features like the Android Room persistence library, this is a simple approach to keep database I/O code off the main thread.

Android: How to send a message from a Thread to a Handler

As a quick example of how to use a Thread with a basic Handler in an Android application, the following code creates a view where the text in the TextView is updated to show the current date and time when the Button is tapped.

Java source code

First, here’s the Java source code for a file class named ThreadHandlerActivity:

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.os.Handler;
import android.os.Message;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import com.alvinalexander.todo.R;

public class ThreadHandlerActivity extends Activity {

    private static final String MSG_KEY = "yo";

    /**
     * perform the action in `handleMessage` when the thread calls
     * `mHandler.sendMessage(msg)`
     */
    @SuppressLint("HandlerLeak")
    private final Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            Bundle bundle = msg.getData();
            String string = bundle.getString(MSG_KEY);
            final TextView myTextView = (TextView)findViewById(R.id.myTextView);
            myTextView.setText(string);
        }
    };

    private final Runnable mMessageSender = new Runnable() {
        public void run() {
            Message msg = mHandler.obtainMessage();
            Bundle bundle = new Bundle();
            bundle.putString(MSG_KEY, getCurrentTime());
            msg.setData(bundle);
            mHandler.sendMessage(msg);
        }
    };

    private String getCurrentTime() {
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss MM/dd/yyyy", Locale.US);
        return dateFormat.format(new Date());
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_thread_example);
        final Button button = (Button) findViewById(R.id.myButton);
        button.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                handleButtonClick(v);
            }
        });
    }

    public void handleButtonClick(View view) {
        new Thread(mMessageSender).start();
    }

    @Override
    protected void onPause() {
        super.onPause();
        //TODO not sure if this is needed for this use case
        mHandler.removeCallbacks(mMessageSender);
    }

}

XML layout file

Next, here’s the layout XML for the view, from a file named activitythreadexample.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/myTextView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:height="32dp"
        android:text="TextView" />

    <Button
        android:id="@+id/myButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />

</LinearLayout>

The app

Here’s what this little app looks like in an Android emulator:

Android thread, runnabler, and handler example

Discussion

Please note that this source code is heavily based on the now-old book, Android 4.4 App Development. I was just looking into threads and handlers in Android last night, and this is a relatively simple example of how to send a message from a thread/runnable to a handler.

Note that I had to add the @SuppressLint annotation to this code. I don’t know much about handlers yet, so I need to look into why that is needed. I do know that Android Studio is telling me that the handler should be declared as a static field. (Adding the annotation isn’t 100% necessary, but it’s a nice reminder that there’s a potential problem here.)

The “Unfortunately your Android app has stopped” error message

Android error FAQ: Help, I'm developing an Android app, and I'm getting a "Unfortunately your Android app has stopped error message"; how do I fix it?

If you're getting an Android error message that looks like this:

"Unfortunately your Android app has stopped error message"

It's probably because you forgot to put a new Activity in the AndroidManifest.xml file (or at least that's been the #1 cause of this error message in my experience).

An Android method to center text when using Canvas drawText

I’m not an expert on this subject just yet, but if you want the source code for an Android method to center text that you want to use with the drawText method of the Canvas class, I know that this code works in two places in my current Android app:

A Java method to log Android memory use

As a quick note today, here’s a little Java method that I use to log Android memory use (RAM use) from an Activity or Fragment:

private void logMemoryInfo(Context context, String TAG) {
   ActivityManager activityManager = (ActivityManager) context.getSystemService(getActivity().ACTIVITY_SERVICE);
   int memoryClass = activityManager.getMemoryClass();
   ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
   activityManager.getMemoryInfo(memoryInfo);

   Log.i(TAG, "\n------------ RAM -------------");
   Log.i(TAG, "mem class: " + memoryClass);
   Log.i(TAG, "mem avail: " + memoryInfo.availMem);
   Log.i(TAG, "low mem:   " + memoryInfo.lowMemory);
   Log.i(TAG, "threshold: " + memoryInfo.threshold);

   long mb = 1024*1024;
   Runtime runtime = Runtime.getRuntime();
   Log.i(TAG, "Used Memory:  " + (runtime.totalMemory() - runtime.freeMemory()) / mb);
   Log.i(TAG, "Free Memory:  " + runtime.freeMemory()  / mb);
   Log.i(TAG, "Total Memory: " + runtime.totalMemory() / mb);
   Log.i(TAG, "Max Memory:   " + runtime.maxMemory()   / mb);
}