Monday, 21 December 2015

Android expert code

source: https://codelabs.developers.google.com/android-dev-summit

Learn about Google codelabs.
This codelab will introduce you to the key Android TV concepts and the Leanback fragments. We will then walk through adding Android TV functionality to an existing mobile video app using Leanback fragments. By the end of the codelab, you'll have a single APK that you can use on both mobile and Android TV.

Monday, 2 November 2015

Friday, 30 October 2015

ImageView and FrameLayout with gestures control and position animation.

source: https://android-arsenal.com/details/1/2705


GestureViews

Maven Central
ImageView and FrameLayout with gestures control and position animation.
Main goal of this library is to make images viewing process as smooth as possible and to make it easier for developers to integrate it into their apps.

Demo video

Demo video
(Click for full demo video)

Sample app

Get it on Google Play

Usage

Add dependency to your build.gradle file:
compile 'com.alexvasilkov:gesture-views:2.0.0'
Note: min SDK version for library is 9, but it was tested mainly on 15+.

License

Copyright 2014 Alex Vasilkov

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.


Tuesday, 20 October 2015

Android Application UI Testing (with monkey and monkeyrunner)

source: http://hariniachala.blogspot.in/2011/09/android-application-ui-testing-with.html


Android Application UI Testing (with monkey and monkeyrunner)



Android has some built in UI testing tools. These tools can be used for automated UI testing. However the tools are not so simple to use. This post is an attempt to set a guideline towards using these tools.

There are 2 main UI testing tools available

1.monkey (aka. UI/Application Exerciser Monkey)

This tool is a command line based tool that can be primarily used to stress test your application UI. It is the simplest tool to use. Here's how..

Running monkey as an application UI stress tester (runs a random set of commands on the application. useful to UI stress testing)

- Open a command console.
- First direct your console to the location of the adb (Android Debug Bridge) program in the android sdk. Typically you can use the following command for this..

$cd path_to_android_sdk/platform-tools/

path_to_android_sdk should be the path to the sdk on your pc

- Now make sure you device is connected with the application running on it or that the emulator is running the application.

- To test on device issue the following command in the console

$./adb -d shell monkey -p package_name -v 1000

(replace -d with -e to test on the emulator.
package_name is the name of the application package abnd it usually begins with com.
-v specifies the number of UI events to be generated, in this case we ask it to generate 1000 random events)

Now you will see the monkey stress testing your app.

If you get force close message while running monkey you have just discovered a bug that needs fixing. You can run

./adb logcat

in the console to generate the relevant logs.


Running specific commands in monkey
The monkey tool can also be used to run a specific set of commands on the application. However it is easier to use the monkeyrunner for this purpose.

On the connected device (to run on emulator simply replace -d with -e)

./adb -d shell monkey -p package_name --port 1080 &
./adb -d forward tcp:1080 tcp:1080
telnet localhost 1080

Now the following will be printed on cmd line..

Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

Now you can type in your instructions

>tap 150 200

you can write all instruction into a script (script.txt) as below..

# monkey
tap 100 180
type 123
tap 100 280
press DEL
press DEL
press DEL
press DEL
press DEL
press DEL
press DEL
press DEL
type -460.3

now run..

./adb -d shell monkey -p package_name --port 1080 &
./adb -d forward tcp:1080 tcp:1080
nc localhost 1080 < script.txt


2. monkeyrunner

The monkeyrunner tool is an API for writing automated UI tests. You can use it to write specific scripts that run a series of commands and inspects the output by taking screenshots etc. The android SDK includes two special scripts written using monkeyrunner which help in running automated UI tests. The scripts are..

monkey_recorder.py
monkey_playback.py

Copy these scripts to /tools folder in the android sdk. Set the console path to the tools directory. Open up the application on the emulator.

You can run the recorder as follows..

./monkeyrunner monkey_recorder.py

Below is a screenshot of monkey_recorder recording actions for calculator.



Use 'Export Actions' button to export the set of actions into a script (eg: calc.mr)

now run the cal.mr script on a connected device as follows.. (first make sure the emulator is shut down)

./monkeyrunner monkey_playback.py calc.mr

For playback to run properly you need to take precautions of setting the correct wait times and using the correct press, fling, type methods in the recorder.

Conclusion: Android has a good collection of tools meant to enable UI test automation. However they still have a lot more room for improvement especially in terms of ease of use and efficiency.

