Sunday, August 13, 2017

Android Tab Layout

Tabs with fragments look better . In case of several screens I prefer adding tabs. I am going to describe the whole process of adding tabs in android.

Step 1 :  Add the following dependency in the moduleable build.gradle file.

compile 'com.android.support:design:23.1.1' 

Step 2 : Now come to the material design part. Open up your styles.xml and add the followings :

    <style name="MyMaterialTheme" parent="MyMaterialTheme.Base">

    </style>

    <style name="MyMaterialTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
        <item name="windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
You can customize your preferred color in colors.xml. After this , dont forget to edit the manifest file. Add MyMaterialtheme as theme there.

Step 3 : We'll create two xml file. One for toolbar & the other one for tablayout. So create tool_bar.xml & add the toolbar.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    
    <android.support.v7.widget.Toolbar
        android:id="@+id/toolBar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        app:layout_scrollFlags="scroll|enterAlways"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light">

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

</LinearLayout>
Create tab_layout.xml & add the followings :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.TabLayout
        android:id="@+id/tablayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:tabMode="fixed"
        app:tabGravity="fill">

    </android.support.design.widget.TabLayout>

</LinearLayout>
We'll include these two xml files as per our need. Here tabMode = fixed means we can't swipe the tablayout. Of course, we can make it swipeable or horizontally scrollable (whatever it is) !!

Step 4 : Now open activity_main.xml. There we gonna add those toolbar & tablayout. Parent layout will be a CoordinatorLayout. First we gonna add a AppBarLayout which will hold the toolbar & tab layout. Below the AppBarLayout, we gonna add a ViewPager. This viewpager contains the fragments which we gonna add later. Also an adapter is needed for this viewpager. We gonna include toolbar & tablayout using "include" tag inside AppbarLayout. The activity_main.xml will look like this :

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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="com.example.newaj.tablayout.MainActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
        
        <include layout="@layout/tool_bar"></include>
        <include layout="@layout/tab_layout"></include>
        


    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/viewpager"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">

    </android.support.v4.view.ViewPager>



</android.support.design.widget.CoordinatorLayout>
Now our xml part is completed.

Step 5 : Now we need an adapter for viewpager. Create a class ViewPagerAdapter  and add the followings :

public class ViewPagerAdapter extends FragmentPagerAdapter {

    private List<Fragment> fragments = new ArrayList<>();
    private List<String> titles = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        return fragments.get(position);
    }

    @Override
    public int getCount() {
        return fragments.size();
    }

    public void addFragment(Fragment fragment, String title) {
        fragments.add(fragment);
        titles.add(title);
    }

    // this method is responsible for displaying tab title
    @Override
    public CharSequence getPageTitle(int position) {
        return titles.get(position);
    }
}
Step 6 : Now create some fragments. We have to set the fragment layout inside oncreateView method. Initialization inside fragment should be done inside onActivityCreated method.

Now open up MainActivity.java and create variable for ToolBar, TabLayout & ViewPager. Initialize them. We have written a method setUpViewPager for adding fragments with viewpager.

public void setUpViewPager(ViewPager viewPager) {
        ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
        viewPagerAdapter.addFragment(new FragmentOne(), "One");
        viewPagerAdapter.addFragment(new FragmentTwo(), "Two");
        viewPagerAdapter.addFragment(new FragmentThree(), "Three");
        viewPagerAdapter.addFragment(new FragmentFour(), "Four");

        viewPager.setAdapter(viewPagerAdapter);
}
Task is almost done.We have to call setSupportActionBar() method after initializing toolbar. Now call the setUpViewPager() method and pass the initiated viewpager object. Finally add tablayout with the viewpager. Additionally you can add icons with tabs. You have to keep those icons inside drawable folder. Note that - if  you use normal fragment, then use  getFragmentManager(). I am using v4 fragment. So I have called getSupportFragmentManager() method.  MainActivity.java code is given below :


