DEV Community

Akshay Ajay Chhajed
Akshay Ajay Chhajed

Posted on • Edited on

Strapping Django & Android Application

Have you developed an web application using Django and Thinking of extending it to android application?

Then you are at perfect place.

Let's get Started!!

Our Plan:

1] Creating the Django Web Application: We will be creating basic user profile mechanism in django web application.

2] Creating API to Communicate with Android: We will be creating the Controllers(Django Views) which will return JSON response (will act as API) Which we will catch in android application.

3] Developing Android Networking Application: We will be creating android networking app which will be communicating with Django API's.


NOTE:- You must Deploy Your web application Online such that the site must be publically Accessible(i.e It must be accessible from other devices).

Now Let's Execute Our Plan:

1] Developing Basic Student Profile Application in Django:

  • Start by creating the Django Project(basic_app) by typing following command in to the terminal: django-admin startproject basic_app

  • Create new app StudentProfile in your project:

   cd basic_app
   python manage.py startapp StudentProfile
   python manage.py createsuperuser 
Enter fullscreen mode Exit fullscreen mode

1st command will take terminal into current project directory.
2nd command is used to create StudentProfile app.
3rd command creates superuser(admin) for admin site.This command ask for username,email and password.

  • We are sort of extending basic User auth model to store the other information specific to student by providing one-to-one relation between StudentProfile and User:
    #CODE SNIPPET 1
    from django.db import models
    #Create your models here.    
    from django.db import models
    from django.contrib.auth.models import User

    class StudentProfile(models.Model):
        user = models.OneToOneField(User,on_delete=models.CASCADE,primary_key=True)
        student_id = models.CharField(max_length=7,null=False,unique=True,default='')
        profile_pic = models.ImageField(upload_to='profilepic/',null=False,default='')
        mobile_number=models.BigIntegerField(blank=True,default=9999999999)

    def __str__(self):
        return "{}".format(self.student_id)
Enter fullscreen mode Exit fullscreen mode

The Above code goes in to models.py in StudentProfile App.

  • As from code snippet 1 we are storing profile picture of the student so we must define MEDIA_URL & MEDIA_ROOT in settings & also some other settings for serving Static Files:
#CODE SNIPPET 2
#add this lines in settings.py

STATIC_URL = '/static/'

MEDIA_URL = '/media/'

STATICFILES_DIRS = [os.path.join(BASE_DIR,'assets/static/'),'']

MEDIA_ROOT = os.path.join(BASE_DIR,'assets/')
Enter fullscreen mode Exit fullscreen mode

Also in DIRS field in TEMPLATE dict in settings.py add path:['assets/static/',]
Also add 'StudentProfile' in Django Settings.py in INSTALLED_APPS at end this helps the server detecting new apps in project:

INSTALLED_APPS=[ ...,
  ...,
  'StudentProfile',]
Enter fullscreen mode Exit fullscreen mode
  • Create folder assets in project directory and inside assets create 2 folder static and profilepic (static will serve template,css,js & profilepic will store profile picture of student).

  • Once we have created model we should register the model in admin site so we can add remove edit the model instances from admin site:

#CODE SNIPPET 3
from .models import StudentProfile
from django.contrib import admin

admin.site.register(StudentProfile)
Enter fullscreen mode Exit fullscreen mode
  • Now we will define controller (Django Views) for how to render login form and how to render student information after successfull login(we are creating very basic form because our main purpose is to create api which will communicate with android):
#CODE SNIPPET 4
from django.shortcuts import render,HttpResponse,redirect
from django.contrib.auth import logout,login,authenticate
from .models import StudentProfile
from django.core import serializers
from django.contrib.auth.models import User

# Create your views here.
def Login(request):
    if request.method == 'POST':
        user=authenticate(request,username=request.POST.get('username'),password=request.POST.get('password'))
        if user is not None:
            login(request,user)
            return redirect('/display')
        else:
            return HttpResponse("Credentials are Incorrect")
    else:
        return render(request,'html/login.html',{})

def display(request):
    if request.method == 'GET':
        user    = User.objects.filter(pk = request.user.pk)[0]
        profile = StudentProfile.objects.filter(user = request.user.pk)[0]
        return render(request,'html/display.html',{'user':user,'profile':profile})