References:

http://developer.android.com/guide/developing/tools/monkey.html
http://developer.android.com/guide/developing/tools/monkeyrunner_concepts.html
Android Application Testing Guide - Diego Torres Milano

Wednesday, 14 October 2015

Beware EditText on API 21

sourcehttp://blog.danlew.net/2015/09/09/dont-use-dynamic-versions-for-your-dependencies/

Beware EditText on API 21

Check out these two EditTexts. One is on an API 21 device, the other on an API 22 device.
See the difference? It's even more pronounced with "show layout bounds" enabled:
The height and vertical alignment of the EditTexts are different! This was caused by a change in the background of EditText between v21 and v22 (diff).
This change can cause sadness if your EditText is vertically aligned with otherViews, such as this case in Trello:
The text should be aligned with the icons, yet clearly it's not. The screenshot above is from 5.0; any other version of Android looks perfectly fine.
This problem crops up even if you're using AppCompat. AppCompat usually defers to the system material styles on v21+, which is the source of the problem.

Solution

Both solutions I've come up with use resource qualifiers to handle API 21 in a special manner.
One possibility is to import your own EditText background assets for API 21. Unless your app is filled with vertically-aligned EditTexts this seems like more effort than it's worth, since precision-targeting the background of EditTexts for just a single API version is tricky.
The hackier (but easier) solution is to just define different margins or paddings based on the API level. For example, I found that they're ~6dp off, so you end up with resources like this:
<!-- values/dimens.xml -->  
<dimen name="edit_text_spacing">6dp</dimen>

<!-- values-v21/dimens.xml -->  
<dimen name="edit_text_spacing">0dp</dimen>

<!-- values-v22/dimens.xml -->  
<dimen name="edit_text_spacing">6dp</dimen>  
I'd be the first to admit it's ugly, but if there's only a handful of places you're fixing the problem, it's not so bad.

Tuesday, 22 September 2015

Android App Template

1) Source: https://github.com/mwolfson/android-historian

1) Screen Flow Demo

Android Ultimate Historian - Material Design Demo

This app is designed to demonstrate the various components of the Android Support libraries, in particular, showing how to implement Material design into your app, using these controls.
This is not a complete example (but will be growing), and is intended to provide a high-level overview of many of the main controls in the Support and Design libraries:
  • AppCompatActivity
  • CoordinatorLayout
  • AppBarLayout & Toolbar
  • RecyclerView (with ItemDecorators)
    • LinearLayoutManager
    • GridLayoutManager
    • StaggeredGridLayoutManager
  • Snackbar
  • TabLayout
  • AppCompat Tinting
  • NavigationView
  • Snackbar
  • SwitchCompat
  • AlertDialog
  • CardView
  • FloatingActionButton
  • TextInputLayout
  • TextAppearance.AppCompat

Special Thanks

This project was originally forked from the Cheesesquare project. Special thanks to Chris Banes.
Item Decorator from recyclerview-playground project. Special thanks to Dave Smith (DevUnwired.

Pre-requisites

  • Android SDK, Build Tools and Support Repository for v23.0.1
====================================================================
2) Download xml template
www.wsdesign.in

Android App Code Architecture

source: http://frank-zhu.github.io/android/2014/11/22/android-app-code-architecture/

Android App Code Architecture

Andrews APP architecture building codes

Android developers engaged for two years, always wanted to organize a get their usual code developed by other projects as infrastructure development, even before finishing off one, but because of their own short-board technology of the time, would have been a bit of code behind, so today is a relatively reasonable thing to rearrange the backup code, if you are interested in previous versions can click here ---> AndroidAppCodeFramework

The new code structure I will use the following open source libraries
  • Network traffic will use these open source libraries Retrofit OKHTTP
  • Network image loading Picasso / UIL
  • View注解 Butterknife
  • DB will use the local cache CursorLoader do with contentProvider
  • JSON parsing will use GSON
  • Notify update data may use EventBus or otto instead of broadcast
  • Message Tip AppMsg instead of the system Toast
  • Round picture CircleImageView

  • adapter ListView / GridView adapters are placed in this folder
  • The main APP app put some constants and configuration files
  • The main activity base and put the base class file fragment
  • dao major release database files
   Table database database 
   datahelper database data manipulation helper class, each table help derive a class action table
  • The main fragment file fragment put different pages
  • log APP help fight LOG class, you can switch off the output LOG to be removed directly by setting compiled Gradle function mode can also be confused.
  • model data model classes folder
  • network network operating mainly put files
    base class file storage controller callback HTTP requests main storage network control APP requested class action
  • ui main discharge activity file
  • utils some help classes are placed in this folder
  • view custom VIEW file
Under every file I have done a comment, a reference to the library also gives a link address, most use a little look WIKI should have no problem. Finally, the code download address, welcome Star and Fork github CODE downloads
By the way, in order to encode more quickly, you may spend some of the IDE plug-ins will be more rapid 1, ButterKnife Plugin , an IDEA plug-in, this should tie in with this open source library ButterKnife use, an annotation library, source As Dragger, by the Great God JakeWharton hand.
2, Parcelable , Andrews data serialization plug, not a last resort before recall will not use Parcelable to serialize, because he wrote it is too much trouble, with the introduction of a plug-in, my mother no longer have to worry about me write arcelable serialized data, and this is a loud noise with a loud noise was great
More plug-in tools can look me in this blog ----> Android handy and popular plug-ins and tools

Tuesday, 15 September 2015

Fresco Image download library for android

source: http://frescolib.org/

About Fresco

Fresco is a powerful system for displaying images in Android applications. It takes care of image loading and display so you don't have to.
Fresco's image pipeline will load images from the network, local storage, or local resources. To save data and CPU, it has three levels of cache; two in memory and another in internal storage.
Fresco's Drawees show a placeholder for you until the image has loaded and automatically show to the image when it arrives. When the image goes off-screen, it automatically releases its memory.
Fresco supports Android 2.3 (Gingerbread) and later.

Splash Screens the Right Way

source: https://www.bignerdranch.com/blog/splash-screens-the-right-way/

The very idea of the splash screen makes me a little angry. Just saying the phrase makes me cringe.
Splash screens just waste your time, right? As an Android developer, when I see a splash screen, I know that some poor dev had to add a three-second delay to the code.
Then, I have to stare at some picture for three seconds until I can use the app. And I have to do this every time it’s launched. I know which app I opened. I know what it does. Just let me use it!

What Google Recommends

You may be surprised to hear that Google advocates that you use a splash screen. It’s right here in the material design spec.
This wasn’t always the case; Google used to advocate against splash screens, and even called it an anti-pattern.
Adia no splash screen
What gives?

Splash Screens the Right Way

I believe that Google isn’t contradicting itself; the old advice and the new stand together. (That said, it’s still not a good idea to use a splash screen that wastes a user’s time. Please don’t do that.)
However, Android apps do take some amount of time to start up, especially on a cold start. There is a delay there that you may not be able to avoid. Instead of leaving a blank screen during this time, why not show the user something nice? This is the approach Google is advocating. Don’t waste the user’s time, but don’t show them a blank, unconfigured section of the app the first time they launch it, either.
If you look at recent updates to Google apps, you’ll see appropriate uses of the splash screen. Take a look at the YouTube app, for example.
YouTube splash screen
The amount of time you spend looking at this splash screen is exactly the amount of time it takes the app to configure itself. This is on a cold launch, too, which means this is the slowest launch possible. If the app is cached, the splash screen will go away almost immediately.

Implementing a Splash Screen

Implementing a splash screen the right way is a little different than you might imagine. The splash view that you see has to be ready immediately, even before you can inflate a layout file in your splash activity.
So you will not use a layout file. Instead, specify your splash screen’s background as the activity’s theme background. To do this, first create an XML drawable in res/drawable.
Note: all code below is available on GitHub.
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">

    <item
        android:drawable="@color/gray"/>

    <item>
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher"/>
    </item>

</layer-list>
Here, I’ve set up a background color and an image.
Next, you will set this as your splash activity’s background in the theme. Navigate to your styles.xml file and add a new theme for your splash activity:
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

    <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/background_splash</item>
    </style>

</resources>
In your new SplashTheme, set the window background attribute to your XML drawable. Configure this as your splash activity’s theme in your AndroidManifest.xml:
<activity
    android:name=".SplashActivity"
    android:theme="@style/SplashTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
Finally, your SplashActivity class should just forward you along to your main activity:
public class SplashActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    }
}
Notice that you don’t even set up a view for this SplashActivity. The view comes from the theme. When you set up the UI for your splash activity in the theme, it is available immediately.
If you did have a layout file for your splash activity, that layout file would be visible to the user only after your app has been fully initialized, which is too late. You want the splash to be displayed only in that small amount of time before the app is initialized.

Doing it Right

With these steps completed, you will have a splash screen implemented the right way:
Sample splash screen
Armed with this knowledge, make your splash screen work the right way. Don’t waste the user’s time, but give them something nice to look at while they wait.

Friday, 11 September 2015

ResourceNestingExample

source: https://github.com/eskimoapps/ResourceNestingExample/blob/master/README.md

ResourceNestingExample

This is a demo app for android that shows how to create nested resource directories using the gradle build system.
Screenshot
The trick to nesting resource folders is to use gradle's ability to merge multiple resource folders, and set the res folder as well as the nested subfolders in the sourceSets block.
The quirk is that you can't declare a container resource folder before you declare that folder's child resource folders.
Below is the sourceSets block from the build.gradle file. Notice that the subfolders are declared first.
sourceSets {
    main {
        res.srcDirs = [
                'src/main/res/layouts/layouts_category2',
                'src/main/res/layouts',
                'src/main/res'
        ]
    }
}

Thursday, 10 September 2015

Building a chat application for Android

source : https://drive.google.com/file/d/0BwuzhQPqnYM_cWhXbDhyOUZzeVk/view


firebase_branding_r4_FINAL.png

Building a chat application for Android

Learn More



Overview

In this codelab you’ll build a chat application for Android using Firebase and Android Studio.

Screen Shot 2015-06-17 at 9.27.20 AM.pngScreen Shot 2015-06-17 at 9.25.19 AM.png

We’ll allow users to log in with an email/password combination.

What you’ll learn

  • Interacting with a Firebase Database from an Android application.
  • Using Firebase Authentication in an Android application to authenticate users.

What you’ll need

  • A test device or emulator with Android 4.1+
  • The device must have internet access to access the Firebase servers
  • While we'll show you what to do in Android Studio, this codelab does not try to explain how Android works.

Create a Firebase application


The first step is to create a Firebase application. This will be the server-side component that our Android application talks to.

  1. Login or sign up
    Screen Shot 2015-06-17 at 11.51.23 AM.png
  2. Manage the app that was automatically created for you
    Screen Shot 2015-06-17 at 11.52.12 AM.png
    This app is on Firebase's free hacker plan. This plan is great for when you're developing your app on Firebase.

  1. Any data that our Android application writes, will be visible in the Data tab
  2. In the Login & Auth tab, enable Email & Password authentication



Create a project in Android Studio


In this step we’ll create a project in Android Studio.

  1. Start Android Studio and Start a new Android Studio project
You can name the project anything you want. But in the code below, we’ve named it Nanochat

  1. Set the minimum SDK to 15 (ICS) or higher. We've left it on 19 (KitKat) here.
  2. Start with a Blank Activity
  3. We’ll leave all the defaults for this activity
  4. If the project outline is not visible on the left, click the 1:Project label
  5. Open up the main activity, which can be found in app/res/layout/activity_main.xml. In this file the root element will be a RelativeLayout and in there will be a TextView. We won’t be using the TextView, so delete it (or leave it and put a welcome message in it).
We now have a blank project in Android Studio. Let’s wire our app up to Firebase!





Connect the Android project to Firebase


Before we can start writing code that interacts with our Firebase database, we’ll need to make Android Studio aware that we’ll be using Firebase. We need to do this in two places: in the gradle build script and in our AndroidManifest.xml.

  1. open Gradle Scripts > build.gradle (Module: app)
    This file contains the steps that Android Studio uses to build our app. We'll add a reference to Firebase to it, so we can start using it.
  2. add the following line to the dependencies object at the bottom:

       compile 'com.firebase:firebase-client-android:2.3.0+'
  3. add the following to the bottom of the android object

       packagingOptions {
           exclude 'META-INF/LICENSE'
           exclude 'META-INF/LICENSE-FIREBASE.txt'
           exclude 'META-INF/NOTICE'
       }
  4. at this stage you’ll probably need to synchronize the project with the gradle files again, so Tools > Android > Sync Project with Gradle Files. Android Studio will parse the gradle files and pick up our changes.
  5. since Firebase is a hosted service, our app will need to be able to access the internet.
  6. open app > manifests > AndroidManifest.xml
  7. add this line inside the manifest element

     <uses-permission android:name="android.permission.INTERNET" />

  8. In this step we’ll also  set up the initial connection between our code and its Firebase backend.
  9. open MainActivity.java and add this code to the end of the onCreate method:

       Firebase.setAndroidContext(this);

    This code allows the Firebase client to keep its context.
  10. If Android Studio is having trouble finding the Firebase class, be sure that you’ve added the line to your gradle file and have synchronized the build file with the project.
  11. We also want to create a connection to our database. We’ll keep this connection in a member field:

       private Firebase mFirebaseRef;

    that we initialize in onCreate:

       mFirebaseRef = new Firebase("https://<your-app>.firebaseio.com");

    Be sure to replace `<your-app>` with the name of the Firebase app you created in the first section.

That’s all the setup that is required. Next up we’ll allow the user to enter a message in our app and send the message to Firebase.


Allow the user to send a message


We’re finally getting to the meat of our project. In this step we’ll allow the user to enter a message in a text box. When they then click the Send button, we will send the message to Firebase.

  1. We’ll first add the necessary views to activity_main.xml:

       <LinearLayout
           android:id="@+id/footer"
           android:layout_alignParentBottom="true"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:orientation="horizontal">
           <EditText
               android:id="@+id/message_text"
               android:layout_width="0dp"
               android:layout_weight="1"
               android:layout_height="wrap_content"
               android:singleLine="true"
               android:inputType="textShortMessage" />
           <Button
               android:layout_width="wrap_content"
               android:layout_height="wrap_content"
               android:text="Send" />
       </LinearLayout>

    So we have an EditText, where the user can enter their chat message, and a Button that they can click to send the message.
  2. In our MainActivity.java we’ll now add a member field for the EditText and initialize it at the end of the onCreate method:
  3. Next, we’ll add a method that grabs the text from the input and send it to our Firebase database:

       public void onSendButtonClick(View v) {
           String message = mMessageEdit.getText().toString();
           Map<String,Object> values = new HashMap<>();
           values.put("name", "puf");
           values.put("message", message);
           mFirebaseRef.push().setValue(values);
           mMessageEdit.setText("");
       }
  4. So we grab the message from the EditText, stuff it into a Map and send it off to Firebase. We’ll look at a way to replace that map with something more type-safe in the next section, but for now this will work.
    Also note that we hard-coded our user name for the moment. We’ll grab the user name from Firebase Authentication in the last section of this code lab.
  5. Now wire up the onSendButtonClick method to the button in main_acitivity.xml by adding this attribute to the button:

       android:onClick="onSendButtonClick"

  6. If you now run the application, you will see that it looks like the picture at the start of this section.
  7. Open the Data tab in the Firebase Dashboard of your app. You’ll see it light up green as you add new messages. Admit it, this is pretty cool!

Now that we can send messages to Firebase, it is time for the next step: making both existing and new messages show up in our Android app.


Show the (existing and new) messages


A chat app that doesn’t show existing messages is not very useful. So in this step we’ll add a list of the existing messages to our Android app. There’s a lot of ground we need to cover, so get ready for it. But at the end of this section we’ll have a fully functional chat app to show for it.


Let's take this in chunks: first you'll build a new layout that we use to display each message, then you'll create a Java class to represent each message and finally we'll get the message from Firebase and put them into a ListView.


  1. As you can see in the screenshot, each chat message has the same layout. So we’ll create a new layout XML file for the messages.
  2. Create a new layout file message_layout.xml

  3. in the layout XML, change the orientation of the LinearLayout to horizontal

       <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
           android:orientation="horizontal" android:layout_width="match_parent"
           android:layout_height="match_parent">
  4. add two TextView controls to the layout: one for the username and one for the chat message:

       <TextView
           android:id="@+id/username_text_view"
           android:text="Username"
           android:textStyle="bold"
           android:gravity="end"
           android:layout_width="0dp"
           android:layout_weight="3"
           android:layout_height="wrap_content"
           android:padding="10dp"/>

       <TextView
           android:id="@+id/message_text_view"
           android:text="Message"
           android:layout_width="0dp"
           android:layout_height="wrap_content"
           android:layout_weight="10"
           android:paddingLeft="0dp"
           android:paddingRight="10dp"
           android:paddingTop="10dp"
           android:paddingBottom="10dp"/>

    Most of these attributes are just there to make the messages look reasonable. So feel free to use your own padding and layout attributes. Just be sure to use the same R.id fields in your code that you specify in the android:id attributes in the XML.



  1. Now create a class ChatMessage.java that wraps the username and text message:

         public class ChatMessage {
             private String name;
             private String message;

             public ChatMessage() {
               // necessary for Firebase's deserializer
             }
             public ChatMessage(String name, String message) {
                 this.name = name;
                 this.message = message;
             }

             public String getName() {
                 return name;
             }

             public String getMessage() {
                 return message;
             }
         }

    As you can see, this is plain-old Java object. But it’s a POJO with some special traits. First ChatMessage follows a JavaBean pattern for its property names. The getName method is a getter for a name property, while getMessage is a getter for a message property. And second, those property names correspond to the ones we’ve been using when we sent messages to Firebase:

       public void onSendButtonClick(View v) {
           String message = mMessageEdit.getText().toString();
           Map<String,Object> values = new HashMap<>();
           values.put("name", "puf");
           values.put("message", message);
           mFirebaseRef.push().setValue(values);
           mMessageEdit.setText("");
       }


  1. With the layout for the message specified and their structure defined in a class, now you need to make a space for them in the main_activity.xml
  2. Add a ListView with android:id="@android:id/list" above the LinearLayout:

       <ListView
           android:id="@android:id/list"
           android:layout_width="match_parent"
           android:layout_height="match_parent"
           android:layout_above="@+id/footer"/>

    This is the container that all messages will be added to: one message_layout for each ChatMessage.

    The id value is very important here and must be exactly as specified: @android:id/list.
  3. Now download FirebaseListAdapter.java from https://github.com/firebase/AndroidChat/blob/master/app/src/main/java/com/firebase/androidchat/FirebaseListAdapter.java and add it to your project. This class adapts a Firebase collection so that it becomes usable in an Android ListView.
  4. Make the MainActivity class descend from ListActivity. This is a built-in Android base-class. By deriving from this, our activity will automatically have access to the ListView we added to the layout:

       public class MainActivity extends ListActivity {
  5. Now we'll make everything come together in the onCreate method of our MainActivity:

       mListAdapter = new FirebaseListAdapter<ChatMessage>(mFirebaseRef, ChatMessage.class,
                                                           R.layout.message_layout, this) {
           @Override
           protected void populateView(View v, ChatMessage model) {
               ((TextView)v.findViewById(R.id.username_text_view)).setText(model.getName());
               ((TextView)v.findViewById(R.id.message_text_view)).setText(model.getMessage());
           }
       };
       setListAdapter(mListAdapter);

    So the FirebaseListAdapter maps the data from your Firebase database into the ListView that you added to the layout. It creates a new instance of your message_layout for each ChatMessage and calls the populateView method. You override this method and put the name and message in the correct subviews.
  6. Don't worry, the worst part is behind us now. All that is left in this step is some clean-up. But before that, run your app and see that it shows all existing messages. And if you send a new message, it shows up in the emulator and in your Firebase dashboard.
  7. The cleanup is minor, but it's important to keep our code as clean as possible at all times. Remember that onSendButtonClick method that we had you write? That stuff with a Map looked a bit messy. Now that we have a ChatMessage class, we can make it a lot more readable:

       public void onSendButtonClick(View v) {
           String message = mMessageEdit.getText().toString();
           mFirebaseRef.push().setValue(new ChatMessage("puf", message));
           mMessageEdit.setText("");
       }

In this section we made our app show the chat messages. It was a lot of work, but in the end you can see that the Java code for our main activity still fits in a single screenshot.


Enable login


As a final step, we're going to allow the users of our app to log in using email and password.

  1. First add a button to the top right of activity_main.xml

       <Button
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="Login"
           android:id="@+id/login"
           android:layout_alignParentTop="true"
           android:layout_alignParentEnd="true"
           android:onClick="onLoginButtonClick" />

    Note that the button refers to an onLoginButtonClick method, which you'll create in a few minutes.
  2. Now create a new layout called dialog_signin.xml, which we'll use to model the body of the sign-in dialog

       <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
           android:orientation="vertical"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content">
         <EditText
             android:id="@+id/email"
             android:inputType="textEmailAddress"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="16dp"
             android:layout_marginLeft="4dp"
             android:layout_marginRight="4dp"
             android:layout_marginBottom="4dp"
             android:hint="Email" />
         <EditText
             android:id="@+id/password"
             android:inputType="textPassword"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="4dp"
             android:layout_marginLeft="4dp"
             android:layout_marginRight="4dp"
             android:layout_marginBottom="16dp"
             android:hint="Password"/>
       </LinearLayout>

    So we have two EditText controls under each other. The rest of the popup will be handled by a stock Android dialog.
Since your app will display the sign-in dialog as a popup, add the handling to MainActivity.java:

   public void onLoginButtonClick(View v) {
       AlertDialog.Builder builder = new AlertDialog.Builder(this);

       builder.setMessage("Enter your email address and password")
              .setTitle("Log in");

       LayoutInflater inflater = this.getLayoutInflater();
       builder.setView(inflater.inflate(R.layout.dialog_signin, null));

       builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               AlertDialog dlg = (AlertDialog) dialog;
               final String email = ((TextView)dlg.findViewById(R.id.email)).getText().toString();
               final String password =((TextView)dlg.findViewById(R.id.password)).getText().toString();

               // TODO: sign in to Firebase

           }
       });
       builder.setNegativeButton("Cancel", null);

       AlertDialog dialog = builder.create();
       dialog.show();
   }

