Android - Material Design colors.xml

As a good slack guy I searched on the internet for an complete colors.xml with material design color values. Thank you to Harshad Kale GitHub.
colors.xml








    #FFEBEE
    #FFCDD2
    #EF9A9A
    #E57373
    #EF5350
    #F44336
    #E53935
    #D32F2F
    #C62828
    #B71C1C
    #FF8A80
    #FF5252
    #FF1744
    #D50000

    #EDE7F6
    #D1C4E9
    #B39DDB
    #9575CD
    #7E57C2
    #673AB7
    #5E35B1
    #512DA8
    #4527A0
    #311B92
    #B388FF
    #7C4DFF
    #651FFF
    #6200EA

    #E1F5FE
    #B3E5FC
    #81D4FA
    #4FC3F7
    #29B6F6
    #03A9F4
    #039BE5
    #0288D1
    #0277BD
    #01579B
    #80D8FF
    #40C4FF
    #00B0FF
    #0091EA

    #E8F5E9
    #C8E6C9
    #A5D6A7
    #81C784
    #66BB6A
    #4CAF50
    #43A047
    #388E3C
    #2E7D32
    #1B5E20
    #B9F6CA
    #69F0AE
    #00E676
    #00C853

    #FFFDE7
    #FFF9C4
    #FFF59D
    #FFF176
    #FFEE58
    #FFEB3B
    #FDD835
    #FBC02D
    #F9A825
    #F57F17
    #FFFF8D
    #FFFF00
    #FFEA00
    #FFD600

    #FBE9E7
    #FFCCBC
    #FFAB91
    #FF8A65
    #FF7043
    #FF5722
    #F4511E
    #E64A19
    #D84315
    #BF360C
    #FF9E80
    #FF6E40
    #FF3D00
    #DD2C00

    #ECEFF1
    #CFD8DC
    #B0BEC5
    #90A4AE
    #78909C
    #607D8B
    #546E7A
    #455A64
    #37474F
    #263238

    #FCE4EC
    #F8BBD0
    #F48FB1
    #F06292
    #EC407A
    #E91E63
    #D81B60
    #C2185B
    #AD1457
    #880E4F
    #FF80AB
    #FF4081
    #F50057
    #C51162

    #E8EAF6
    #C5CAE9
    #9FA8DA
    #7986CB
    #5C6BC0
    #3F51B5
    #3949AB
    #303F9F
    #283593
    #1A237E
    #8C9EFF
    #536DFE
    #3D5AFE
    #304FFE

    #E0F7FA
    #B2EBF2
    #80DEEA
    #4DD0E1
    #26C6DA
    #00BCD4
    #00ACC1
    #0097A7
    #00838F
    #006064
    #84FFFF
    #18FFFF
    #00E5FF
    #00B8D4

    #F1F8E9
    #DCEDC8
    #C5E1A5
    #AED581
    #9CCC65
    #8BC34A
    #7CB342
    #689F38
    #558B2F
    #33691E
    #CCFF90
    #B2FF59
    #76FF03
    #64DD17

    #FFF8E1
    #FFECB3
    #FFE082
    #FFD54F
    #FFCA28
    #FFC107
    #FFB300
    #FFA000
    #FF8F00
    #FF6F00
    #FFE57F
    #FFD740
    #FFC400
    #FFAB00

    #EFEBE9
    #D7CCC8
    #BCAAA4
    #A1887F
    #8D6E63
    #795548
    #6D4C41
    #5D4037
    #4E342E
    #3E2723

    #F3E5F5
    #E1BEE7
    #CE93D8
    #BA68C8
    #AB47BC
    #9C27B0
    #8E24AA
    #7B1FA2
    #6A1B9A
    #4A148C
    #EA80FC
    #E040FB
    #D500F9
    #AA00FF

    #E3F2FD
    #BBDEFB
    #90CAF9
    #64B5F6
    #42A5F5
    #2196F3
    #1E88E5
    #1976D2
    #1565C0
    #0D47A1
    #82B1FF
    #448AFF
    #2979FF
    #2962FF

    #E0F2F1
    #B2DFDB
    #80CBC4
    #4DB6AC
    #26A69A
    #009688
    #00897B
    #00796B
    #00695C
    #004D40
    #A7FFEB
    #64FFDA
    #1DE9B6
    #00BFA5

    #F9FBE7
    #F0F4C3
    #E6EE9C
    #DCE775
    #D4E157
    #CDDC39
    #C0CA33
    #AFB42B
    #9E9D24
    #827717
    #F4FF81
    #EEFF41
    #C6FF00
    #AEEA00

    #FFF3E0
    #FFE0B2
    #FFCC80
    #FFB74D
    #FFA726
    #FF9800
    #FB8C00
    #F57C00
    #EF6C00
    #E65100
    #FFD180
    #FFAB40
    #FF9100
    #FF6D00

    #FAFAFA
    #F5F5F5
    #EEEEEE
    #E0E0E0
    #BDBDBD
    #9E9E9E
    #757575
    #616161
    #424242
    #212121

    #000000
    #FFFFFF

    
    @color/indigo_500
    @color/indigo_700
    @color/pink_A200


