Friday, 31 May 2024

Privacy policy

Privacy Policy

Introduction: This Privacy Policy elucidates the procedures employed by the Compass-plus application in the collection, utilization, and sharing of information during its usage. By utilizing our application, you provide consent for the collection and utilization of information in accordance with the guidelines outlined in this Privacy Policy.

Information/Permission required:

Location Information/Permissions: In order to calculate the direction from your current location to the target location, the Custom and Any-direction modes of the application require access to your current location. Therefore, users are prompted to grant permission for location access. The location data is exclusively utilized for direction calculation purposes and is not shared with any third parties.

Changes to This Privacy Policy: We reserve the right to periodically update this Privacy Policy, with any modifications being posted on this page. Your continued usage of the application subsequent to any changes signifies your acceptance of the updated Privacy Policy.

Contact Information: Should you have any inquiries regarding this Policy, please feel free to contact us at ibrahimgiki@gmail.com.

Wednesday, 2 March 2022

Create/develop simple login application in android using wamp server and MySQL  databases.

In this tutorial we will create a simple login application using wamp server and MySQL databases.
We will use Retrofit library for server communication. 

So lets start

1. Run wamp server and open phpMyAdmin home page






2. Create a databases and name it "simple_login_app_db"


 
3. Execute following query to create 'users' table
    CREATE TABLE IF NOT EXISTS `users` (
     id` int(11) NOT NULL AUTO_INCREMENT,
	`username` varchar(200) NOT NULL,
	`password` text NOT NULL,
	 PRIMARY KEY (`id`)
     ) 
4. Insert a record

5. Now go to 'C:\wamp64\www', create a project/folder and give name 'simple_login_app'

Create two .php files, connect.php & login.php

   i. Copy below code in connect.php file 


	ini_set('display_errors',0);
    date_default_timezone_set('Asia/Karachi');
    $servername = "localhost";
    $username = "root";
    $password = "";
    try {
        $conn = new PDO("mysql:host=$servername;dbname=simple_login_app_db", $username, $password);
        $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    }catch(PDOException $e){
        echo "Connection failed: " . $e->getMessage();
    }
    ii. Copy below code in login.php
php 
header('Content-type: application/json');
include_once('connect.php');
$response=array();

if ( isset($_REQUEST['username']) & isset($_REQUEST['password']) ){

  $username = $_REQUEST['username'];
  $password = md5( $_REQUEST['password'] ); 
    
  $stmt = $conn->prepare("SELECT * FROM `users`  WHERE username='$username' AND  password = '$password'  ");  
  
      $stmt->execute();
      $stmt->setFetchMode(PDO::FETCH_OBJ); 
      $row = $stmt->fetch();

      if($row->id != ""){

        $response['id']= $row->id;
        $response['username']= $row->username;
    
        $response["success"] = 1;
        $response["message"] = "Logged in successfully";
        
      }else{
        $response["success"] = 0;
        $response["message"] = "Invalid username or password"; 
      }
  
}else{    
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";
}
echo json_encode($response);
6. Create a project in android studio and give name "SimpleLoginApp".

7. Rename MainActivity to LoginActivity (Optional) and past below code.

import android.os.Bundle
import android.util.Log
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatButton
import com.google.android.material.textfield.TextInputLayout
import com.google.gson.JsonObject
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class LoginActivity : AppCompatActivity() {

    private lateinit var userNameField: TextInputLayout
    private lateinit var passwordField: TextInputLayout
    private lateinit var loginBtn: AppCompatButton

    private lateinit var messageFromServerTextView: TextView
    private var messageFromServer = ""

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.login_activity)

        messageFromServerTextView = findViewById(R.id.message_from_server)

        userNameField = findViewById(R.id.username)
        passwordField = findViewById(R.id.password)
        loginBtn = findViewById(R.id.login_btn)

        loginBtn!!.setOnClickListener {
            loginFunc(userNameField.editText!!.text.toString(),   passwordField.editText!!.text.toString())
        }
    }

    private fun loginFunc(username: String, password: String) {

        val userServiceInterface = RetrofitClient.getRetrofitInstance().create(UserServiceInterface::class.java)
        val  call = userServiceInterface.login(username, password)

        call?.enqueue(object : Callback {
            override fun onResponse(call: Call, response: Response) {
               if (response.isSuccessful) {
                   val jsonObject =  response.body()!!.asJsonObject
                   messageFromServer = jsonObject.get("message").toString()
                    //if (jsonObject.get("message").toString().contains("Logged in successfully")){ }
               }else {
                   messageFromServer = response.message().toString()
               }
               messageFromServerTextView.text = messageFromServer
               Toast.makeText(this@LoginActivity, messageFromServer, Toast.LENGTH_LONG).show()
               Log.i("server response", messageFromServer)
            }
            override fun onFailure(call: Call, t: Throwable) {
               messageFromServer = t.message.toString()
               messageFromServerTextView.text = messageFromServer
               Toast.makeText(this@LoginActivity, messageFromServer, Toast.LENGTH_LONG).show()
               Log.i("server response", messageFromServer)
            }
        })

    }
}
8. Create a class "RetrofitClient" and copy below code

import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;

public class RetrofitClient {
    public static final String URL_LOGIN = "http://192.168.00.00/simple_login_app/";
    private static Retrofit retrofit = null;
    public static Retrofit getRetrofitInstance(){
        if(retrofit == null){
            retrofit = new Retrofit.Builder()
            .baseUrl(URL_LOGIN)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
        }
        return retrofit;
    }
}
9. Create an interface "UserServiceInterface" and copy below code.
import com.google.gson.JsonObject;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.POST;

public interface UserServiceInterface {
   @FormUrlEncoded
   @POST("login.php")
   Call login(
     @Field("username") String username,
     @Field("password") String password
   );
}
10. Open 'manifest' file and add following permission.
 uses-permission android:name="android.permission.INTERNET" 
11. Open 'build.gradle' file and add following dependencies.

implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
implementation 'com.google.code.gson:gson:2.8.6'
12. Go to layout folder and copy below code in the login_activity.xml.

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".LoginActivity"
    >
        <TextView
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="50dp"
            android:textStyle="bold"
            android:textSize="32sp"
            android:text="Simple Login App"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>

        <LinearLayout
            android:layout_marginTop="20dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="30dp">

            <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/username"
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Username">

                <com.google.android.material.textfield.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="text" />
            </com.google.android.material.textfield.TextInputLayout>

            <com.google.android.material.textfield.TextInputLayout
                android:id="@+id/password"
                android:layout_marginTop="10dp"
                style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="Password">

                <com.google.android.material.textfield.TextInputEditText
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:inputType="textPassword" />

            </com.google.android.material.textfield.TextInputLayout>

            <androidx.appcompat.widget.AppCompatButton
                android:id="@+id/login_btn"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="20dp"
                android:background="@color/purple_500"
                android:textColor="@color/white"
                android:text="Login" />

    </LinearLayout>

    <TextView
       android:layout_margin="10dp"
        android:id="@+id/message_from_server"
        android:layout_gravity="center_horizontal"
        android:textSize="24dp"
        android:layout_marginTop="30dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

Now your code is ready. Run it. Following UI should be shown.

Note: Replace IP address in RetrofitClient class with your machine address.

Watch the video for practical implementation


That's it. Thank you 



 

Friday, 10 September 2021

Find your machine/computer/laptop IP address

To find your machine/computer/laptop IP address follow these steps.

    1. Search for cmd in the search bar

    2. Type ipconfig command and press Enter button

    Watch video



Thursday, 9 September 2021

How to change View/Button/Layout background color in android while maintaining effects and state color ?

 This tutorial will answer following questions:

  1.   Difference between android:background & android:backgroundTint in android
  2.   Why background color is not applying to Views/Buttons in android
  3.   Why android:background is not working in android?
  4.   Why button background color is not changing ?
  5.   Difference between  app: and android: prefix, used in android XML layouts

android:background & android:backgroundTint are two very important and confusing properties. Both are used for background styling of a View/Layout/Button. Here, I am listing some important points  about the functionality these properties/attributes.

    1. Both are used to change background color of a View/Button/Layout.
    2. android:background applies a color or a full drawable resource (PNG image, XML state list description) to the background, while android:backgroundTint is only used for coloring the background    
    3. android:backgroundTint is having high priority than android:background i-e if you set both of these attributes/properties for a view, android:backgroundTint will affect/apply while android:background will not. 
    4. If android:background attribute/property is used for changing background color, the default click effect behavior (view/button rounded corners and default selection states) of the view will be lost.
    5. use android:background for background resource(PNG/XML) setting and android:backgroundTint for color changing
    6. Use backgroundTint instead of background, until unless there is some special need (e-g wanna to change background image for a View).
    7. By default, Views/buttons/layouts usually use custom/support-library values (purple color +some padding) for backgroundTint property so if you wanna to change it by using/setting  android:backgroundTint property, it will not work. It's because app:backgroundTint (default one) have high priority than android:backgroundTint. So to replicate the changes, you will have to do  one of the following:                                           
      • Disable its custom values in the res->values->themes->themes.xml OR          
      • Use app:backgroundTint instead of android:backgroundTint


    Thursday, 26 August 2021

    How to get fresh instance of current user from firebase database in android? Stop disabled/deleted user (in firebase databases) from login/sign-In in firebase Why disabled/deleted user still able to login to firebase databases ? Why after deleting/disabling a user from firebase console, still returning NON-NULL value ? What is the exact functionality of firebase reload() function/method in android ?

    If you have used Email or OTP authentication for your application in android you will have user table  as shown below:

    Sometimes admin wants to disable/delete a user, from firebase console, to stop their login to the application. 

    The problem is that after disabling/deleting a user from server, it is still able to login to the application because the user will have local instance in their device. 

    Following code snippet is used to check user instance for NULL value.

    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

    if (user != null){

    // Go to login activity

     }else{

     // Go for authentication

    }

    The above piece of code is checking LOCAL instance of the application and NOT user status/instance on the server side. If an application data is cleared locally from the device (as shown in below snap), in that case user instance will be cleared and the above code will return NULL value for the user variable.


    If a user is disabled/deleted on server side(in firebase databases) it will still be able to login as the device is still having the local instance.

    Usually disabling/deleting a user from firebase console is not clearing/deleting the local instance from user mobile that's why its still returning non-null value which does not stop user from login.

    To resolve the issue you will have to check local instance as well as user status on the server (in firebase user table). For this reload() function/method is used. So following code/check will do the trick.

    if (user != null){

                user.reload();

            }

    user.reload() will load new/fresh instance (user status) from firebase user table. if user does not exist or disabled on server side, it will NOT get a fresh instance and hence its local instance will also become NULL.

    Final code will be:

        FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

    if (user != null){

                user.reload();

            }

    if (user != null){     // again check user for fresh instance

    // Go to login activity

            }else{

      // Go for authentication

    }

    Testing:

     Use case1: 

    1. Install your application and login using OTP authentication. 

    2. Go to firebase console and disable the user as shown in the above image. 

    3. Close your application and then open it again (repeat it at least two times).

    4. It will ask again for OTP authentication which indicates that user local instance has been initialized to NULL by reloading it from server(from firebase databases).

    Use case2: 

    1. Install your application and login using OTP. 

    2. Go to firebase console and disable the user.

    3. Disconnect your device from internet

    4. Close your application and then open it again (repeat multiple times). 

    5. This time it will not ask for re-authentication as Internet is disconnected and reload() function is not communicating with server to check user status on server to re-initialize the local instance of the user. It will only check for local instance which is NON-NULL. 

    For practical implementation watch the video










    Wednesday, 24 March 2021

    How to logout/sign out from WhatsApp?

     

    Hello friends, today I am going to explain logout in WhatsApp.  If you open your WhatsApp you will not see logout option anywhere that means you cannot logout, explicitly, from WhatsApp.

    Actually WhatsApp authenticate user by sending OTP to their mobile number. When user enters correct OTP it is authenticated. But the OTP is valid for one time use only. It’s not like a password.

    When a user is authenticated, an instance is created in their mobile memory. In programming terminology it is stored in shared preferences. Now, whenever user opens WhatsApp application, it checks that instance. If it has been created that means user/mobile phone has been authenticated and is allowed to the WhatsApp.

    This instance is not associated with the mobile number instead it is associated with mobile phone. E-g if someone change SIM card in mobile phone and connect to Wi-Fi WhatsApp will work normally as the mobile phone have the instance. Now if user destroys this instance and open WhatsApp. It will be asked for authentication again. So destroying the instance is one type of log out. So, how to destroy this instance?

    Go to mobile setting -> manage apps. Then click on WhatsApp as shown in the following snap.


    In the bottom click “Clear data”. It will clear all data including that instance. So now, when you open WhatsApp it will ask for authentication as now the mobile phone does not have the instance.

    THATS IT. Thank you

    Wednesday, 12 August 2020

    How to add toggle button (switch) to navigation drawer and register listener in android ?

     1. Add following item to the navigation drawer xml

        <item

        android:id="@+id/toggle_btn"

        android:title="Toggle"
    app:actionViewClass="android.widget.Switch"
    android:icon="@drawable/ic_icon"
    />
    2. Create following method and call it in onCreate() method of the activity

    public void addListenerOnSwitch(){
    NavigationView mNavigationView = findViewById(R.id.nav_view);
    Menu navMenu = mNavigationView.getMenu();
    MenuItem menuItem = navMenu.findItem(R.id.toggle_btn);
    Switch switchButton = (Switch) menuItem.getActionView();

    //add listener
    switchButton .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {



    if ( switchButton .isChecked() ){
    //your action
    }else {
    //your action
    }


    }
    });
    }

    3. thanks