This method builds and show the dialog, with our two text boxes as the main body. When the user clicks OK, it extracts the email address and password from the text controls.

Now wire the values that we got from the dialog to the Firebase Authentication back-end. Replace the TODO with the following code:

   mFirebaseRef.createUser(email, password, new Firebase.ResultHandler() {
       @Override
       public void onSuccess() {
           mFirebaseRef.authWithPassword(email, password, null);
       }
       @Override
       public void onError(FirebaseError firebaseError) {
           mFirebaseRef.authWithPassword(email, password, null);
       }
   });

In this code, we always try to register the user. If the user already registered that will result in onError, otherwise it will result on onSuccess.

Either way, we next call authWithPassword to authenticate the (pre-existing or just-created) user.


  1. With the above we have the registration/login flow working. But we still need to listen to when Firebase Authentication tells us the user has been authenticated, so that we can store the username and use that in the chat message instead of the hard-coded value we have now.
  2. Add a field to the class to hold the user name:

       private String mUsername;
  3. Add the end of the onCreate method, add a callback method that listens for authentication state changes in Firebase:

       mFirebaseRef.addAuthStateListener(new Firebase.AuthStateListener() {
           @Override
           public void onAuthStateChanged(AuthData authData) {
               if(authData != null) {
                   mUsername = ((String)authData.getProviderData().get("email"));
                   findViewById(R.id.login).setVisibility(View.INVISIBLE);
               }
               else {
                   mUsername = null;
                   findViewById(R.id.login).setVisibility(View.VISIBLE);
               }
           }
       });

    Firebase calls our listener whenever the authentication state changes, so whenever the user logs in or out. When the user logs in, we store their email address in our field and hide the login button.

    Firebase Authentication supports multiple authentication providers and each of them exposes a different set of data. For example, if we'd allow our users to authenticate with their existing Twitter account, we could identify them by their twitter handle.
  4. Finally, replace the hard-coded username with the field we just populated:

       mFirebaseRef.push().setValue(new ChatMessage(mUsername, message));



    We could definitely improve the layout of things. But this step has been long enough as it is. So let's wrap up with a few notes.
  5. One thing you may note is that the user stays logged in, even when they restart the app. If instead you want to sign out the user, you can call:

       mFirebaseRef.unauth();

    This will trigger the AuthStateListener we created before, which will clear the username field and re-enable the login button.
  6. If you want to know which users logged in to your application, you can find them in the Login & Auth tab of your Firebase's dashboard.

    This is also where you can configure the password reset emails that you can send to your users, in case they forgot their password.



Wrap-up


Congratulations! You've just built a fully functional multi-user chat application that uses Firebase to store the data and authentication users.
Screen Shot 2015-06-17 at 9.27.20 AM.pngScreen Shot 2015-06-17 at 9.25.19 AM.png

What we've covered

  • Interacting with a Firebase Database from an Android application.
  • Using Firebase Authentication in an Android application to authenticate users.

Next Steps


  • Add a log-out button to the app
  • Add a password-reset button to the login dialog
  • Allow the user to specify a nickname or use one of the Firebase's social authentication providers to look up their first name.
  • Get your app on the Play Store!