Android - Export and Import SQLite



As I said in this post, you can find the sqlite file of your application in /data/data/APP_PACKGE_NAME/databases/DATABASE_NAME and you can interact directly with this file. In this post I'll show how to export a created sqlite and how to import some sqlite into your application.

Here is the class that I use to do it:
import android.content.Context;
import android.util.Log;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class SQLiteTools {

    private String databaseName;
    private Context context;

    public SQLiteTools(Context context, String databaseName) {
        this.context = context;
        this.databaseName = databaseName;
    }

    public boolean exportDatabase(File to) {
        File from = this.getCurrentDatabaseFile();
        if(!to.getParentFile().exists())
            to.getParentFile().mkdirs();
        return execute(from, to);
    }

    public boolean importDatabase(File from) {
        File to = this.getCurrentDatabaseFile();
        return execute(from, to);
    }

    private File getCurrentDatabaseFile() {
        return new File(context.getDatabasePath(databaseName).getPath());
    }

    private boolean execute(File from, File to){
        try {
            copyFile(from, to);
            Log.i("SQLITETOOLS FROM/TO", from.getAbsolutePath() + "/" + to.getAbsolutePath());
            return true;
        } catch (IOException e) {
            Log.i("SQLITETOOLS ERROR", e.getMessage());
        }
        return false;
    }

    private void copyFile(File from, File to) throws IOException {
        FileInputStream in = new FileInputStream(from);
        FileOutputStream out = new FileOutputStream(to);
        FileChannel fromChannel = null, toChannel = null;
        try {
            fromChannel = in.getChannel();
            toChannel = out.getChannel();
            fromChannel.transferTo(0, fromChannel.size(), toChannel);
        } finally {
            if (fromChannel != null)
                fromChannel.close();
            if (toChannel != null)
                toChannel.close();
        }
    }

}
As you can see, there are no complex operations. All what the methods do are copy the sqlite file from your application (using getDatabasePath(databaseName).getPath() to get the path) to a determined location and the inverse operation.

Example of usage:
SQLiteTools sqliteTools = new SQLiteTools(context, "yourdbname");
sqliteTools.exportDatabase(new File("/path/to/export"));
sqliteTools.importDatabase(new File("/path/from/import"));
Remember to declare in your manifest if you are intended to export to external storage:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

You can download a full example in masterapp repository on my GitHub! Master App contains a lot of examples that could help you. For this post, take a look on sqlite package.

Linux - Basic and Daily Commands



Hello folks!

Today I want to share some commands for who is starting or for who forgot some commands that could be useful in day-to-day. I won't give a detailed explanation of each command, only a basic usage of each one, a short description and sometimes tips.

I started to use Linux at Indústria Fox (place that I still working) in the beginning of 2013 when Fabio Alvaro (Linux master, my boss and teacher. See more about him at: http://fabioalvaro.blogspot.com.br/) "Wololoed" me to install Slakcware (Yeah, Rambo mode ON) in my machine. The first few days were horrible but exciting. Nowadays I still using Slackware but I also work with Debian.

Very well, let's start the list...
* the commands starting with $ means that you can do with normal users. # needs super user permission. But you will not put it to execute the commands, it's only a reference.




$ pwd
It will show to you your current path.

$ cd path
Move you to the specified path. If your path start with "/" it means that you are giving the full path that you want to go, otherwise means that you are entering in directories directly from where you are.
Tips: cd ~ will move you to the user home; cd / moves you to root directory of Linux; cd .. return one path level.

$ mv origin destiny (root needed depending of origin or destiny)
Move the origin file to destiny directory. If you are moving a directory with items inside, use -R (recursive) on the final of the command.

$ cp origin destiny (root needed depending of origin or destiny)
Copy the origin file to destiny directory. If you are copying a directory with items inside, use -R (recursive) on the final of the command.

$ rm path1 ... pathN (root needed depending of the file permission)
Remove 1 or N files specified. If you are deleting a directory, use -R (recursive) on the final of the command.

$ ssh user@host
Access via SSH (Secure Shell) the determined host with determined user.

$ scp path user@host:path
Copy file between two machines via SSH: local to host, host to local, host to host. The example above is a transfer between the machine where you are logged in and an external host. Other examples: scp user@host:path path or scp user@host:path user@host:pathIf you are copying a directory with items inside, use -R (recursive) on the final of the command. 

# ifconfig
Show the informations about your network adapters (Ethernet, WiFi...).

$ cat path
Show the content of specified file.

$ vi path
The main text editor for Unix systems. Some Linux distros come with vim, a better version of vi. It's a little bit different from other text editors, you need to edit with some commands and it's really hard for those who are used to work with another simpler editor.

$ nano path
Another text editor for Terminal but it's too much easier.

$ find -option description
Search from where you are for files containing the description value in the respective option informed. For example: find -name test.txt the command will list the path of all files from where I'm and it subfolders which the file name is test.txt. If you know only a piece of the filename, you could make a search like find -name te*.txt. For more options and tips, here is a guide: 10 Tips for Using GNU Find.

$ df
Show the amount of avaliable disk space on wich the user has reading access in block. If you aren't a Jedi or a robot then you should use the option -a to see the space in KB/MB/GB instead of blocks (df -a).

# halt
or
# poweroff
Turn off the machine immediately. You can use the option -f to force this, but it's dangerous (The finishing of the processes isn't waited and it could result in memory's data problems). If you want to run this command with other user, this user needs to be part of power group.

# reboot
Similar to halt or poweroff but the machine will boot again after turned off.

# shutdown
Similar to halt or poweroff but it's safer. All logged users will receive a message about the shutdown and if another user log in, the command is canceled.

$ uname -a
Show basic system infos like distro name and version for example.

$ history
Show the list of commands sent to Terminal of current user.

$ su
Give super user permission while the session is opened. To exit from super user mode just type exit. Root's password required.

$ sudo next_command
Command available for sudoer users that allow execute the following command as root. Root password required.

$ mkdir dir_name
Create specified directory if the user has write permission in the parent path.

# chmod permission_code path
Give the specified permission to the following path. To know what permission you should give, you need to know two things:  the kinds of permission, their values and what means each block that you give permission (usually three).
Very there are three kinds of permission:
    read (r) - 4
    write (w) - 2
    execute (x) - 1
If you use the command ln -l you can see the actual files permission (something like -rwxr--r-- or -rwxrwxrwx).  If you pay attention, you could see that we can separate in three groups after the first -111222333, where the the first one is the permissions assigned to the file owner, the second is for the group and the last for the public. For example, if the permission is -rwxr--r-- it means that the owner can read, write and execute this file and other group's members and the public can only read it. So, to give this permission for some file you just need to give execute the command chmod 744 path... But why 744? Each number position represents their respective group. The number 7 (The sum of read, write and execute values) will gives all permissions for the file owner and the number 4 only allows the groups member and the public read it.

# chown user path
Change the owner of the path passed as parameter for the respective user.

$ ln path link_path
Create a hard link of the informed path in the link path. If you user ln -s instead of only ln a symbolic link will be created. The difference between hard and symbolic link is that the hard link is a pointer to a file while the symbolic is a pointer to the specified path. It means you can rename or move the file and the hard link will still point it but if you change the file for new version, the link loses the reference and with symbolic solves this problem, but if you change the file path or rename it, you lost the reference.

$ tar options path
Tar files manager. You can extract, compact and do a lot of other things with tar files using this command. To extract a tar file you should use the option -xvf (x: extract; v: verbose (show the process progress); f: inform that the next param is file name of the archive) and inform the target file path. To compact, use -cvf (c: compact), the file to be generated and after you can inform 1 or N files to compact. To list: -tvf (t: list (? ... I don't know what's the link between t and list) and the target file.

$ cal
Show a beautiful and simple calendar.

$ date
Show the system date and time. There is a lot of options that you can use, type date --help to see.

$ mount path_to_mount path_where
Include some file system (Every file system that isn't a part of the Linux file tree, the /) into somewhere inside Linux file tree. There are some options that you can inform before specify the path_to_mount and the two most important are -t, where you can define the mount type like vfat for example, and -a, but in this case you don't pass the paths, only call for mount -a and all mounts specified at /etc/fstab will be mounted or remounted.

$ umount mounted_path
Manually unmount the specified file system.

$ ping host
Test TCP/IP connections between devices. You can use some options before the host like -c N, which will stop the ping process after N pings.

$ top
Show informations like memory and cpu usage and tasks.

$ kill process_id
Kill the process with the specified id (PID) if the invoke user has permission. You can get the PID using top command.

$ killall process_name
Kill all process with the specified that the current user has permission.

# useradd options user
Create an user. The's a lot of available option such as groups, bash file, etc. To see more about it, please visit The Complete Guide to “useradd” Command in Linux – 15 Practical Examples.

$ passwd
Change the password of some user. If you don't pass a parameter the command will understand that you want to change the password of the current user but you can specify the user if you have the permission to do this or if you are logged as root.

$ clear
Clear the terminal screen.



That's all! If you have some question, please, leave a comment so I'll replay as soon as possible!

Android - Simple CRUD with SQLite

Platform:
- Android
Difficulty level:
- Beginner
IDE:
- Android Studio

Hello everyone!

The idea of this post is help the reader step by step to create a simple CRUD App for Android using SQLite where we are going to check a list, register, edit and delete characters. Reading this post you will be able to insert, update, delete and select datas in an Android Application. To enjoy 100% of this post is required the basic knowledge in Android language and at least the minimum of Object Orientation concept.

One of the first things that every Android Developer needs to dominate is SQLite. The main method to store local data for your Android Application.

SQLite is a light and simple (but fast and efficient) database present in all Android devices. In each app, it's a file inside /databases app's instalation folder (/data/data/APP_PACKAGE_NAME/databases/DATABASE_NAME).

Very well... Let's code!









1 - Create the Project
- Open Android Studio and Start a new project called SimpleCRUD and Next;
-  Check only Phone and Tablet option with API  15. Next;





- Select Blank Activity with Fragments. Next;
- Don't alter the names of files and Finish.


2 - Add Floating Action Button
Only to create a good view for our app in a simple way :)

- Add as a dependency to your build.gradle:

dependencies {
    compile 'com.melnykov:floatingactionbutton:1.3.0'
}





 3 - Layout Time
Before the hard code, let's set up out xml files.

- First our first fragment with ListView to show our registers and the Floating Action Button for insert new items. Tip: you need an image to put on Action Button and Google provides a lot of icons here: https://www.google.com/design/icons/ in this example we'll use ic_add, download and copy the drawable content to your project into drawable folders).

fragment_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fab="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <com.melnykov.fab.FloatingActionButton
        android:id="@+id/actionButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|right"
        android:layout_margin="16dp"
        android:src="@drawable/ic_add"
        fab:fab_colorNormal="#144266"
        fab:fab_colorPressed="#ff15304c"
        fab:fab_colorRipple="#ff3b7095" />

</FrameLayout>

- Second, the character fragment which we'll insert and edit characters.
fragment_character.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fab="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:orientation="vertical">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Name:" />

        <EditText
            android:id="@+id/edtName"             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:inputType="textPersonName" />         <TextView             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:text="Race:" />         <EditText             android:id="@+id/edtRace"             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:inputType="textPersonName" />         <TextView             android:layout_width="match_parent"             android:layout_height="wrap_content"             android:text="Sex:" />         <RadioGroup
            android:id="@+id/rgSex"             android:layout_width="match_parent"             android:layout_height="wrap_content">             <RadioButton                 android:id="@+id/rbSexMale"                 android:layout_width="match_parent"                 android:layout_height="wrap_content"                 android:text="Male" />             <RadioButton
                android:id="@+id/rbSexFemale"                 android:layout_width="match_parent"                 android:layout_height="wrap_content"                 android:text="Female" />         </RadioGroup>     </LinearLayout> </ScrollView>

- A little adjust in our main activity xml (our fragment container).
activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/fragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

- For last, our menu (Icons: ic_delete and ic_done).
menu_character.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_delete"
        android:title="Delete"
        android:icon="@drawable/ic_delete"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/action_save"
        android:title="Save"
        android:icon="@drawable/ic_done"
        app:showAsAction="ifRoom" />
</menu>


4 - Code Time!
Finally the time comes :)

- Let's start adapting the Main Activity, checking if the savedInstanceState (parameter that keep your Activity's data when you recreate it) is null to instantiate and allocate the Fragment only in the first time when the Activity is created.
MainActivity.java
package com.letscodeeveryday.simplecrud;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if(savedInstanceState == null){
            getSupportFragmentManager()
                    .beginTransaction()
                    .add(R.id.fragment, new MainFragment())
                    .commit();
        }
    }
}

- The second thing to do is create the class for our Characters who will contains an id, a name, a race and a sex. It's a simple class with getters and setters as you use to create in the beginning of your Object Orientation classes. The unique difference here is three addtional functions that I'll explain later (fromCursor, toValues and toString). I'm used to create a package called model inside the main package to put this kind of classes into (it's only for organization and is recommended).
model/Character.java
package com.letscodeeveryday.simplecrud.model;

import android.content.ContentValues;
import android.database.Cursor;

import com.letscodeeveryday.simplecrud.database.tables.TableCharacter;

public class Character {

    private int id;
    private String name;
    private String race;
    private String sex;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRace() {
        return race;
    }

    public void setRace(String race) {
        this.race = race;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Character fromCursor(Cursor c){
        this.setId(c.getInt(c.getColumnIndex(TableCharacter.FIELD_ID)));
        this.setName(c.getString(c.getColumnIndex(TableCharacter.FIELD_NAME)));
        this.setRace(c.getString(c.getColumnIndex(TableCharacter.FIELD_RACE)));
        this.setSex(c.getString(c.getColumnIndex(TableCharacter.FIELD_SEX)));
        return this;
    }

    public ContentValues toValues() {
        ContentValues cv = new ContentValues();
        if(this.getId() > 0){
            cv.put(TableCharacter.FIELD_ID, this.getId());
        }
        cv.put(TableCharacter.FIELD_NAME, this.getName());
        cv.put(TableCharacter.FIELD_RACE, this.getRace());
        cv.put(TableCharacter.FIELD_SEX, this.getSex());
        return cv;
    }

    public String toString(){
        return this.getName();
    }
}

- Next step: a class for the character's table. It's important to centralize the table informations like the create statement and fields names and everytime that you need to use some reference about some field, you should use this class attributes. It makes the maintenence easier. In this step you can see a create statement example, it's like any SQL create, the peculiarity here is the data types: SQLite works only with NULL, INTEGER, REAL, TEXT and BLOB values. For more informations and tips of how to work with other data types like DATE you can check here: Datatypes In SQLite Version 3. I put it into package database/tables.
database/tables/TableCharacter.java
package com.letscodeeveryday.simplecrud.database.tables;

public class TableCharacter {
    public static String TABLE_NAME = "character";
    public static String FIELD_ID = "_id";     public static String FIELD_NAME = "name";     public static String FIELD_RACE = "race";     public static String FIELD_SEX = "sex";
    public static String CREATE_STATEMENT =             "CREATE TABLE `" + TABLE_NAME + "` (" +                     " `" + FIELD_ID + "` INTEGER PRIMARY KEY AUTOINCREMENT," +                     " `" + FIELD_NAME + "` TEXT NOT NULL," +                     " `" + FIELD_RACE + "` TEXT NOT NULL," +>                     " `" + FIELD_SEX + "` TEXT NOT NULL" +                     ")";
}

- With our character and table class in hands let's go for the main class of this project... The SQLiteOpenHelper class! This is the class responsible for create the database, aplly the database version upgrades changes, offer the database object to interact with it. Everytime when this class is instantiated it'll check if the database file exists and if it's not then the class will call the onCreate function. If you increment the database version and run it in an device that contains an older version, the functions onUpgrade is called. In this example we are going to use only the onCreate (wi event and put the database name and version fixed.
database/MyOpenHelper.java
package com.letscodeeveryday.simplecrud.database;

import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper;
import com.letscodeeveryday.simplecrud.database.tables.TableCharacter;
public class MyOpenHelper extends SQLiteOpenHelper{
    public static String DATABASE_NAME = "SimpleCRUD";     public static int DATABASE_VERSION = 1;
    public MyOpenHelper(Context context) {         super(context, DATABASE_NAME, null, DATABASE_VERSION);     }
    @Override     public void onCreate(SQLiteDatabase db) {         db.execSQL(TableCharacter.CREATE_STATEMENT);     }
    @Override     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    } }

