Imaginemos un mundo libre

La paz interior comienza en el momento en el que decides no permitir, que ninguna persona o evento, tome el control de tus emociones.

Archive for the ‘Android’ Category

KDE Connect: Connecting your devices to KDE

with 3 comments

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:

  • Show your phone battery next to your computer battery.
  • Share the clipboard between devices.
  • Remote control your music and videos.
  • Show phone notifications in KDE and keep them in sync.
  • Pause music/videos during a phone call.
  • Send and receive pings between phone and computer.
  • Browse the remote device filesystem using SFTP.
  • Receive and send files, URLs or plain text easily.
  • Show notifications for calls ans SMS.
  • Use your phone as a touchpad.

To make this connection possible, you need to install both: The KDE Connect software on your desktop and the KDE Connect app for your mobile device.

INSTALL KDE CONNECT ON YOUR DESKTOP

Some popular Linux distributions like Debian,  Ubuntu,  OpenSUSE,  Fedora… already have KDE Connect available on their repositories. Use your package manager to install it, but you can compile it from the source code. To install it on openSUSE & Debian use the following instructions (It should be similar on other Linux distros):

– Install the requiring packages:

openSUSE : 
sudo zypper in kdebase4-workspace-devel libqca2-devel libqjson-devel libfakekey-devel

Debian : 
sudo aptitude install kde-workspace-dev libqca2-dev libqjson-dev libxtst-dev libfakekey-dev

– Clone the repository:

git clone git://anongit.kde.org/kdeconnect-kde

– Compile it:

cd kdeconnect-kde
mkdir build
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr
make
sudo make install

– Make KDE aware of KDE Connect.

Run the following command as a non-root user:

qdbus org.kde.kded /kded loadModule kdeconnect (It should return true)

– Rebuild system configuration cache:

kbuildsycoca4 -noincremental

Once you have KDE Connect installed, you will see it in your System Settings: KDE Connect This option will be empty until your pair your desktop with your mobile. We’ll talk about it next lines.

INSTALL KDE CONNECT ON YOUR MOBILE

Currently, there is a KDE Connect Android app available on Google Play and the IPhone app is currently being developed by other Google Summer of Code student. For the Android app, version 4.1 or higher is recommended to get all the functionality, but you could still use the app in old Android versions.

  • The first time you open the KDE Connect Android app, you will see the hostname of your desktop:

KDE Connect Android app

CONNECT DESKTOP AND MOBILE

Now you need to pair your devices. It’s so simple, the only requirement is that your mobile and desktop must be connected to the same Wi-Fi network.

  • Click on your hostname and request pairing:

KDE Connect Android app

  • A notification will appear on your desktop:

KDE Connect pairing request

  • You should accept the request you send from desktop to mobile too:

KDE Connect pairing requested

  • Once you have accepted, the desktop is listed on the connected devices view:

KDE Connect connected devices

  • After the successful pairing you can enable/disable the features and plugins you need in the KDE Connect Settings:

KDE Connect Settings

TESTING THE PAIRING

  • Send a ping from your device to the desktop and vice versa:

KDE Connect mobile ping KDE Connect desktop ping

START HAVING FUN

  • On your mobile, when you click on your device connected you will an option to select/deselect plugins:

KDE Connect Android plugins KDE Connect Android plugins

  • Control your media player from your mobile:

KDE Connect control media player

  •  Send a file from mobile to desktop.  KDE Connect is now listed on your apps to share content.

KDE Connect Android send file KDE Connect desktop file received

  • Use your mobile as a touchpad. Actually, this is one of my favorite features, use your mobile to control your desktop windows, tabs and other stuff is amazing.

KDE Connect Android touchpad

  • Send a file from desktop to mobile:

KDE Connect desktop send file KDE Connect desktop received file

  • Also, there is a Plasmoid (Widget) for your KDE desktop, where you can see your devices:

KDE Connect Plasmoid Other features include get notifications on your desktop when you receive a phone call or an SMS, copy an URL on your mobile and open it on your desktop, etc. These are just some examples of what you can do with KDE Connect As you can see the technology has great potential and a very promising future.

Happy KDE Connect

Advertisements

Written by Ronny Yabar

August 21, 2014 at 10:14 am

Android QR Code Scanner – Quick Guide

leave a comment »

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.

1.- Add ZXing to your project.