public class MainActivity extends AppCompatActivity {

    private Toolbar toolbar;
    private TabLayout tabLayout;
    private ViewPager viewPager;
    private int[] icons = {R.drawable.one, R.drawable.two, R.drawable.three, R.drawable.four};


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

        toolbar = (Toolbar) findViewById(R.id.toolBar);
        setSupportActionBar(toolbar);

        viewPager = (ViewPager) findViewById(R.id.viewpager);
        setUpViewPager(viewPager);

        tabLayout = (TabLayout) findViewById(R.id.tablayout);
        tabLayout.setupWithViewPager(viewPager);

        setUpTabIcons(tabLayout, icons);

    }

    public void setUpViewPager(ViewPager viewPager) {
        ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(getSupportFragmentManager());
        viewPagerAdapter.addFragment(new FragmentOne(), "One");
        viewPagerAdapter.addFragment(new FragmentTwo(), "Two");
        viewPagerAdapter.addFragment(new FragmentThree(), "Three");
        viewPagerAdapter.addFragment(new FragmentFour(), "Four");

        viewPager.setAdapter(viewPagerAdapter);
    }

    public void setUpTabIcons(TabLayout tabLayout, int[] icons) {
        tabLayout.getTabAt(0).setIcon(icons[0]);
        tabLayout.getTabAt(1).setIcon(icons[1]);
        tabLayout.getTabAt(2).setIcon(icons[2]);
        tabLayout.getTabAt(3).setIcon(icons[3]);
    }

}
Final output :
That's all.

Source Code

continue reading Android Tab Layout

Friday, July 14, 2017

Login & registration system using PHP, MySQL & Retrofit 2 library

I am going to create user login & registration system. I'll use PHP in backend & MySQL database. JSON response will be handled using retrofit 2 library. Let's start.

First, lets create a database. First, create a database. I have named it as "jnklogreg". Then create a table with 4 column - id, Name, Email, Password. Here, the table name is "consumers". Below is the structure of the table :


Now our database is ready. Next come to server side coding. Create a file "init.php". It contains the configuration of our database. Here is it's contents :

<?php

$host = "localhost";
$user = "root";
$password = "";
$database = "jnklogreg";

$conn = mysqli_connect($host, $user, $password, $database);

?>

Here mysqli_connect function creates connection with the database. Put your password in the $password field. Next create another php file - "register.php". Below is it's contents :

<?php 
require 'init.php';

$name = $_POST["name"];
$email = $_POST["email"];
$password = $_POST["password"];

// variables for handling response
$code = "";
$message = "";
$response = array();

//checking the email already registered or not
$sql = "SELECT * FROM consumers WHERE email LIKE '".$email."';";
$result = mysqli_query($conn, $sql);

if (mysqli_num_rows($result) > 0) {
    $code = 0;
    $message = "user already registered with this email";
    
    print_r(error_get_last());
} else {
    $sql_insert = "INSERT INTO consumers(Name, Email, Password) VALUES('$name', '$email', '$password')";
    $result_of_insertion = mysqli_query($conn, $sql_insert);
    
    if ($result_of_insertion) {
        $code = 1;
        $message = "Registration successful!";
    } else {
        $code = 0;
        $message = "Error!!!";
        
        print_r(error_get_last());
    }
}

$response['code'] = $code;
$response['message'] = $message;

echo json_encode($response);

?>

Here first we imported the init.php file so that we can use it's $conn variable which holds the connection with database. $name , $email & $password contains the corresponding values which will be assigned using POST method. Then we checked whether the email is already registered or not. If yes, mysqli_num_rows() function will return rows, in other words - the email is alredy registered. Otherwise data gonna be inserted in table. Finally we encoded the response in JSON.

Next, another php file login.php to handle login system. Contents below :

<?php
require 'init.php';

$email = $_POST["email"];
$password = $_POST["password"];

$code = "";
$message = "";
$user = "";
$response = array();

$sql_email = "SELECT * FROM consumers WHERE Email LIKE '$email';";

$result_email = mysqli_query($conn, $sql_email);

if (mysqli_num_rows($result_email) > 0) {
    $sql_password = "SELECT * FROM consumers WHERE Email LIKE '$email' AND Password LIKE '$password';";
    $result_password = mysqli_query($conn, $sql_password);
    if (mysqli_num_rows($result_password) > 0) {
        // getting value from 'Name' column 
        $row = mysqli_fetch_row($result_password);
        $user = $row[1];
        $code = 1;
        $message = "Login successful!";
    } else {
        $user = "unavailable";
        $code = 0;
        $message = "Wrong password";
    }
} else {
    $user = "unavailable";
    $code = 0;
    $message = "Wrong email";
    print_r(error_get_last());
}

$response['code'] = $code;
$response['message'] = $message;
$response['user'] = $user;

echo json_encode($response);

?>

First we have imported init.php file to access the database connection. Then values assigned in $email & $password variable using POST method. First we checked whether the email is correct or not. If correct , then we fetched associated rows using both email & password. Other things are pretty simple. Finally we encoded the code, message & user name in JSON format.

So far, our backend is ready. Now come to the android part...

As usual, first create a project in Android Studio. Add permission for accessing internet. Open AndroidManifest.xml & add the followings :

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
Now add dependency for using retrofit.Open build.gradle file & add the following :

compile 'com.squareup.retrofit2:retrofit:2.3.0'
compile 'com.squareup.retrofit2:converter-gson:2.3.0'

Now sync the project & make sure that there is no error. Now create a model class . In our JSON response , there were 3 fields - code, message & user. I have designed this model class keeping in mind the JSON response. Create ResponseModel.java class . Contents are as follows :

public class ResponseModel {

    @SerializedName("code")
    private String code;
    @SerializedName("message")
    private String message;
    @SerializedName("user")
    private String user;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getUser() {
        return user;
    }

    public void setUser(String user) {
        this.user = user;
    }
}

Here @Serialized annotaion is needed to map the JSON keys with our fields. In keeping with camelCase naming convention, using underscore is not recommended.
@SerializedName("code") means our JSON key "code" should be mapped to the java field "code". If both the values are same, there would be no need of @Serialized annotation.

Next create ApiClient.java class. Retrrofit object will be initialized here.

public class ApiClient {

    private static final String BASE_URL = "ipaddress/directory/";
    private static Retrofit retrofit  = null;

    public static Retrofit getClient () {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
        }
        return retrofit;
    }

}

in the BASE_URL, put ip address and directory. Next, create an interface "ApiInterface.class". Here we gonna put the endpoints.

public interface ApiInterface {

    @FormUrlEncoded
    @POST("register.php")
    Call<ResponseModel> registerUser(@Field("name") String name, @Field("email") String email, @Field("password") String password);

    @FormUrlEncoded
    @POST("login.php")
    Call<ResponseModel> loginUser(@Field("email") String email, @Field("password") String password);

}

Here we have created two separate methods for registration & login purpose. Now create "Registeractivity.java". There we have theree edittext for inputting name,email & password. There is  a button to save these. Here is the full content :

public class RegisterActivity extends AppCompatActivity {

    EditText nameEditText, emailEditText, passwordEditText;
    Button registerButton;
    String name, email, password;
    ProgressDialog progressDialog;


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

        registerButton = (Button) findViewById(R.id.btnRegister);
        nameEditText = (EditText) findViewById(R.id.etRegName);
        emailEditText = (EditText) findViewById(R.id.etRegEmail);
        passwordEditText = (EditText) findViewById(R.id.etRegPassword);