def Logout(request):
    if request.user.is_authenticated:
        logout(request)
        return redirect('/')
    else:
        return HttpResponse("ERROR:Error Logging Out")
Enter fullscreen mode Exit fullscreen mode

This code goes Into views.py in StudentProfile.

Explanation:-
1]Login:-this defination checks whether the request is 'POST' or 'GET' if It is 'GET', Then It will render the form for Signin.Else,if request is 'POST' then it will use data received from form and will try to authenticate user.If credentials are correct then user is LoggedIn else Error message is displayed.

2]display:- Once User is Successfully loggedin he is redirected to dispaly page which displays his information by rendering the html.

3]Logout:-This defination logs the user out.


NOTE:- We will just require to change our views to create the API's for communicating with android application.

  • Now we will create Urls (Routers) which will route us to different controller which will render pages for us:
#CODE SNIPPET 5
from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('StudentProfile.urls')),
]

    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Enter fullscreen mode Exit fullscreen mode

This code must be contained by basic_app urls.py file.

Explanation:-
1]urlpatterns define url for invoking different controllers which either renders or redirects.
2]include is used to include all urls of apps.
3]We are adding urlpatterns for MEDIA_ROOT ('assets/') URL will be MEDIA_URL ('/media/').This will expose Media files from project directory.

#CODE SNIPPET 6
from django.contrib import admin
from django.urls import path,include
from .views import Login,display,Logout

urlpatterns = [
    path('',Login),#Calls Login View(Homepage)
    path('display/',display),#Calls display View(After Successful Login )
    path('logout/',Logout),#Controller for logging out 
]
Enter fullscreen mode Exit fullscreen mode

This code must be contained by StudentProfile's urls.py.

  • Now we Need to Create Template's which will be render by Views:
<!--CODE SNIPPET 7-->
<!DOCTYPE html>
<html>
    <head>
        <title>LOGIN</title>
    </head>

    <body style="font-family:sans-serif;">
        <form method='POST' action=''>
        {%csrf_token%}
        <input type='text' name='username' placeholder='username'>    
        <input type='password' name='password' placeholder='password'>
        <button>SUBMIT</button>
        </form>

    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

This Templates should be stored in assets/static/html as login.html

<!--CODE SNIPPET 8-->
{% load static %}
<!DOCTYPE html>
<html>
    <body>
        <p>username:{{user.username}}</p>
        <p>firstname:{{user.first_name}}</p>
        <p>lastname:{{user.last_name}}</p>
        <p>email:{{user.email}}</p>
        <p>student_ID:{{profile.student_id}}</p>
        <p>mobile number:{{profile.mobile_number}}</p>
        <img src="/media/{{profile.profile_pic}}" height="25px" width="25px">
        <form action='/logout' method='GET'><button>LOGOUT</button></form>
    </body>
</html>
Enter fullscreen mode Exit fullscreen mode

This Templates should be stored in assets/static/html as display.html

Now We are Done with our Web App

2] Creating API's for Android Application:-As in one of the Note, I told it's very easy to create the API's.We will use same controller as created before for web application just we will have some small changes.

  • Start New Project Called api:python manage.py startapp api
  • Form & Login API:
from django.shortcuts import render,HttpResponse,redirect
from django.contrib.auth import logout,login,authenticate
from StudentProfile.models import StudentProfile
from django.core import serializers
from django.contrib.auth.models import User
from django.middleware.csrf import *

# Create your views here.
def Login(request):
    if request.method == 'POST':
        user=authenticate(request,username=request.POST.get('username'),password=request.POST.get('password'))
        if user is not None:
            login(request,user)
            return redirect('/api/display/')
        else:
            return HttpResponse("ERROR:-Credentials are Incorrect")
    else:
        if request.session.is_empty():
            return render(request,'html/api_login_workThrough.html',{})
        authenticate(request)
        print('-------------------')
        print(request.user)
        return redirect('/api/display/')

def display(request):
    if request.method == 'GET':
        user    = User.objects.filter(pk = request.user.pk)[0]
        profile = StudentProfile.objects.filter(user = request.user.pk)[0]
        return HttpResponse(serializers.serialize('json',[user,profile])) 


def Logout(request):
    if request.user.is_authenticated:
        logout(request)
        return redirect('/')
    else:
        return HttpResponse("ERROR:-Error Logging Out")
Enter fullscreen mode Exit fullscreen mode

This code should be placed in file api/views.py

Explanation:-

1]Login:-there are some minor changes in url '/api' is appended this is because now we are referring different set of controllers which we will use to communicate with application.
If the request method is 'GET' then there is significant changes in the code as compared to what we have in web app.This is because once we are logged in to the app and we close app with out logging out it must open profile page for us rither than a form.
we are checking request.session exist or not, If it exist then we will redirect to profile page directly and if it not then we will return the form containing csrf token(what is csrf and how it works we will discuss it later).

2]display:-rither than rendering the display page we are simply return JSON as HttpResponse to the apllication(i.e making controller work as REST API).we have serialize django model to JSON using serializers library provided by django itself for serializing models.


NOTE:-when request method is 'GET' and there is no session object associated with request we are rendering the page called api_login_workThrough.html,This was the work Through of which I thought of to use csrf mechanism of django to work with my android application.There may be better way,but I came up with this simple Idea.We will see how this work Through works in detail later in the article.

  • The api_login_workThrough.html resides in assets/static/html and contains:-
<form>{%csrf_token%}</form>
Enter fullscreen mode Exit fullscreen mode
  • Now we will create URLS(Routers) for API:
from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static
from .views import *

urlpatterns = [
    path('login/',Login),
    path('display/',display),
    path('logout/',Logout)
]
Enter fullscreen mode Exit fullscreen mode

This code is contain by api/urls.py.

It looks same as that of StudentProfile urls.py,Actually Its Same the difference will be made by urls.py of basic_app.

In urls.py of basic_app(Main project app) add url pattern at end:-

urlpatterns =[
               ...,
               ...,
               path('api/',include('api')), ]
Enter fullscreen mode Exit fullscreen mode

We Created API for the User Student Profile.

Now Let's get Started with Android

  • OverView of Android Apllication

Andoid Activity and Classes

AsyncRequest:-Request Response Handler

package com.example.workstation.basic;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.CookieStore;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import javax.net.ssl.HttpsURLConnection;

public class AsyncRequest extends Thread
        /* Thread is used to make the request response cycle asynchronous to help preventing the UI from being Unresponsive*/
{
    final String TAG = AsyncRequest.class.getSimpleName();

    final String domain_name;
    BasicCookieStore store;
    /*Basic Cookie Store is Persistent Cookie Store implementation for Android used to store Cookie */
    String ResponseMsg = new String();  //Response message received from (Django)server
    int  ResponseCode;                  //Response code received from server (Code: (2xx for OK),(3xx for Redirects),(4xx for ClientError),(5xx for InternalSerer Error)
    String ResponseBody = new String(); //It is Data Received from Server(HTTP response or File response or JSON response)
    Map<String,List<String>> ResponseHeader;//Response Header Received from Server



    String Url = new String();             //Url to which to send request and response
    String RequestBody = new String();     //Request Body means Data to be sent to Server
    final String RequestType;              //Type of Request(GET,POST)

    AsyncRequest(String requestType,Context context)
    /* Context is accepted for CookieStore to initialize for the Application*/
    {
        RequestType = requestType;
        store=new BasicCookieStore(context);
        domain_name=context.getResources().getString(R.string.domain_name);
    }

    @TargetApi(Build.VERSION_CODES.N)
    @Override
    public void run()
    {
        try
        {
            URL url = new URL(Url);
            URI uri = new URI(Url);
            HttpURLConnection httpconn = (HttpURLConnection) url.openConnection();
            /*HttpURLConnection is the class which establish the connection between client and server and exchange data
            * using HTTP request response cycle.
            * url.openConnection() establishes the connection between client and server */
            httpconn.setInstanceFollowRedirects(false);
            /*Sets whether HTTP redirects (requests with response code 3xx) should be automatically followed by this HttpURLConnection
             instance*/
            HttpsURLConnection.setFollowRedirects(false);
            /*Sets whether HTTP redirects (requests with response code 3xx) should be automatically followed by this class*/
            httpconn.setRequestMethod(RequestType);//set Types of Request
            String S="";
            for(HttpCookie H:store.get(new URI(domain_name)))
                S+=H+"; ";
            httpconn.setRequestProperty("Cookie",S);
            /*retriving the cookie from cookie store and sending back to the server(session_id,csrf_token,etc)*/
            if(RequestType=="POST")
            {
                DataOutputStream output=new DataOutputStream(httpconn.getOutputStream());
                output.writeBytes(RequestBody);
                output.flush();
                output.close();
            }
            /* if the request is POST  then we send data to the server this using output stream received from connection*/

            boolean redirect = false;


            // normally, 3xx is redirect
            int status = httpconn.getResponseCode();
            if (status != HttpURLConnection.HTTP_OK) {              //if request succeds then skip
                if (status == HttpURLConnection.HTTP_MOVED_TEMP
                        || status == HttpURLConnection.HTTP_MOVED_PERM
                        || status == HttpURLConnection.HTTP_SEE_OTHER)//if response code is 3xx then it is redirect request
                    redirect = true;                                  //set redirect to true
            }

            System.out.println("Response Code ... " + status);

            if(redirect) {
                // when response code 3xx then we receive redirect url in header field called "location"
                String newUrl = httpconn.getHeaderField("Location");

                // get the cookie if need, for login
                List<String> cookiesL =httpconn.getHeaderFields().get("set-cookie");
                Log.i(TAG, "run: "+httpconn.getHeaderFields());
                if(cookiesL != null)
                    for(String x:cookiesL)
                        store.add(new URI(domain_name),HttpCookie.parse(x).get(0));

                // open the new connnection again on url recived from location header
                url = new URL(domain_name+newUrl);
                uri = new URI(domain_name+newUrl);
                Log.i(TAG, "run: "+url);
                httpconn.disconnect();
                httpconn = (HttpURLConnection) url.openConnection();
                httpconn.setInstanceFollowRedirects(false);
                HttpURLConnection.setFollowRedirects(false);
                httpconn.setRequestMethod("GET"); //considered that redirect url will be GET request only
                S="";
                for(HttpCookie H:store.get(new URI(domain_name)))
                    S+=H+"; ";
                httpconn.setRequestProperty("Cookie",S);
                Log.i(TAG, "CookiesSession--: "+S);
                /*same as processed for first request*/

            }

            Log.i(TAG, "run: " + httpconn);

            this.ResponseMsg = httpconn.getResponseMessage(); //retriving  response message from httpconn object
            this.ResponseCode = httpconn.getResponseCode();//response code is retrived
            this.ResponseHeader = httpconn.getHeaderFields(); //getting header fields
            byte[] b = new byte[1024 * 1024]; // reserving the memory for responsebody
            int len;
            len = (new DataInputStream(httpconn.getInputStream())).read(b); //reads complete response body from httpconn object
            Log.i(TAG, "run: "+b.toString());
            this.ResponseBody = new String(b, 0, len); //stores in responsebody
            httpconn.disconnect();
        }
        catch(IOException e)
        {
            Log.e(TAG, "run: ",e );
        }
        catch (URISyntaxException e)
        {
            Log.e(TAG, "run: ",e );
        }

    }

    /*Getters and Setters*/

    void setUrl(String Url)
    {
        this.Url=Url;
    }


    void setRequestBody(String RequestBody)
    {
        this.RequestBody=RequestBody;
    }

    String getResponseMsg()
    {
        return ResponseMsg;
    }

    String getResponseBody()
    {
        return ResponseBody;
    }

    Map<String,List<String>> getResponseHeader()
    {
        return ResponseHeader;
    }
}

Enter fullscreen mode Exit fullscreen mode

BitmapD:-Loads the image asynchronously using url

package com.example.workstation.basic;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class BitmapD extends Thread {

    Bitmap B;
    String Url;

    public void setUrl(String Url)
    {
        this.Url=Url;
    } //Url from which to fetch image

    public void run()
    {
        try {
            Log.e("src",Url);
            URL url = new URL(Url); // converts string url to URL object
            HttpURLConnection connection = (HttpURLConnection) url.openConnection(); //establishes connection between client and server
            connection.setDoInput(true);
            connection.connect();//connection is established
            InputStream input = connection.getInputStream();//retriving input stream to retrive image data
            B= BitmapFactory.decodeStream(input);//convert input received to proper image format depending on header
            Log.e("Bitmap","returned");
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("Exception",e.getMessage());
        }
    }

    public Bitmap getBitmap()
    {
        return B;
    }//getter for fetching bitmap
}

Enter fullscreen mode Exit fullscreen mode

BasicCookieStore:-Persistent Cookie store implementation

The Implementation can be found at:Gist Repo for cookie store

This git repo contains two classes from our application viz. BasicCookieStore and SeriallizableHttpCookie,2nd class supports the first class to serialize the httpcookie object to string and store in the cookie store.

MainActivity:-Provides the Login Page for User Login

package com.example.workstation.basic;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.net.CookieStore;
import java.net.HttpCookie;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;

public class MainActivity extends AppCompatActivity {

    String domain_name;
    BasicCookieStore store;
    String csrf_token=new String();

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        domain_name=getResources().getString(R.string.domain_name);       //server domain

        store = new BasicCookieStore(this);                             //Creating CookieStore for Application
        AsyncRequest P=new AsyncRequest("GET",this);        //AsyncRequest object to snrd request
        P.setUrl(domain_name+this.getResources().getString(R.string.Login));                                    //url to which to send request
        P.start();                                                              //starting asynchronous process

        try
        {
            P.join();                                                           //procced after process P is completed
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        Log.i("FORM:---", "onCreate: "+P.getResponseBody());
        /*remember of csrf work through i told of explaining in android
          once we receive the workthrough file from server we are checking for substring at index 1 to 4 if it is word "form"
          then we are retriving the csrf token from form generated by {%csrf_token%} tag in template and store it in a variable
          In response header there is field called "set-cookie" which contains cookie to be set we retrive the data and store it in this store
         */
        if(P.getResponseBody().substring(1,5).equals("form"))
        {
            csrf_token = P.getResponseBody().substring(61, 61 + 64);
            Log.i("csrf_token:--", "onCreate: "+csrf_token);
            try {
                store.add(new URI(domain_name), HttpCookie.parse(P.getResponseHeader().get("set-cookie").get(0)).get(0));
            } catch (URISyntaxException e) {
                e.printStackTrace();
            }
        }
        /*then we check if it returns error substring if so then something has went wrong and we recreate the activity
        else
        if workthrough form  and also error is not returned then it implies that the user session was saved in cookie store and hence we directly authenticate
        user to the user data preview
         */
        else
        {
            if(P.getResponseBody().substring(0,5).equals("Error"))
            {
                this.recreate();
            }
            else
            {
                Intent dashBoard = new Intent(this,DashBoard.class); //Explicit intent creation
                this.finish();
                dashBoard.putExtra("displayData",P.getResponseBody());//sending response data to new intent i.e dashboard
                Log.i("JSON:::", "onCreate: "+P.getResponseBody());
                store.loadAllCookies();
                Log.i("VC", "SignIN: "+store.getCookies());
                startActivity(dashBoard);//starting the intent(control goes to dashboard activity)
            }

        }

    }

    // create an action bar button
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        return super.onCreateOptionsMenu(menu);
    }

    /* this is function which is triggered when user click on login button*/
    void SignIN(View B) throws MalformedURLException, URISyntaxException, InterruptedException {
        Button b = (Button)B;
        EditText usernameView = (EditText) findViewById(R.id.Email);
        EditText passwordView = (EditText) findViewById(R.id.Password);

        String username = usernameView.getText().toString(); //retriving username from username field
        String password = passwordView.getText().toString(); //retriving password from password field

        if(!username.isEmpty() && !password.isEmpty()) //username and password validations
        {
            b.setClickable(false);
            AsyncRequest P = new AsyncRequest("POST",this); //creating the login request
            P.setUrl(domain_name+this.getResources().getString(R.string.Login));//setting login url
            P.setRequestBody("username="+username+"&password="+password+"&csrfmiddlewaretoken="+csrf_token+"&LOGIN=LOGIN");
            //setting request body it contains(username,password and csrf token which is used for CSRF attack protection by django)
            P.start();//satrting the process
            P.join();//procced after process P is completed
            if(P.getResponseBody().substring(0,5).equals("ERROR"))//if response contains "ERROR" string then recreate activity
            {
                Toast.makeText(this,P.getResponseBody(),Toast.LENGTH_LONG).show();
                usernameView.setText("");
                passwordView.setText("");
                this.recreate();
            }
            else                        //if login is successful then create Dashboard activity
            {
                Intent dashBoard = new Intent(this,DashBoard.class);
                dashBoard.putExtra("displayData",P.getResponseBody());
                store.loadAllCookies();
                this.finish();
                startActivity(dashBoard);
            }

        }


    }



}



Enter fullscreen mode Exit fullscreen mode
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    android:background="@color/colorPrimaryDark">

    <TextView
        android:id="@+id/LOGIN"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/Email"
        android:text="LOGIN"
        android:textColor="@color/green_intheme"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="15dp"
        android:fontFamily="serif-monospace"
        android:textSize="35dp"/>

    <EditText
        android:id="@+id/Email"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:inputType="textWebEmailAddress"
        android:layout_centerVertical="true"
        android:layout_above="@id/Password"
        android:background="@color/gray_outlook"
        android:layout_marginBottom="10dp"
        android:hint="Email"/>


    <EditText
        android:id="@+id/Password"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:inputType="textWebPassword"
        android:layout_centerVertical="true"
        android:layout_marginBottom="10dp"
        android:background="@color/gray_outlook"
        android:hint="Password"/>

    <Button
        android:id="@+id/SignIN"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Sign IN"
        android:layout_marginTop="10dp"
        android:layout_below="@id/Password"
        android:background="@color/blue_intheme"
        android:layout_centerHorizontal="true"
        android:textSize="20dp"
        android:onClick="SignIN"
        android:clickable="true"/>

</RelativeLayout>
Enter fullscreen mode Exit fullscreen mode

DashBoard:-user profile preview

package com.example.workstation.basic;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Build;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class DashBoard extends AppCompatActivity {

    boolean flag=true;
    String domain_name;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_dash_board);

        this.domain_name =this.getResources().getString(R.string.domain_name);

        BitmapD B=new BitmapD();

        Intent DataIntent = getIntent(); //receiving the intent

        JSONArray obj = new JSONArray();
        try {
            obj = new JSONArray(DataIntent.getStringExtra("displayData"));
            //the received response from server was JSON serialized coverting it back to JSON Array
        } catch (JSONException e) {
            e.printStackTrace();
        }
        try {
            Log.i("Json", "SignIN: "+((JSONObject)((JSONObject)obj.get(0)).get("fields")).get("username"));
        } catch (JSONException e) {

            e.printStackTrace();
        }
        //selectiong differnt elements from UI(xml)
        TextView username = (TextView) findViewById(R.id.username);
        TextView firstname = (TextView) findViewById(R.id.firstname);
        TextView lastname = (TextView) findViewById(R.id.lastname);
        TextView email = (TextView) findViewById(R.id.email);
        ImageView I =(ImageView) findViewById(R.id.ProfilePic);

        try
        {
            //setting appropiate value from JSON Array
            username.setText("username : "+((JSONObject)((JSONObject)obj.get(0)).get("fields")).get("username"));
            lastname.setText(""+((JSONObject)((JSONObject)obj.get(0)).get("fields")).get("last_name"));
            firstname.setText(""+((JSONObject)((JSONObject)obj.get(0)).get("fields")).get("first_name"));
            email.setText("Email : "+((JSONObject)((JSONObject)obj.get(0)).get("fields")).get("email"));
            B.setUrl(domain_name+"/media/"+((JSONObject)((JSONObject)obj.get(1)).get("fields")).get("profile_pic"));
            //setting image url to BitmapD object which loads the image on other thread
            B.start();
            B.join();
            Bitmap bm=B.getBitmap();
            I.setImageBitmap(bm);

        } catch (JSONException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.actionbardb, menu);
        return super.onCreateOptionsMenu(menu);
    }

    //triggers on clicking close icon  and finishes activity
    public void Close(MenuItem i)
    {
        this.finish();
    }

    //triggers on clicking logout icon and destroys the current session and finishes activity
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    public void LogOut(MenuItem i) throws InterruptedException {
        AsyncRequest P=new AsyncRequest("GET",this);
        P.setUrl(domain_name+this.getResources().getString(R.string.Logout)); //sends logout request
        P.start();
        P.join();
        this.finish();
    }

}

Enter fullscreen mode Exit fullscreen mode
<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".DashBoard">

    <LinearLayout
        android:id="@+id/DataLayout"
        android:layout_width="match_parent"
        android:layout_height="fill_parent"
        android:background="@color/colorPrimaryDark"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <android.support.v7.widget.CardView
                xmlns:card_view="http://schemas.android.com/apk/res-auto"
                android:layout_width="160dp"
                android:layout_height="160dp"
                card_view:cardCornerRadius="80dp"
                card_view:cardBackgroundColor="@color/white"
                card_view:cardElevation="20dp">


                <android.support.v7.widget.CardView
                    xmlns:card_view="http://schemas.android.com/apk/res-auto"
                    android:layout_width="150dp"
                    android:layout_height="150dp"
                    android:layout_margin="5dp"
                    card_view:cardCornerRadius="75dp"
                    card_view:cardBackgroundColor="@color/white"
                    card_view:cardElevation="10dp">

                    <ImageView
                        android:id="@+id/ProfilePic"
                        android:layout_width="150dp"
                        android:layout_height="150dp"/>

                </android.support.v7.widget.CardView>
            </android.support.v7.widget.CardView>

            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/firstname"
                    android:layout_width="match_parent"
                    android:layout_height="30sp"
                    android:textSize="25sp"
                    android:fontFamily="serif-monospace"
                    android:textColor="@color/white" />

                <TextView
                    android:layout_width="match_parent"
                    android:layout_margin="1dp"
                    android:layout_height="1dp"
                    android:background="@color/blue"/>

                <TextView
                    android:id="@+id/lastname"
                    android:layout_width="match_parent"
                    android:layout_height="30sp"
                    android:textSize="25sp"
                    android:fontFamily="serif-monospace"
                    android:textColor="@color/white" />


            </LinearLayout>

        </LinearLayout>

        <TextView
            android:layout_width="match_parent"
            android:layout_margin="1dp"
            android:layout_height="1dp"
            android:background="@color/blue"/>


        <TextView
            android:id="@+id/username"
            android:layout_width="match_parent"
            android:layout_height="30sp"
            android:textSize="25sp"
            android:fontFamily="serif-monospace"
            android:textColor="@color/white" />


        <TextView
            android:layout_width="match_parent"
            android:layout_margin="1dp"
            android:layout_height="1dp"
            android:background="@color/blue"/>

        <TextView
            android:id="@+id/email"
            android:layout_width="match_parent"
            android:layout_height="60sp"
            android:textSize="25sp"
            android:fontFamily="serif-monospace"
            android:textColor="@color/white"/>

        <TextView
            android:layout_width="match_parent"
            android:layout_margin="1dp"
            android:layout_height="1dp"
            android:background="@color/blue"/>


    </LinearLayout>

</RelativeLayout>
Enter fullscreen mode Exit fullscreen mode

Phew!!!

OHH ,That's It.

we are done with our Tutorial.I have shared only code snippet which are important for understanding ,rest all I have skipped because of the length of the Article.I am linking my web application repo and android application repo:

1)Web application repo
2)Android Application repo

Top comments (6)

Collapse
 
pankajgarg profile image
pankaj garg

Hello, I am working on both Django and Android Studio. Your article is awesome. I would suggest you one edit in your article:
replace
django manage.py startapp StudentProfile
with
python manage.py startapp StudentProfile

Because manage.py will be interpreted by python interpreter only.

Collapse
 
akshaychhajed1998 profile image
Akshay Ajay Chhajed

Thank You!

Collapse
 
nirmanp6 profile image
nirmanp6

Hey, I was working on learning android studio, I have some experience with Django, your article looks helpful. I just have some problem setting it up can you help me out?

Collapse
 
akshaychhajed1998 profile image
Akshay Ajay Chhajed • Edited

Yes, offcourse 🙂😀
Can you describe problem

Collapse
 
apoorvashukla profile image
Apoorva Kumar Shukla

Nice

Collapse
 
nirmanp6 profile image
nirmanp6

Did it work for you? Could you set it up? I need help setting it up.