- After of had our database created, we need to make actions with it. So, we create the Character DAO (Database Access Object). In this class where we will find actions like select, insert, update and delete for related to Character Table. This class uses MyOpenHelper class to get access to the database. For each action a connection to the database opens in beginning and close in the end. Here we can even see the functionality of the functions fromCursor and toValues create in Character class which the first one helps to create a character by Cursor (Object returned when you make a select and works like a cursor of any database: it's a pointer in the set returned by the query where you can move around the rows doing something) and toValues converts a character in a ContentValues (Object used to insert or update values in database) object. I create the package dao to put it.
dao/CharacterDAO.java
package com.letscodeeveryday.simplecrud.dao;

import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase;
import com.letscodeeveryday.simplecrud.database.MyOpenHelper; import com.letscodeeveryday.simplecrud.database.tables.TableCharacter; import com.letscodeeveryday.simplecrud.model.Character;
import java.util.ArrayList;
public class CharacterDAO {
    MyOpenHelper myOpenHelper;
    public CharacterDAO(Context context){         myOpenHelper = new MyOpenHelper(context);     }

    public ArrayList<Character> select(String where, String[] whereArgs){         ArrayList<Character> characters = new ArrayList<>();         SQLiteDatabase database = myOpenHelper.getReadableDatabase();         try{             Cursor c = database.query(TableCharacter.TABLE_NAME, new String[]{"*"}, where, whereArgs, null, null, TableCharacter.FIELD_NAME);             if(c.getCount() > 0 && c.moveToFirst()) {                 while (!c.isAfterLast()) {                     characters.add(new Character().fromCursor(c));                     c.moveToNext();                 }                 c.close();             }         }catch (Exception e){             e.printStackTrace();         }         database.close();         return characters;     }
    public long insert(Character c){         long id = -1;         SQLiteDatabase database = myOpenHelper.getWritableDatabase();         try {             id = database.insert(TableCharacter.TABLE_NAME, null, c.toValues());         }catch (Exception e){             e.printStackTrace();         }         database.close();         return id;     }
    public int update(Character c){         int rows = -1;         SQLiteDatabase database = myOpenHelper.getWritableDatabase();         try {             ContentValues cv = c.toValues();
            rows = database.update(TableCharacter.TABLE_NAME, cv, TableCharacter.FIELD_ID + " = ?", new String[]{String.valueOf(cv.getAsInteger(TableCharacter.FIELD_ID))});         }catch (Exception e){             e.printStackTrace();         }         database.close();         return rows;     }
    public int delete(int id){         int rows = -1;         SQLiteDatabase database = myOpenHelper.getWritableDatabase();         try {             rows = database.delete(TableCharacter.TABLE_NAME, TableCharacter.FIELD_ID + " = ?", new String[]{String.valueOf(id)});         }catch (Exception e){             e.printStackTrace();         }         database.close();         return rows;     }
}

- Now is time to create (or edit if you already have it) the Main Fragment. This fragment will contain the list of characters and the awesome floating action button (hmmmmm... what a modern app) to add characters. When a list item is clicked we are redirected to the register fragment with loaded fields (next step is for this) where you can delete or edit the character. On onResume event we are going to populate the list, it's important to do it in this moment because if we do it on onCreate event, when we go to the second fragment and come back, the list will not get updated. Now is the time to explain the function toString created on Character class, that's necessary because we are using the class ArrayAdapter to populate our ListView and we are giving a ArrayList of Characters. So, the ArrayAdapter will try to convert the chacters to string to show it in ListView and if we had hadn't created the toString function it'd appears a strange thing like Character@blablabla...
MainFragment.java
package com.letscodeeveryday.simplecrud;

import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView;
import com.letscodeeveryday.simplecrud.dao.CharacterDAO; import com.letscodeeveryday.simplecrud.database.tables.TableCharacter; import com.letscodeeveryday.simplecrud.model.Character; import com.melnykov.fab.FloatingActionButton;
import java.util.ArrayList;
public class MainFragment extends Fragment {
    FloatingActionButton actionButton;     ListView listView;
    ArrayList<Character> characters = new ArrayList<>();
    public MainFragment() {     }
    @Override     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {         View view = inflater.inflate(R.layout.fragment_main, container, false);
        //find views         actionButton = (FloatingActionButton) view.findViewById(R.id.actionButton)         listView = (ListView) view.findViewById(R.id.listView);
        //start listeners         actionButton.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 replaceFragment(null);             }         });         listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {             @Override             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {                 Character character = characters.get(position);                 Bundle bundle = new Bundle();                 bundle.putInt(TableCharacter.FIELD_ID, character.getId());                 replaceFragment(bundle);             }         });
        return view;     }
    @Override     public void onResume() {         //populate list         CharacterDAO characterDAO = new CharacterDAO(getActivity());         characters = characterDAO.select(null, null);         listView.setAdapter(new ArrayAdapter<>(getActivity(), android.R.layout.simple_list_item_1, characters));         super.onResume();     }
    private void replaceFragment(Bundle args) {         CharacterFragment fragment = new CharacterFragment();         if (args != null) {             fragment.setArguments(args);         }         getActivity()                 .getSupportFragmentManager()                 .beginTransaction()                 .addToBackStack(this.getClass().getName())                 .replace(R.id.fragment, fragment)                 .setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE)                 .commit();     } }

- The last thing to do is the second fragment, where is possible to insert, update and delete a character. To recovery, update and delete character, it'is important to get the Character's id passed by the Fragment before using the getArguments method
CharacterFragment.java
package com.letscodeeveryday.simplecrud;

import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.EditText; import android.widget.RadioButton; import android.widget.RadioGroup; import android.widget.Toast;
import com.letscodeeveryday.simplecrud.dao.CharacterDAO; import com.letscodeeveryday.simplecrud.database.tables.TableCharacter; import com.letscodeeveryday.simplecrud.model.Character;
import java.util.ArrayList;
public class CharacterFragment extends Fragment {
    EditText edtName, edtRace;     RadioGroup rgSex;
    public CharacterFragment() {     @Override     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {         View view = inflater.inflate(R.layout.fragment_character, container, false);         //find views         edtName = (EditText)view.findViewById(R.id.edtName);         edtRace = (EditText)view.findViewById(R.id.edtRace);         rgSex = (RadioGroup)view.findViewById(R.id.rgSex);         if(getArguments() != null){             recoveyCharacter();         }         setHasOptionsMenu(true);         return view;     }     private void recoveyCharacter(){         Bundle args = getArguments();         CharacterDAO characterDAO = new CharacterDAO(getActivity());         ArrayList<Character> characters = characterDAO.select(TableCharacter.FIELD_ID + " = ?", new String[]{String.valueOf(args.getInt(TableCharacter.FIELD_ID))});         if(characters.size() > 0){             Character character = characters.get(0);             edtName.setText(character.getName());             edtRace.setText(character.getRace());             if(character.getSex().equals("M")){                 RadioButton rb = (RadioButton)rgSex.findViewById(R.id.rbSexMale);                 rb.setChecked(true);             }else{                 RadioButton rb = (RadioButton)rgSex.findViewById(R.id.rbSexFemale);                 rb.setChecked(true);             }         }     }     private void saveCharacter(){         CharacterDAO characterDAO = new CharacterDAO(getActivity());         if(checkFields()) {             Character character = new Character();             character.setName(edtName.getText().toString().trim());             character.setRace(edtRace.getText().toString().trim());             switch (rgSex.getCheckedRadioButtonId()){                 case R.id.rbSexMale:                     character.setSex("M");                     break;                 case R.id.rbSexFemale:                     character.setSex("F");                     break;             }             if(getArguments() != null){                 character.setId(getArguments().getInt(TableCharacter.FIELD_ID));                 characterDAO.update(character);             }else{                 characterDAO.insert(character);             }             popThisFragment();         }     }     private void deleteCharacter(){         CharacterDAO characterDAO = new CharacterDAO(getActivity());         characterDAO.delete(getArguments().getInt(TableCharacter.FIELD_ID));         popThisFragment();     }     private boolean checkFields(){         String error = "";         if(edtName.getText().toString().trim().length() < 1){             error += "- Name required\n";         }         if(edtRace.getText().toString().trim().length() < 1){             error += "- Race required\n";         }         switch (rgSex.getCheckedRadioButtonId()){             case R.id.rbSexMale:             case R.id.rbSexFemale:                             default:                 error += "- Sex required\n";         }         if(error.equals("")){             return true;         }         Toast.makeText(getActivity(), error, Toast.LENGTH_LONG).show();         return false;>     }     private void popThisFragment(){         getActivity().getSupportFragmentManager().popBackStack();     }     @Override     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {         super.onCreateOptionsMenu(menu, inflater);         inflater.inflate(R.menu.menu_character, menu);         if(getArguments() == null){             menu.findItem(R.id.action_delete).setVisible(false);         }     }     @Override     public boolean onOptionsItemSelected(MenuItem item) {         switch (item.getItemId()){             case R.id.action_save:                 saveCharacter();                 break;             case R.id.action_delete:                 deleteCharacter();                 break;         }         return super.onOptionsItemSelected(item);     } }

5 - Build and Run
Eyes of the Tiger!

- Yes great warrior... If you still are here you are a champion and congratulations! Your app is ready to run.
Do it and you will see something like this:


 

Introducing the Blog and the Author


Hello everyone!
I'm Pedro Simão, brazilian, born in 1995. I've been studying Computer Science and working as developer since 2013 at Indústria Fox (check www.industriafox.com for more details), where I learned and I keep learning Android and Web development.
The goal of this Blog is to share my knowledge, posting some tutorials, articles or daily facts which can be helpful. Sometimes I'll only post an image or video about technology or fun things (we deserve some laughs).
I hope you enjoy it!