In particular, we need two Zxing classes, IntentIntegrator and IntentResult. 
Add them easily to your project. In your source directory create another package. Right click and select New -> Package. Let’s call it com.google.zxing.integration.android  and save the classes.  You can find the code here.

Then, in our activity code, we just need to import these classes:

import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;

Once, we have add ZXing to our project, we can start working on our app.

2.- Create the layout.

We need a Button to call the Barcode Scanner app and a TextView to see the qr code content scanned.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="com.qr.scanner.MainActivity">

    <Button
        android:id="@+id/button_get_qr_code"
        android:layout_centerHorizontal="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/get_qr_code" />

    <TextView
        android:id="@+id/text_view_qr_content"
        android:layout_below="@+id/button_get_qr_code"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>

Obviously, we have a  <string name=”get_qr_code”>Get QR Code</string> in the strings.xml file.

3.- Create the Activity and the scanning code.

Find the layout widgets and create a method with “Get QR Code” logic:

import android.content.Intent;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

...

public class MainActivity extends Activity {
    private static final String TAG = "QR Scanner";
    private Activity mActivity;
    private Button mGetQRButton;
    private TextView mQRCodeTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mActivity = this;
        mGetQRButton = (Button) findViewById(R.id.button_get_qr_code);
        mQRCodeTextView = (TextView) findViewById(R.id.text_view_qr_content);
        setupButton();
    }

In the setupButton method, create an instant of the IntentIntegrator class and call the initiateScan() method to start scanning.

    private void setupButton() {
        mGetQRButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                IntentIntegrator integrator = new IntentIntegrator(mActivity);
                integrator.initiateScan();
            }
        });
    }

4.- Get the Scanning results.

Now, we are going to use the IntentResult class, to get the scanned data and show it in our Activity.

The IntentIntegrator will return this data to the onActivityResult method of the calling activity. Create and instant of the IntentResult class. Call the getContents() method of the scanning result and save the returned data in a string.

Finally, update your textview text with this string. It’s always useful to log what we are getting.

    public void onActivityResult(int requestCode, int resultCode, Intent intent) {
        IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
        if (scanResult != null) {
            String scanContent = scanResult.getContents();
            mQRCodeTextView.setText(scanContent);
            Log.d(TAG, "QR Scan Content: " + scanContent);
        }
    }

You can see the full example at my GitHub account:

Written by Ronny Yabar

January 24, 2014 at 12:05 pm

Joel on Software

leave a comment »

Joel Spolsky is a famous blogger in the software world. He’s an ex-Microsoft employee who worked in the Excel team, is the Co-Founder of Fog Creek, a software company with a great culture and successful products like Trello, FofBugz, Copilot, CityDesk… By the way, the Fog Creek culture is really simple and is summarized like this:

Best Working Conditions -> Best Programmers -> Best Software -> Profit

It’s really funny (Life is to too short, we have to laugh and smile), how some managers still don’t understand this and make the programmers job really painful. Wake up! Wake up! managers.

Joel started writing articles in 2000 and has influenced the way of thinking of many people around the globe. Although, he’s not very active today, he has written really great articles about Software Development, Programming, Design, Startups, Recruiting and Interviews.

If you are a Software Developer, CEO, Team Leader, Product Manager, Startup founder, CS student or just work in the Software Industry, I think you will find these articles really interesting.

You can find all those articles in his blog or you can buy the two books with his writings in Amazon. I really enjoy reading in a tablet too. So, instead of buying the two books, I downloaded the Joel on Software Android app, created by the software company Digicorp. You can use the app, even without an Internet connection. Thanks guys!.

Joel on Software - Android App

These are my favorite articles, in no particular order:

Go and read, buy or download the Joel on Software stuff, it’s worth reading.

Written by Ronny Yabar

October 8, 2013 at 11:44 am

Android Code Snippets: Improving Layout Performance

leave a comment »

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;
    }

Written by Ronny Yabar

September 7, 2013 at 11:17 am

Android Code Snippets: Getting the device metrics

leave a comment »

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;
    }

...

Written by Ronny Yabar

August 3, 2013 at 1:21 pm

Android Code Snippets: Adapter notifyDataSetChanged()

leave a comment »

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

Written by Ronny Yabar

August 2, 2013 at 1:18 pm

Android Code Snippets: Get User Accounts by domain

leave a comment »

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” />

Written by Ronny Yabar

July 4, 2013 at 12:47 pm