        progressDialog = new ProgressDialog(this);
    }

    public void onRegisterUser(View view) {

        progressDialog.setMessage("Submitting. Please wait...");
        progressDialog.show();

        name = nameEditText.getText().toString();
        email = emailEditText.getText().toString();
        password = passwordEditText.getText().toString();

        ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
        Call<responsemodel> call = apiInterface.registerUser(name, email, password);
        call.enqueue(new Callback<responsemodel>() {
            @Override
            public void onResponse(Call<responsemodel> call, Response<responsemodel> response) {
                progressDialog.dismiss();
                if (response.body().getCode().equals("1")) {
                    Toast.makeText(RegisterActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(RegisterActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<responsemodel> call, Throwable t) {
                progressDialog.dismiss();
                Toast.makeText(RegisterActivity.this, t.toString(), Toast.LENGTH_SHORT).show();
            }
        });
    }

}</responsemodel></responsemodel></responsemodel></responsemodel></responsemodel>

We've called registerUser method & passed the name, email & password. The Json response is handled inside onResponse() & onFailure() method. The response are shown in a toast message. The xml file of this activity is given below :

<?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="com.example.nooo.RegisterActivity"
    android:background="#3C3F41">

    <EditText
        android:maxLines="1"
        android:inputType="textCapWords"
        android:background="#2b2b2b"
        android:padding="10dp"
        android:layout_margin="10dp"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:textColor="#FFFFFF"
        android:hint="Your Name"
        android:id="@+id/etRegName"/>

    <EditText
        android:maxLines="1"
        android:inputType="textCapWords"
        android:background="#2b2b2b"
        android:padding="10dp"
        android:layout_margin="10dp"
        android:layout_below="@+id/etRegName"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:textColor="#FFFFFF"
        android:hint="Your Email"
        android:id="@+id/etRegEmail"/>

    <EditText
        android:maxLines="1"
        android:background="#2b2b2b"
        android:padding="10dp"
        android:layout_margin="10dp"
        android:layout_below="@+id/etRegEmail"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:textColor="#FFFFFF"
        android:hint="Enter Password"
        android:id="@+id/etRegPassword"
        android:inputType="textPassword"/>

    <Button
        android:layout_below="@+id/etRegPassword"
        android:layout_margin="10dp"
        android:id="@+id/btnRegister"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Register"
        android:background="#FF0071"
        android:onClick="onRegisterUser"/>




</RelativeLayout>

In the main activity , the login operation is handled. Here is the xml file :

<?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"
    android:background="#3C3F41"
    tools:context="com.example.nooo.MainActivity">

    <EditText
        android:id="@+id/etEmail"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_margin="10dp"
        android:background="#2B2B2B"
        android:hint="Enter your email"
        android:inputType="textCapWords"
        android:maxLines="1"
        android:padding="10dp"
        android:textColor="#FFFFFF" />

    <EditText
        android:id="@+id/etPassword"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_alignStart="@+id/etEmail"
        android:layout_below="@+id/etEmail"
        android:layout_margin="10dp"
        android:background="#2b2b2b"
        android:hint="Enter Your Password"
        android:inputType="textPassword"
        android:maxLines="1"
        android:padding="10dp"
        android:textColor="#FFFFFF" />

    <Button
        android:id="@+id/btnLogin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/etPassword"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="10dp"
        android:background="#FF0071"
        android:onClick="onLogin"
        android:text="Log In" />

    <LinearLayout
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/btnLogin"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:layout_margin="10dp"
        android:orientation="horizontal">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:gravity="center"
            android:onClick="openRegisterActivity"
            android:text="Not member yet? Register Now"
            android:textColor="#FFFFFF"
            android:textSize="18dp" />

    </LinearLayout>

</RelativeLayout>

The java part is almost same as the RegisterActivity.java, we called interface method loginUser & passed emial & password. Success response is handled inside onResponse() method. If login success, there'll be a message like "Login successs!Welcome userName". This is shown as toast message inside onResponse() method. Full code is given below :

public class MainActivity extends AppCompatActivity {

    EditText emailEditText, passwordEditText;
    Button loginButton;
    String email, password;
    ProgressDialog progressDialog;

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

        emailEditText = (EditText) findViewById(R.id.etEmail);
        passwordEditText = (EditText) findViewById(R.id.etPassword);
        loginButton = (Button) findViewById(R.id.btnLogin);
        progressDialog = new ProgressDialog(this);

    }

    public void onLogin(View view) {
        progressDialog.setMessage("Submitting. Please wait...");
        progressDialog.show();
        email = emailEditText.getText().toString();
        password = passwordEditText.getText().toString();

        ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
        Call<ResponseModel> call = apiInterface.loginUser(email, password);
        call.enqueue(new Callback<ResponseModel>() {
            @Override
            public void onResponse(Call<ResponseModel> call, Response<ResponseModel> response) {
                progressDialog.dismiss();
                if (response.body().getCode().equals("1")) {
                    Toast.makeText(MainActivity.this, response.body().getMessage() + "Welcome " + response.body().getUser(), Toast.LENGTH_SHORT).show();
                } else {
                    Toast.makeText(MainActivity.this, response.body().getMessage(), Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<ResponseModel> call, Throwable t) {
                progressDialog.dismiss();
                Toast.makeText(MainActivity.this, t.toString(), Toast.LENGTH_SHORT).show();
            }
        });
    }

    public void openRegisterActivity(View view) {
        Intent intent = new Intent(this, RegisterActivity.class);
        startActivity(intent);
    }

}

Thats all! Now time to run & check.
continue reading Login & registration system using PHP, MySQL & Retrofit 2 library

Monday, July 10, 2017

Upload image to local server using retrofit

First, create a folder "uploads" in the desire directory. Our uploaded photos will be stored in this folder.

Let's finish server side coding first. Create a file uploadImage.php . Here is the content of the uploadImage.php file :
$folder = "uploads/";
$path = $_FILES['uploadimage']['name'];
// $extension = pathinfo($path, PATHINFO_EXTENSION);
$fileName = basename($path);

$response = array();
$code = "";
$message = "";

if ($_SERVER['REQUEST_METHOD'] == "POST") {
    
    if ($_FILES['uploadimage']) {
        
        $destination = $folder.$fileName;
        if (move_uploaded_file($_FILES['uploadimage']['tmp_name'], $destination)) { // key = uploadimage
            $code = 1;
            $message = "Image successfully uploaded!";
        } else {
            $code = 0;
            $message = "Error! Image is not uploaded!";
            
            print_r(error_get_last());
        }
        
    } else {
        $code = 0;
        $message = "Error while uploading!";
    }
    
} else {
    $code = 0;
    $message = "Error! HTTP method mismatch!";
}

$response['code'] = $code;
$response['message'] = $message;

echo json_encode($response);
Here a JSON response will be created where 'code' & 'message' are two attributes.

Now we'll do the android side coding. I am going to use android studio. Create a project. First, add the necessary permission in AndroidManifest.xml file. We need permission for accessing internet & to read external storage. Add the following lines :

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
Now we gonna add dependency. Add the followings in build.gradle file to include retrofit & cardview in our project.

    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
    compile 'com.android.support:cardview-v7:23.1.1'
Our layout will look like this :

Add the followings in activity.xml file
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.android.MainActivity">

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

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Open Gallery"
            android:id="@+id/btnGallery"/>

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Upload"
            android:id="@+id/btnUplopad"/>

    </LinearLayout>

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="10dp"
        android:elevation="5dp">

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scaleType="centerInside"
            android:id="@+id/img"
            android:visibility="gone"/>

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

</LinearLayout>
So our layout is ready now.Initially the upload button is disabled (will disable it later in java) & the cardview's visibility is gone.

Now come to the next part. For "retrofit" purpose, we need 2 types of java class & an interface. One of the java classes will contain the JSON model. In other word, it contains fields just like the JSON response, i mean it is our model class. In the other one, we'll initialize the retrofit object. The interface will contain the api endpoints.

Now let's create the java model class. Create a class ImageModel.java . Remember, in JSON response, there are two attributes - "code" & "message". So our model class will contain two fields. Here is the full file :

public class ImageModel {

    @SerializedName("code")
    private String code;
    @SerializedName("message")
    private String message;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
Now create another class ApiClient.java . We gonna initialize retrofit here.

public class ApiClient {

    public static final String BASE_URL = "http://localhost/jnknotes/imageUploadToServer/";
    public static Retrofit retrofit = null;

    public static Retrofit getApiClient () {
        if (retrofit == null) {
            retrofit = new Retrofit.Builder().baseUrl(BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
        }
        return retrofit;
    }

}
 Here BASE_URL is the location of our project in our local server. We have to find out the IP address , then replace "localhost" with IP address in BASE_URL.
getApiClient() method will return the retrofit object after initialization. Thats all about ApiClient class.

Next create an interface ApiInterface.java. This will include our api endpoint.

public interface ApiInterface {
 
    @Multipart
    @POST("uploadImage.php")
    Call<imagemodel> uploadTheImage(@Part MultipartBody.Part image);
 
}
In the POST annotaion we have specified the endpoint which is uploadImage.php.

So, our model class, api client class & interface all are ready. No we can move to the activity.java class. Initially, when there is no image is selected, the upload button will be disabled. This is done in onCreate() method.

uploadButton.setEnabled(false);

Now we want to open the gallery of all images . This is done in the onClick method of the openGalleryButton. Earlier we initialized an integer value REQUEST_CODE which we used later in onActivityResult() method.

                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(intent, REQUEST_CODE);

Here is the overrided method onActivityResult :

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            Uri uri = data.getData();
            String[] imageProjection = {MediaStore.Images.Media.DATA};

            Cursor cursor = getContentResolver().query(uri, imageProjection, null, null, null);
            if (cursor != null) {
                cursor.moveToFirst();

                int imageIndex = cursor.getColumnIndex(imageProjection[0]);
                partImage = cursor.getString(imageIndex);

                if (partImage != null) {
                    File image = new File(partImage);
                    imageView.setImageBitmap(BitmapFactory.decodeFile(image.getAbsolutePath()));
                    imageView.setVisibility(View.VISIBLE);
                    openGalleryButton.setEnabled(false);
                    uploadButton.setEnabled(true);
                }
            }
        }
    }

Now if we select an image , it will be displayed. Notice, now openGalleryButton is disabled & the uploadButton is enabled. Now we have to handle the uploadButton button's onClick method. Here it is :

public void upPhoto () {
        File file = new File(partImage);
        RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-file"), file);
        MultipartBody.Part prt_image = MultipartBody.Part.createFormData("uploadimage", file.getName(), requestBody);
 
        ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
        Call<imagemodel> call = apiInterface.uploadTheImage(prt_image);
 
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call<imagemodel> call, Response response) {
                Log.d("Retro", "On Response : " + response.body().toString());
                if (response.body().getCode().equals("1")) {
                    Toast.makeText(MainActivity.this, "Response : " + response.body().getMessage(), Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(MainActivity.this, "Response : " + response.body().getMessage(), Toast.LENGTH_LONG).show();
                }
                uploadButton.setEnabled(false);
                imageView.setVisibility(View.GONE);
                openGalleryButton.setEnabled(true);
            }
 
            @Override
            public void onFailure(Call<imagemodel> call, Throwable t) {
                Log.d("Retro", "On Error : " + t);
            }
        });
    }

Here partImage is a string which was initialized while selecting image from gallery. Later we created an ApiInterface object and called it's uploadTheImage() method. In the overrided method onResponse() we handled the JSON response by calling response.body(). Other things are pretty straight forward. Now notice this in upPhoto() method  :

MultipartBody.Part prt_image = MultipartBody.Part.createFormData("uploadimage", file.getName(), requestBody);

Here the 1st parameter "uploadimage" is exactly the same that we used in the php file which was :

 $_FILES['uploadimage']

Here is the full activity.java class :

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    Button openGalleryButton, uploadButton;
    ImageView imageView;
    final int REQUEST_CODE = 455;
    String partImage;


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

        openGalleryButton = (Button) findViewById(R.id.btnGallery);
        uploadButton = (Button) findViewById(R.id.btnUplopad);
        imageView = (ImageView) findViewById(R.id.img);

        uploadButton.setEnabled(false);

        openGalleryButton.setOnClickListener(this);
        uploadButton.setOnClickListener(this);

    } // end of main()

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnGallery :
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(intent, REQUEST_CODE);
                break;

            case R.id.btnUplopad :
                upPhoto();
                break;
        }
    } // end of onClick()

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            Uri uri = data.getData();
            String[] imageProjection = {MediaStore.Images.Media.DATA};

            Cursor cursor = getContentResolver().query(uri, imageProjection, null, null, null);
            if (cursor != null) {
                cursor.moveToFirst();

                int imageIndex = cursor.getColumnIndex(imageProjection[0]);
                partImage = cursor.getString(imageIndex);

                if (partImage != null) {
                    File image = new File(partImage);
                    imageView.setImageBitmap(BitmapFactory.decodeFile(image.getAbsolutePath()));
                    imageView.setVisibility(View.VISIBLE);
                    openGalleryButton.setEnabled(false);
                    uploadButton.setEnabled(true);
                }
            }
        }
    } // end of onActivityResult()

    public void upPhoto () {
        File file = new File(partImage);
        RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-file"), file);
        MultipartBody.Part prt_image = MultipartBody.Part.createFormData("uploadimage", file.getName(), requestBody);

        ApiInterface apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
        Call call = apiInterface.uploadTheImage(prt_image);

        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                Log.d("Retro", "On Response : " + response.body().toString());
                if (response.body().getCode().equals("1")) {
                    Toast.makeText(MainActivity.this, "Response : " + response.body().getMessage(), Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(MainActivity.this, "Response : " + response.body().getMessage(), Toast.LENGTH_LONG).show();
                }
                uploadButton.setEnabled(false);
                imageView.setVisibility(View.GONE);
                openGalleryButton.setEnabled(true);
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                Log.d("Retro", "On Error : " + t);
            }
        });
    }

}

Now time to run & check the app.




continue reading Upload image to local server using retrofit

Monday, June 5, 2017

Run ".sh" files in ubuntu.

So far there are multiple ways to run ".sh" files. Here I will note the easiest one, which is through GUI. So follow the steps below :

    1. Right click on the ".sh" file & select properties.
    2. Click on the "Permission" tab. Check "Allow executing file as program". Close the    window.
    3. Now double click the file. A pop up window will give you an option to run the file on terminal. Select it. And thats all!
continue reading Run ".sh" files in ubuntu.

Friday, May 26, 2017

Saturday, March 25, 2017

Monday, March 13, 2017

Reverse a string using stack in java

In my previous post, I reversed a string in java. I'll do the same thing here using stack.

Steps : 1) Declare an empty stack.
              2) put the string elements in a character array.
              3) Push every single character of the array into the stack.
              4) Pop character one by one from the stack & add the removed character in an empty string.
             

import java.util.Scanner;
import java.util.Stack;

public class MyStack {

 
 public static void main(String[] args) {
  
  Scanner scanner = new Scanner(System.in);
  String string = scanner.nextLine();
  String output = "";
    
  Stack stack = new Stack();
  
  char[] array = string.toCharArray();
  
  for (char c : array) {
   stack.push(c);
  }
  
  for (int i = 0; i < array.length; i++){
   char c = (char) stack.pop();
   output += c;
  }
  
  System.out.println("Reversed string : " + output);
  
 }

}


continue reading Reverse a string using stack in java