KDE Connect: Connecting your devices to KDE

KDE Connect

KDE Connect was initially developed as part of a KDE GSoC project in 2013 and is one of those exciting KDE projects that makes you love more this awesome community.  KDE Connect aims to communicate and connect all sort of devices to KDE and vice versa. The objective of KDE Connect is to make your devices interact with each other in a simple and efficient way. Some examples:  Imagine, with a single click, send a document/picture/video from your desktop to your Android phone or control your desktop media player from your mobile. KDE Connect, at the moment, support the following features: … Continue reading “KDE Connect: Connecting your devices to KDE”

Advertisements

Android QR Code Scanner – Quick Guide

In this tutorial, we are going to build a simple Android QR Scanner using ZXing, a well known Open Source library to work with bar and qr codes.

Our small QR Scanner works this way: We call the Barcode Scanner app with an Intent action, it gets the QR Code and send it back to our app.

One problem, is that probably the user doesn’t have the Barcode scanner app installed. In this case our QR Scanner needs to tell this the user and redirect them to Google Play in order to install it.

So, we are going to use ZXing to manage this situation… Continue reading “Android QR Code Scanner – Quick Guide”

Android Code Snippets: Improving Layout Performance

A common task in Android development, is to call the findViewById() method in your adapters.
There is a repeated use of findViewById() in each cycle, because you need to look up all the elements and update them. This can be really slow in you have hundreds of elements to show, therefore the performance is affected.

What you usually do when start working with adapters is the following:

    public View getView(final int position, View convertView, ViewGroup parent) {
        convertView = inflater.inflate(R.layout.artist_item, null);
        ImageView artistImageView = (ImageView) convertView.findViewById(R.id.artist_image);
        TextViewartistNameTextView = (TextView) convertView.findViewById(R.id.artist_name);
		
        ...Update your views
		
        return convertView;
    }

Instead, use the View Holder design pattern. This will avoid to look the views up in each cycle.

First, you need to create a ViewHolder class and group your views inside it.
Then, in your getView method, match your viewHolder elements with your views in the layout.
Finally, update your views content.

    // Hold the views
    static class ViewHolder {
        ImageView artistImageView;
        TextView artistNameTextView;
    }

    // Populate viewHolder views and set up their content.
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.artist_item, null);
            viewHolder = new ViewHolder();
            viewHolder.artistImageView = (ImageView) convertView.findViewById(R.id.artist_image);
            viewHolder.artistNameTextView = (TextView) convertView.findViewById(R.id.artist_name);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        ...Update your views here

        return convertView;
    }

Android Code Snippets: Getting the device metrics

It’s really important to know the device metrics (Height and width pixels, density, density dpi)  when working on an Android app, specially if you are dealing with fragmentation.

Android has a utility class called DisplayMetrics to get these device properties. Let’s say you need these properties in X activities.  It would be better create a utils class and get the device metrics there.

import android.util.DisplayMetrics;

Your class...
    public static float deviceDensity;
    public static int deviceDensityDpi;
    public static int deviceHeightPixels;
    public static int deviceWidthPixels;

    void getDeviceMetrics(Activity activity)  {
        DisplayMetrics metrics  =  new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
        deviceDensity = metrics.density;
        deviceDensityDpi = metrics.densityDpi;
        deviceHeight = metrics.heightPixels;
        deviceWidth = metrics.widthPixels;
    }

...

Android Code Snippets: Adapter notifyDataSetChanged()

A common error when working with adapters in Android, is not to notify your adapter when your data has changed.  If you don’t do that, you’ll receive and exception like this:

java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification.

Just call the notifyDataSetChanged() method after you modify your content.  But, maybe even if you notified your adapter, you receive an exception like this:

java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread.

That means, you need to call notifyDataSetChanged() from the UI thread.  It’s better to create a method, so you can call it at anytime:

private void notifyAdapter()  {
    activity.runOnUiThread(new Runnable()  {
        public void run() {
            listView.setAdapter(null);
            if(adapter != null) {
                adapter.notifyDataSetChanged();
             }
        }
    });
}

I assume you have a listview and adapter objects created.

Enjoy

Android Code Snippets: Get User Accounts by domain

Sometimes, when working on your Android apps, you will need to get the user accounts registered on the phone. A usual scenario, is the Login stuff, where you want to get domain specific accounts.

One way to achieve this, is to use the Account and AccountManager classes. If you want to get only accounts of an specific type, use the getAccountsByType() method.

Imagine I only want to get Google Accounts of mydomain.com

I call the method account_manager.getAccountsByType(“com.google”) to get Google accounts and for matching my domain, I use the Patterns util class that works with regular expressions. What I really need is the Patterns.EMAIL_ADDRESS pattern. Once I got these accounts, I can store them in an array and do whatever I want with them.

Here we go:

import android.accounts.Account;
import android.accounts.AccountManager;
import android.util.Log;
import android.util.Patterns;
...

import java.util.ArrayList;
import java.util.regex.Pattern;

public class LoginActivity extends Activity {
    private static final String TAG = "LOGIN";
    private static final String GOOGLE_ACCOUNT = "com.google";
    private static final String DOMAIN = "@yourdomain.com";
    private ArrayList<String> mDomainAccounts = new ArrayList<String>();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.login);
        getAccounts();
    }

    private void getAccounts() {
        AccountManager account_manager = AccountManager.get(this);
        Pattern emailPattern = Patterns.EMAIL_ADDRESS;

        if(account_manager != null) {
            Account[] accounts = account_manager.getAccountsByType(GOOGLE_ACCOUNT);
            for (Account account : accounts) {
                if (emailPattern.matcher(account.name).matches()) {
                    mDomainAccounts.add(account.name);
                    Log.i(TAG, account.name);
                }
            }
        }
    }

    ...
}

Don’t forget to add the GET_ACCOUNTS permission to your AndroidManifest:

<uses-permission android:name=”android.permission.GET_ACCOUNTS” />

Aplicaciones Android de alta calidad por Bruno Oliveira.

En un español casi perfecto,  Bruno Oliveira de Brasil y Android Developer de Google, nos explica como desarrollar aplicaciones Android de alta calidad.

Un excelente video y un “must-see” para todo desarrollador de aplicaciones móviles.  Excelente los consejos dados por Bruno, personalmente me ayudó muchísimo para seguir para seguir mejorando las habilidades como desarrollador Android.

Gracias por tu visita al blog. Puedes seguirme en Twitter haciendo click en el siguiente enlace: