Airo Global Software

Think Beyond Future !

Introduction

Online learning is presented in excellent demand. With online learning, we can discover anywhere and anytime. It’s will provide several benefits for users in their education strategy. Also I myself am a user of online learning apps. The educational sector has witnessed a drastic transformation in its approach as more resources have been created open to make it successful. Among these resources, E-Learning apps have their worth in gold. E-Learning apps have come into movement over the last 4-5 years and since their coming, the overall system of education has changed forever. E-Learning has gathered recognition from parents and students from all over the world for the techniques of learning it brings alongside it.

The team has conducted small research and they found various user problems like:

  • Most o the users don’t like the UI.
  • The platform is complicated to use.
  • Hard to find the motivation to learn.

Goals:

Based on the issues found by the research team, the purposes of this project are:

  • Designing the UI/UX of online learning mobile applications to be more user-friendly and able to increase the motivation of users to learn.

Benefits of E-Learning app:

Major benefits of E-Learning apps.

  • These apps offer better fulfillment rates and retention rates. They take pride in delivering the range in a concise way. In this way, learners can fast learn one course and jump onto the next one.

  • Lack of cooperation tends to hinder the rate of studies that a student does. However, one of the core ideas of these e-learning apps is to facilitate collaborative learning through online neighbourhoods within the app.

  • These apps make the education process rather flexible as they provide various opportunities for learning to the students in the form of podcasts, videos, and other fruitful methods.

  • One of the sites these apps extremely focus on is developing ways for higher engagement of students. They have performed remarkably on making the apps available for the students at any point in time and from any place.

  • Parents have also been made a part of this system as they are held in touch about their kid’s version in school or college. The report drafted by these apps for the parents consists of exam preparedness, use factor, time spent in learning.

Major categories of E-Learning app-based businesses

E-Learning business classes consist of three main kinds and we will discuss all these in detail.

E2C e-learning – Education to Consumers

In this kind, the customers typically are students who are examining to gain educational knowledge. Students of all kinds of organizations are it school, college or university have displayed a lot of interest in following their studies through e-learning mobile apps. Now, this preference for e-learning apps constructs a business option for app creators. But it is not a straightforward path and if you are feeling a bit perplexed then you can have a peek at some of the most exciting options for creating revenues in this category.

Online education courses

Internet today is full of different kinds of online courses and helps developers earn millions. They cooperate with famous universities and colleges to offer their online courses to as many students as feasible. They especially have helped thousands of students who desire to educate themselves but lack financial support. Their ingredients are the following

  • Audio and video lectures
  • Courses archives, blog, and forum
  • Availability of mobile version to access all the essential material
  • Integrated payment system to make the procedure of online payment more manageable
  • Online quizzes plus surrender of tasks to peer students for assessment

E2B E-Learning Apps– Education to Business

Any organization looking to incorporate a new training program into their business can turn to e-learning in order to keep them from tedious face-to-face or classroom learning. Efficiency and progress are two preferences for businesses in today’s world. In order to reach these businesses turn to e-learning which benefits them by saving their money, time, and energy. Let us have a peek at some of the advantages that make e-learning mobile apps such a great tool to use for businesses.

Advantages of E-Learning mobile apps for companies in corporate training:

  • Cost-Effective – An e-learning app lowers the money spent on a venue, study materials, and trip costs to the classroom.
  • Flexible and Convenient – e-learning apps allow anybody to understand and join classes virtually which causes it quite suitable for learners to participate.
  • Increase productivity & performance – Another e-learning app is that it lets the user learn anytime and anywhere which makes it easy to utilize their free time.
  • Easy entry to valuable information – Allows users to access well-written notes in pdf and video lessons with concerns in an interactive way. So, useful, easy to consume data at your fingertips.
  • Constructive feedback – Facility to give feedback to tutors and courses in realtime and real-time progress check of app users
  • High retention capacity – Interactive range, easy to use, and learning lessons drives the learning process fun which makes the students retain info efficiently and stay on the app longer

E2E – Education to Educators

E-Learning mobile apps have not only been for the growth of students but e-learning apps also take teachers under their care. It is true that e-learning has been confirmed to be hugely helpful for the students but that is not the whole picture. These e-learning apps have also allowed teachers to increase leaps and bounds.

Since there was a shift in the method of training with the disposal of physical classes and approval of virtual online classes, teachers needed little tweaks in their style of teaching. E-learning apps have come in a lot of handy in their pursuit of learning the new techniques of teaching.

Advantages of teaching via e-learning mobile apps include:

  • Assigning positions and tasks to students and keeping a way of their improvement in real-time.
  • Scheduling of class at any time according to their convenience.
  • More useful contact with students and their parents
  • Flexibility to get data at any point in time
  • Availability of push information about any important activity
  • Availability of e-learning applications for institutions

E-Learning business by E-Learning mobile app:

Mobile E-Learning is also comprehended as M-learning and is a new way of accessing range using mobile devices. It permits you to understand from any place and any moment with the use of a mobile device and internet connection.

According to analysis more and more people in the present scenario are accessing the internet via their smartphones. No suspicion, laptops, and computers are still popular but nowadays people use different gadgets to perform various activities at a single moment of time.

Students have entry to smartphones and through these smartphones, they use mobile learning. Students are bringing up different courses from different e-learning apps in charge to organize themselves for the future. Apart from bringing up courses, students are using mobile learning to make for various entrance and government exams. Incorporate sector too mobile application for e-learning provides a portal to get out to workers that use to travel a lot, operate remotely and who are willing to act the training regime after their working hours.

In-App chat use cases for E-Learning app:

  • Personalized online tutoring
  • Virtual classrooms for real-time communication
  • Webinars and training session
  • Interactive group chats
  • Feedback and reviews
  • File and screen sharing
  • Collaborative whiteboards

Delivery Methods for e-Learning Apps:

Synchronous Learning

Synchronous e-learning programmers are one that takes place in real-time. Synchronous communication needs two people to be performed with each other at a particular time. Examples of synchronous e-learning are chatting and Instant Messaging, live webcasting, video and audio conferences etc

Asynchronous Learning

Asynchronous programmes are free of time. An example of asynchronous learning is a self-paced course as online learning can be acted at any given place or time. Prime Asynchronous tools include e-mail or discussion forums. In these cases, students finish the course at their own pace with the help of a learning program like LMS.

Hybrid Learning

Hybrid learning is a various approach to the above-mentioned ones and targets delivering courses by including face-to-face classroom instruction with online performance. This kind of learning reduces the overall amount of seating time. Hybrid learning makes students engage in collaborative experiences that will make them well in the future. Hybrid education takes satisfaction in striking a balance between face-to-face and online aspects.

Why one should fund an e-Learning mobile app?

E-learning applications stand at third in terms of most installed apps on mobile with a current rate of 8.47%. Another set indicates that the overall market of m-learning applications was worth of total $165.36 billion in 2016 but going by the indefinite growth of this market it is expected to cross $243 billion by the year 2022 at a pace of 5.08% CAGR. This virtual classroom method is expected to reach a CAGR of 11% in the coronavirus pandemic period.

Monetization Opportunities in e-Learning Apps

In-app advertisements

In-app promotions have been a monetization strategy for mobile publishers. Here the E-learning app businesses get paid for promoting a specific college, academic institute, or its benefits. Apps are a key driver of portable usage and along with that they also drive global media consumption. All of this in favour makes in-app advertising an appealing transaction channel for the E-learning mobile app businesses. Acquired data tracking and user tracking make a good in-app environment that allows promotions to reach customers with high accuracy.

Featured listing

E-learning apps receive grants from colleges and educational institutions in return for the courses they deliver to that app. However, these academic institutions provide another source of income to these apps through the featured listings. All the courses inside an application are not made by the app owners therefore they have the educational institutional courses completed by top educators. When a student inquiry for courses on a particular subject, the courses of these institutions seem right at the top of the search bar. This occurs because the colleges and institutions pay an extra amount to these e-learning apps to construct their courses occur at the top of the courses list. This in turn improves the popularity level of a certain institution which proves to be a win-win situation for both parties.

Certifications and Selling Courses

E-learning apps contain courses in numerous fields and because of this variety in courses, they are able to attract students curious about different subjects and fields. Now, the process of earning revenue from this begins when they deliver learning and certification to a student in business for an enrolment fee. The student after delivering up the fees gains entry to a certificate course of a specific subject for a certain amount of time. After achieving this certification course, the student is offered a certification that opens up a gate of new possibilities for the student like applying for a job of his liking.

These e-learning apps also provide videos of certain courses on their platforms but they don’t offer the basics of a subject in those videos and these in-depth basics of a certain course are shown in their premium courses for which they set the students. E-learning apps these days are using online courses as a wonderful way of monetizing their channels. Websites and apps cause a great amount of income within a day of establishing an online course. Different advantages that this type of monetization method involves are financial strength, growth of client base through student enrolments, connection with course creator community.

eCommerce integration

This method of monetization has become quite effective in recent days where the e-learning apps have involved retail setups in their style of doing business. All the stationery items and several other products related to teaching can be bought through their website. Items like pens, registers, pencils, files, folders are made known to the students through an online store. Books on different subjects in which the students are curious are also up for sale via the websites of these e-learning platforms.

Top E-learning Mobile Apps:

Edx

Using this application, students can take a virtual trip to Mcgill and MIT. One can use the Edx application to attend a higher source of education that will make him in his course for the future. This application able students even earn a degree for themselves by taking part in lectures, tests and personal timing given by the application. The downside regarding this app is that some courses charge pretty high prices.

Coursera

Coursera is an influential E-learning web portal that has collaborated with museums and so many universities in order to enroll free classes to students on a vast number of topics and for all age groups. Coursera has over 1000 courses in various subjects. A learner who is pursuing his learning through Coursera can finish the course, take a test, and by clearing it get the certification of his education.

Udemy

Udemy is an e-learning application that runs beyond all the common subjects and offers classes related to subjects such as science & technology, yoga, cooking, drawing, marketing. It has over 32,000 online courses. This application is trendy among the learning section of the public because of its unique features and easy design.

Byju’s

Byju’s is a well-managed education startup that has put all its focus on making learning enjoyable for students. It has grown to a reputed education application in India on the back of its creative way of teaching. Byjus has pretty engaging video lessons on multiple topics that help in learning. The app contains all the mock tests and sample papers for classes 7-12 for all the board exams which helps the learners prepare for competitive exams.

Challenges in e-learning Mobile App development

Developing study material and documents to access

Creating the best study content be a great challenge for app developers. The success of an e-learning mobile application depends very much on the study material. Apart from the online live classes, learners want notes and documents for revision. Generating this material is paramount if you need your students to stay on the application and continue with what you are providing.

Video content development

Creating an online video takes a lot of effort behind the scenes. The same is the case with e-learning videos. Making a video with an educator teaching an exact subject is not the final or first step, there are other directions associated with it like editing the shooted video to make it worth watching without any useless content, mixing other major things such as sound, proper light effects, framework and more.

Tutor training programs development

The teachers who are opted to teach the students on the e-learning platform require to be taught the insights that are needed for taking a class online. The programs for teachers require to have stuff on multiple subjects from which the teacher can learn and broaden his overall understandings of a particular subject. Addition of multiple courses such as video courses, online teaching programs that facilitate classes through video conferencing, text chat messages, etc.

Server load balance for hassle-free streaming

Load balancing is the efficient distribution of network for application traffic across various servers in a server farm. There require a load balancer among the user devices and backend servers which will get and then give requests to any server that is able of completing them. This process is important as the live classes require to be shot before any interference otherwise the complete flow of studies will be interrupted.

General Features in an e-learning mobile app

Student Panel Features

  • Social Signup/Login
  • Browse via multiple subscription plans
  • Payment for courses and e-learning plan
  • Pick and view subjects
  • Post questions
  • Find and filter through online teachers
  • Select teachers.
  • Subscribe for the test series.
  • Consult with a mentor through live chat, video call.
  • Rate and review courses.

Teacher Panel Features

  • Registration
  • Manage detailed profile
  • Manage profile settings
  • Push messages for learner interaction
  • Schedule live classes
  • View ratings and reviews
  • Sort and answer doubts posted by students
  • Interact with learners through text, audio or video

Parents/Guardian Panel

  • Registration by email
  • Track learners performance
  • Track progress
  • Consult with mentors through chat
  • Check assignments and test results
  • Enroll subscription
  • Push notifications by mentors and Admins
  • Track attendance of learners
  • Check student leaderboard

Admin Panel Features

  • Manage mentors and students
  • Manage multiple subjects and courses
  • Learners details system management
  • Manage plan prices
  • Manage content
  • View reports for user engagement

Advanced features to add in e-learning mobile application

AI (Voice Command)

The availability of the Voice command simplifies the process of using the e-learning application for visually challenged students. AI can help a learner select a course via voice commands installed in the system.

Real-time analytics

Real-time analytics perform as a measuring stick for application actions and user behaviour with the application. Through this feature, one can eligibly track mobile learning assignments, learner progress, course completion, assessment score, and more.

Role-based dashboard

These dashboards help in measuring the overall actions of the application. This overview of the working of the app aids in finding out any deficiency in the app and working on improving the quality and productivity of the app.

Multiple languages support

Integrating an e-learning app with various languages can be more significant in the success of the application as the option of different languages makes users from all over the world be part of the application.

CMS Integration

CMS stands for a content management system and as we can know by its name, its work is to manage the content of the application. CMS plays a key in the application as it stores constant tabs on the content of the portal.

Discussion board

This program in the app makes increasing the interaction among the app customers. With the help of discussion forums, the app customers can simply produce a new topic or include a comment under the topic.

Leaderboard

Making the competition among the learners is a large way of motivating them and leaderboards are integrated into the application to do just that.

Chat room+Video steaming

This option makes the students ask their teacher a doubt about a topic through a text in the chat room even in the middle of the class. The mentor can stop proceeding further to pay attention to the doubt of the learner and only moves on after providing the student with the solution for his problem.

Video lesson streaming

E-learning applications are initially in attention as they give free video lessons for the learners. Through the e-learning apps, the students can stream a live video lesson to gain perfect knowledge on the topic they are looking to master.

Team structure for e-learning mobile app development

  • Project Manager
  • Android/ios Developers
  • Back-end developers
  • Front-end developers
  • UX/UI Designers
  • QA Testers
  • Delivery Manager

Cost of developing an e-learning mobile application

The cost of developing an e-learning mobile application depends on three factors:

  • The complexity of the app
  • Number of platforms
  • App development region

Conclusion

COVID-19 has really changed the world used to operate. New norms published by governments across the globe are strictly social distancing which provides e-learning with a hot prospect for current and future times. E-learning has already become popular and modernized but during this pandemic, it has become the main point of education. If you were looking to make an app that targets e-learning then these times are a great opportunity to kick start their ride. So, hire a reputed mobile app development company that could help you build an amazing application.

E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:www.linkedin.com/in/johnsontaugustine/

Case Study: Food Delivery App

- Posted in App Development by

Abstract:

Foodiday is a food delivery application that provides food delivery at your doorstep in very little time and with the best packaging and hygiene. By providing the food from every famous food place nearby online food ordering is the process of ordering food from an application. The product can be either ready-to-eat food. This online food ordering system sets up a food menu online and customers can easily track the orders. There are various facilities provided so that the users of the system will get service effectively. Increasing the use of smartphones is also considered as a motivation. So that any users of this system get all services with a single click. Another motivation can be considered as the system will be designed to avoid users making fatal errors, users can track their food items through GPS users can provide feedback and recommendations and can give ratings, It will give appropriate feedback to restaurants. In the proposed system there will be no limitation on the number of orders the customer wants.

Introduction:

With the development of Foodiday.We know that people look over the mobile app for ordering food to comfort their life. With the huge number of young professionals in the big cities, people can’t find much time to prepare food. By developing this food delivery app to make the job too easy in Kerala. Download this app from the play or app store, register into the app, select the menu to place food delivered to your doorstep. Most of the young professionals and other office goers found this method too easy to place a food delivery app in Kerala and has become in stand popular among users. People have a huge number of choices to select among the apps to compare and pay with offer price from online food ordering apps.

Foodiday is a food delivery app designed to make it simple to find and order food one is craving.

The time frame for developing a food delivery app:

  • While using flutter:16 weeks
  • While using Native-Android:16 weeks
  • While using Native-IOS:16 weeks

Below are some of the issues that we wanted the redesign to address.

The community of existing food delivery apps causes it hard to find dishes one wants.

  • Grouping dishes by eatery forces users to scroll through long restaurant menus
  • Many dishes have no pictures making it so effort to scan and know what they are ordering

Current explanations do not sufficiently address those with dietary restrictions

  • There are no options to ban foods with certain ingredients
  • User has to read dish explanations or avoid ordering from certain restaurants

Suggested restaurants and dishes are not personalized

  • No option to count dish or restaurant to favourites
  • Easy to reorder past dishes, but falls short of suggesting similar ones

The interface offers too many food options

  • Many customers who use the service are usually hungry, busy, or tired and needs instant-gratification
  • Do not require making too many decisions
  • Lower patience levels
  • Want things very quick

My Role

  • Do competitive study by trying contender apps and reading app reviews
  • Make user interviews with students and instructors who order food online or eat out
  • Develop and post user surveys online
  • Participate in generating user personas

Research

Domain Research

With the project idea expressed, the team identified the iOS App Store for food delivery apps. This gave us a better sense of the current food delivery apps out there. For each app, we determined what key elements they had and read reviews to determine pain points and what features people like. We used this data to formulate our user interview questions and will review them when making workflow and design decisions.

Below are some concepts collected from user reviews:

  • Need choice to cancel the order
  • Need right notification of delivery will be late
  • Notification if the dish is unavailable and suggests another
  • Advise customer if ordering near restaurant closing time
  • Option to include a dish to favourites for easy reordering
  • See order status and delivery ETA on the home screen
  • display contact info of deliverer and restaurant
  • display order number with client support phone number

User Interviews

My team reached around interviewing students and instructors to know about the following:

  • How often, why, when, and how they order food online
  • Why they would select one food delivery service over another
  • Their background using one of the food delivery services
  • How food allergies affect their placement experience
  • How they locate new restaurants and dishes
  • How they order food in the app
  • Areas they consider competitors can enhance on

As I had never ordered food online before, conducting user interviews gave me a better sense of what users run through in the ordering and delivery knowledge by responding to the 5 W’s (who, what, where, when, why, and how). It was also useful in coming up with more questions as unexpected points were introduced.

From the user interviews, we found that customers are:

  • Food-based or restaurant-based
  • Price susceptible and are concerned about delivery fees
  • Enjoying more correct order status information
  • Visually driven.
  • Neutral in helping local businesses and organics

User Surveys

Afterwards, we developed and deployed a user survey on different communities on Reddit which garnered 315 answers over 3 days. The survey was one of the key ways of deciding what elements are required and not with more significant confidence. It also ensures some of the user interview results.

The survey results also modified the initial project idea, which was a “Don’t make me think” technique to food ordering with customized proposals, rating, scheduling, and budgeting.

We discarded the scheduling and budgeting features as most people are not curious about scheduled deliveries and people order food a lot further from the app, making budgeting unusable.

Planning

With the research piece concluded, we drove onto the planning stage where we developed user personas, customer journey maps and user flow diagrams.

User Personas

From the user interview conclusions, we made 2 user personas, restaurant-based and food-based users. Restaurant-based users track the current model of food delivery apps where dishes are grouped by the restaurant. Food-based users follow a new model where they are more curious about finding dishes rather than restaurants.

Restaurant-Based

  • Need to visit the eatery first before ordering online
  • Need to read restaurant reviews and blog mentions
  • Usually, order from the usual restaurants
  • Will utilize whatever food delivery app the restaurant endorses

Food-Based

  • Enquire for food to satisfy one’s cravings.
  • Look at pictures to comprehend what to expect
  • Periodically tries ordering from new restaurants

Both

  • Don’t need to or couldn’t cook or pick up food
  • Deals price, restaurant type, delivery fees, and speed are the most
  • Looks at a distance, thoughts, pictures, and values when selecting a restaurant

Customer Journey Map

Afterwards, we made a current and prospective customer journey map to emphasize the touchpoints, actions, thoughts, and pain points. To help us know the current flow, we downloaded the foodiday mobile app and executed through methods to see how the apps completed or did not meet the user’s requirements.

User stories

Here are the user narratives showing the user’s plans for each major page.

Dishes page

  • As a restaurant-based user, I need to identify restaurants so I can call from my favourite restaurants
  • As a restaurant-based user, I enjoy discovering the best restaurants for a typical cuisine in my area so I can order delicious food
  • As a food-based user, I like to search for distinct dishes so I can see food I am craving for
  • As a user, I like to see presented dishes founded on my choices so I do not have to create as many decisions
  • As a user, I like to discover dishes with free delivery or other values so I can save money
  • As a user, I like to see my famous dishes so I can reorder them

Filter page

  • As a user, I like to sort dishes by distance, rating, cost, and favour so I can uncover dishes fast
  • As a user, I like to filter dishes by cuisine or allergies so the recommendations fit my tastes and dietary limitations

Dish info page

  • As a food-based user, I like to see pictures of words so I have an idea of what I am calling
  • As a user, I like to know which restaurant a dish comes from so I can create reported purchasing decisions
  • As a user, I like to check restaurant reviews before summoning so I can be guaranteed the food quality
  • As a user, I like to know the restaurant beginning hours so I understand when they can deliver
  • As a user, I like to count dishes to my favorites so I can readily revisit and/or reorder them
  • As a user, I like to be capable to convey a link to the dish to others so I can bring others to check it out
  • As a user, I want to customize dish toppings so the dish fits my tastes
  • As a user, I like to count a note to a dish so I can select element changes or omissions

Cart/Checkout page

  • As a user, I like to understand the estimated total before fitting out so I know how much I will be paying before I input the lesson and payment facts
  • As a user, I like to be able to go back to scanning so I can count more dishes to the cart
  • As a user, I like to change the dish options or remove dishes in case I switch my mind
  • As a user, I like to have my address and payment points saved so I can fit out faster
  • As a user, I like to be capable to count delivery instructions so the delivery agent can buzz themselves in
  • As a user, I want to have the opportunity to have the pass emailed to me so I can get job reimbursements

Order status page

  • As a user, I like to have the accurate GPS tracking of my order so I understand when it will arrive
  • As a user, I like to be able to call the client consent or the delivery agent so I can track up if something goes wrong
  • As a user, I like to be capable to cancel an order if I made a misstep
  • As a user, I like to order the food and delivery service individually so my rating is more precise
  • As a user, I like to pay the delivery tip after the delivery so I can tip according to the delivery rate
  • As a user, I like to see tickets of past orders so I have a record if the order that reaches is incorrect

Design

For this project, the group determined to try a hybrid approach to prototyping where rather than making the mockups from scratch for each set of fidelity, we repeated them. This will permit more time for testing and fixing the prototype. Extra time was also given to understanding how to build a high-fidelity prototype with spirits in Invision Studio.

E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:www.linkedin.com/in/johnsontaugustine/

What is bootstrap?

Bootstrap is an available and open-source CSS framework aimed at responsive, mobile-first front-end web development. It includes CSS- and javaScript-established design templates for typography, forms, buttons, navigation, and other components.

What is the bootstrap grid?

The Bootstrap Grid System is used for layout, especially Responsive Layouts. Recognition of how it operates is vital to understanding Bootstrap. The Grid is made up of groupings of Rows & Columns inside 1 or more containers. The Bootstrap Grid can be used only, without the Bootstrap JavaScript and other CSS Elements. You are just required to download and reference the “bootstrap-grid.css” which includes the Grid and Flexbox classes. More info on only doing the Bootstrap Grid CSS.

Here’s the most general example of using the Grid:

< div class="container">
  < div class="row">
     < div class="col">I'm your content in the grid! < /div>
  < /div>
< /div>

What are the different types of bootstrap grid systems?

Bootstrap grid is a great system for creating mobile-first layouts. It's a very extensive tool with a large number of benefits. Below we give you the core principles. It's an uncomplicated overview of the most generally used examples. Bootstrap’s grid system uses a set of containers, rows, and columns to design and align content. It’s built with a flexbox and is fully active.

What are the basic examples of a bootstrap grid system?

Below is an illustration and an in-depth explanation of how the grid system comes together.

< div class="container"> 
< div class="row">
 < div class="col-md"> One of three columns < /div> 
< div class="col-md"> One of three columns < /div> 
< div class="col-md"> One of three columns < /div> < /div> < /div>

The above example produces three equal-width columns across all devices and viewports using our predefined grid classes. Those columns are centered in the page with the parent .container.

Taking it to step by step:

Container

Bootstrap needs a containing component to wrap site contents and house our grid system. Without a container, the grid won't operate properly.

Row

Rows build parallel groups of columns. Therefore, if you need to break your layout horizontally, use row.

Columns

Bootstrap's grid system allows up to 12 columns across the page.

How does it work?

Breaking it down, here’s how the grid system comes together:

  • Our grid supports six responsive breakpoints. Breakpoints are based on min-width media questions, meaning they assume that breakpoint and all those preceding it. This means you can constrain container and column sizing and behaviour by each breakpoint.
  • Containers horizontally pad your content. Use .container for a responsive pixel width, .container-fluid for width: 100% across all viewports and devices, or a responsive container for the mixture of fluid and pixel widths.
  • Rows are covers for columns. Each column has horizontal padding for controlling the space between them. This padding is then checked on the rows with negative margins to defend the content in your columns is visually arranged down the left side. Rows also hold transformer classes to consistently apply column sizing and gutter classes to improve the spacing of your content

  • Columns are amazingly flexible. There are 12 template columns free per row, allowing you to perform different sequences of components that traverse any number of columns. Column classes show the number of template columns to span. widths are set in sections so you always have the same corresponding sizing.

  • Gutters are also warm and customizable. Gutter classes are open across all breakpoints, with all the same areas as our margin and padding spacing. Change regular gutters with .gx-* classes, upright gutters with .gy-*, or all gutters with .g-* classes. .g-0 is also available to switch gutters
  • Sass variables, maps, and mixins power the grid. If you don’t need to use the predefined grid properties in Bootstrap, you can do our grid’s origin Sass to build your own with more semiotic markup. We also add some CSS custom properties to consume these Sass components for even larger flexibility for you.

What are the most common examples?

A few of the most popular grid layout examples to get you close with construction within the Bootstrap grid system.

Five grid tiers

There are five Bootstrap grid system, one for each range of devices we support. Each tier creates at a minimum viewport size and default to the greater systems unless overridden.

< div class="row">
  < div class="col-4">.col-4< /div>
  < div class="col-4">.col-4< /div>
  < div class="col-4">.col-4< /div>
< /div>
< div class="row">
  < div class="col-sm-4">.col-sm-4< /div>
  < div class="col-sm-4">.col-sm-4< /div>
  < div class="col-sm-4">.col-sm-4< /div>
< /div>
< div class="row">
  < div class="col-md-4">.col-md-4< /div>
  < div class="col-md-4">.col-md-4< /div>
  < div class="col-md-4">.col-md-4< /div>
< /div>
< div class="row">
  < div class="col-lg-4">.col-lg-4< /div>
  < div class="col-lg-4">.col-lg-4< /div>
  < div class="col-lg-4">.col-lg-4< /div>
< /div>
< div class="row">
  < div class="col-xl-4">.col-xl-4< /div>
  < div class="col-xl-4">.col-xl-4< /div>
  < div class="col-xl-4">.col-xl-4< /div>
< /div>

Three equal columns Get three equal-width columns starting at desktops and scaling to great desktops. On devices, tablets and below, the columns will default stack.

< div class="row">
  < div class="col-md-4">.col-md-4< /div>
  < div class="col-md-4">.col-md-4< /div>
  < div class="col-md-4">.col-md-4< /div>
< /div>

Three unequal columns

Get three columns begins at desktops and scaling to multiple widths. Don’t forget, grid columns should include up to twelve for a single block. More than that, and columns create stacking no matter the viewport.

< div class="row">
  < div class="col-md-3">.col-md-3< /div>
  < div class="col-md-6">.col-md-6< /div>
  < div class="col-md-3">.col-md-3< /div>
< /div>

Two columns

Get two columns creating at desktops and scaling to great desktops.

< div class="row">
  < div class="col-md-8">.col-md-8< /div>
  < div class="col-md-4">.col-md-4< /div>
< /div>

Two columns with two nested columns

nesting are simple—just put a row of columns within an existing column. This provides you two columns scaling to large desktops, with another two within the larger column.

At mobile machines sizes, tablets and down, these columns and nested columns will stack.

< div class="row">
  < div class="col-sm-6 col-lg-8">.col-sm-6 .col-lg-8< /div>
  < div class="col-6 col-lg-4">.col-6 .col-lg-4< /div>
< /div>
< div class="row">
  < div class="col-6 col-sm-4">.col-6 .col-sm-4< /div>
  < div class="col-6 col-sm-4">.col-6 .col-sm-4< /div>
  < div class="col-6 col-sm-4">.col-6 .col-sm-4< /div>
< /div>

Mixed: mobile and desktop

The Bootstrap v5 grid system has five t classes: xs, small, medium, large, and extra-large. You can use almost any mixture of these classes to build more dynamic and suitable layouts.

Each classes scales up, meaning if you plan on setting the equal widths for md, lg and xl, you only require to md.

< div class="row">
  < div class="col-md-8">.col-md-8< /div>
  < div class="col-6 col-md-4">.col-6 .col-md-4< /div>
< /div>
< div class="row">
  < div class="col-6 col-md-4">.col-6 .col-md-4< /div>
  < div class="col-6 col-md-4">.col-6 .col-md-4< /div>
  < div class="col-6 col-md-4">.col-6 .col-md-4< /div>
< /div>
< div class="row">
  < div class="col-6">.col-6< /div>
  < div class="col-6">.col-6< /div>
< /div>

Containers

Additional included classes in Bootstrap make containers that are wide until a particular breakpoint.

< div class="container">.container< /div>
< div class="container-sm">.container-sm< /div>
< div class="container-md">.container-md< /div>
< div class="container-lg">.container-lg< /div>
< div class="container-xl">.container-xl< /div>
< div class="container-xxl">.container-xxl< /div>
< div class="container-fluid">.container-fluid< /div>

If you have any doubt about this Bootstrap tutorial. If you want any software consultations and services, Don’t hesitate to contact us through the given email. Airo global software will always be your digital partner.

E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:www.linkedin.com/in/johnsontaugustine/

What is Adobe XD?

Adobe XD is a vector-placed UI and UX design tool and it can be used to design anything from smartwatch applications to full-fledged websites. Let’s take a glance at what it gives designers and why it’s become such a dominant tool in web design management.

What is Adobe XD used for?

What’s essential to retain is that Adobe XD addresses the two main problems Photoshop and other graphics applications couldn’t:

  1. Communication design isn’t static. A designer cannot give a fluid and dynamic design using pixels simply.
  2. A modern design method requires more than a polished completed article. Wireframing, iteration, and performance are all part of the collaborative arrangement with UI and UX design.

Adobe XD is a model for vector-based UI design, wireframing, interactive design, prototyping, and great-fidelity web design, for whole teams.

How can you export Adobe XD assets?

Start your Adobe XD file and choose the asset or the artboard you require to export. To select an artboard, select the artboard title.

You can also identify assets or artboards for exportation and then export them all in size. To mark assets for export, remove the Layers panel and press the Mark for Batch Export icon.

To transport a JPEG on macOS, select File > Export. On Windows, select the Hamburger menu, and select Export. There are 3 options to export:

  • Batch: Export assets that are identified using the Mark for Export option.
  • Selected: Export chosen assets.
  • All Artboards: To transport all the artboards in your design.

When you transport assets as JPEG, you can place the state level of the exported JPEG according to your requirements. Want any of the percentage benefits in the Quality drop-down list, navigate to the destination folder, and click Export.

If you have any doubt about this Adobe XD tutorial and Adobe XD plugins. Don’t hesitate to contact us through the given email. Airo global software will always be your digital partner.

E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile:www.linkedin.com/in/johnsontaugustine/

What Is Augmented Reality In Flutter?

- Posted in Flutter by

AR core in flutter is a wonderful plugin that gives us an API to perform Augmented presence in flutter applications. This is one of the emerging new technologies in the business. With this plugin, we shall consider the different features presented by this plugin the flutter, so let’s start.

How to Enable ARCore?

To qualify ARCore functionality in Android Studio you require to complete the following steps:-

  1. Include AR Required or AR Optional entries to the manifestAR

    Required

You need to include the below entries in your AndroidManifest.xml file:-

< uses-permission android:name="android.permission.CAMERA"  />
< uses-sdk android:minSdkVersion="24" />
< uses-feature android:name="android.hardware.camera.ar" />
< application …>
   < meta-data android:name="com.google.ar.core" android:value="required" />

AR Optional
< uses-permission android:name="android.permission.CAMERA" />
< uses-sdk android:minSdkVersion="14" />
< application>
   < meta-data android:name="com.google.ar.core" android:value="optional" />
< /application>

The difference between the AR Optional and AR Required is that AR Required app requires an ARCore Supported Devices that had Google Play Services for AR-enabled in it. In AR Required apps the play store automatically stores the Google Play Services for AR.

While in AR Optional apps can be installed and run on the machines that don’t support ARCore and also play store will not enable the Google Play Services for AR automatically.

  1. Modify build.gradle

Please ensure that your project's build.gradle file includes the below code.

allprojects {
   repositories {
       google()

Add the below dependencies in your app-level build.gradle file

dependencies {
 implementation 'com.google.ar:core:1.16.0'
}
  1. Sceneform plugin in your app-level build.gradle file
android {
   compileOptions {
       sourceCompatibility 1.8
       targetCompatibility 1.8
}
dependencies {
   implementation 'com.google.ar.sceneform.ux:sceneform-ux:1.8.0'
   implementation 'com.google.ar.sceneform:core:1.8.0'
}
  1. Enable android X

Include the below code into your gradle.properties

org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

Which are the Classes provided by the plugin?

There are a total of 13 classes provided by this plugin.

  • ArCoreView
  • ArCoreController
  • ArCoreFaceView
  • ArCoreFaceContrller
  • ArCoreSphere
  • ArCoreCylinder
  • ArCoreCube
  • ArCoreNode
  • ArCoreMaterial
  • ArCoreHitTestResult
  • ArCoreRotatingNode
  • ArCorePlane
  • ArCoreReferenceNode

ArCoreView

This class returns the view kinds. There are two kinds of views in it.

  • AUGMENTEDFACE
  • STANDARDVIEW

There are 4 properties in it:-

  • onArCoreViewCreated
  • enableTapRecoginzer
  • enableUpdateListener
  • type

onArCoreViewCreated

This kind takes an ArCoreController. We shall discuss ArCoreController in our later section.

enableTapRecoginzer

Initially, set to false. It is made an augment by MethodChannel.

enableUpdateListener

Initially, set to false. It is used as an augment by the MethodChannel.

type

It is a view type, it is AUGMENTEDFACE, STANDARDVIEW. It is set to STANDARDVIEW by automatic.

ArCoreController

This controller used to add a ArNode using addArCoreNode function, include a ArCoreNode with anchor using a addArCoreNodeWithAncher function and also remove node using removeNode function.

ArCoreFaceView

It is a stateful widget that makes an ArCoreAndroidView. It has two characters: enableAugmentedFaces, onArCoreViewCreated.

At first, enableAugmentedFaces is set to false.

onArCoreViewCreated takes a program with an ArCoreController augment.

ArCoreFaceController

It is used to dispose of and loadMesh the method to control the FaceView.

ArCoreSphere

It is ArCoreShape, which takes a radius and ArCoreMaterial.

ArCoreCylender

It is ArCoreShape, which takes a radius, height, and ArCoreMaterial.

ArCoreCube

It is ArCoreShape, takes a size i.e. Vector3 and ArCoreMaterial.

ArCoreNode

This widget is used to give the position, shape, scale, rotation, name.

ArCoreMaterial

It is used to make the outlook of the virtual type generated by the user.

It has colour, texture bytes, metallic, roughness, reflection.

ArCoreRotatingNode

It is an ArCoreNode with a degree per second property which is a double value.

ArCorePlane

It takes the x, y of the plane, ArCorePose, and ArCorePlaneType.

There are three kinds of plane:-

  • HORIZONTAL_UPWARD_FACING
  • HORIZONTAL_DOWNWARD_FACING
  • VERTICAL

ArCoreReferenceNode

It is ArCoreNode, it has all the characteristics that the ArCoreNode has also it has objectUrl and object3DFileName.

objectUrl

URL of glft object for remote rendering.

object3DFileName

Filename of sfb object in assets folder. Making a Sphere

void _addSphere(ArCoreController controller) {
 final material = ArCoreMaterial(
   color: Color.fromARGB(120, 66, 134, 244),
 );
 final sphere = ArCoreSphere(
   materials: [material],
   radius: 0.1,
 );
 final node = ArCoreNode(
   shape: sphere,
   position: vector.Vector3(0, 0, -1.5),
 );
 controller.addArCoreNode(node);
}

Making a Cylinder

void _addCylinder(ArCoreController controller) {
 final material = ArCoreMaterial(
   color: Colors.red,
   reflectance: 1.0,
 );
 final cylinder = ArCoreCylinder(
   materials: [material],
   radius: 0.5,
   height: 0.3,
 );
 final node = ArCoreNode(
   shape: cylinder,
   position: vector.Vector3(0.0, -0.5, -2.0),
 );
 controller.addArCoreNode(node);
}

Making a Cube

void _addCube(ArCoreController controller) {
 final material = ArCoreMaterial(
   color: Color.fromARGB(120, 66, 134, 244),
   metallic: 1.0,
 );
 final cube = ArCoreCube(
   materials: [material],
   size: vector.Vector3(0.5, 0.5, 0.5),
 );
 final node = ArCoreNode(
   shape: cube,
   position: vector.Vector3(-0.5, 0.5, -3.5),
 );

 controller.addArCoreNode(node);
}

main.dart file

import 'package:arcore_flutter_plugin/arcore_flutter_plugin.dart';
import 'package:flutter/material.dart';
import 'package:vector_math/vector_math_64.dart' as vector;
void main() {
 runApp(HelloWorld());
}
class HelloWorld extends StatefulWidget {
 @override
 _HelloWorldState createState() => _HelloWorldState();
}
class _HelloWorldState extends State {
 ArCoreController arCoreController = ArCoreController();
 @override
 Widget build(BuildContext context) {
   return MaterialApp(
     home: Scaffold(
       appBar: AppBar(
         title: const Text('Hello World'),
       ),
       body: ArCoreView(
         onArCoreViewCreated: _onArCoreViewCreated,

       ),
     ),
   );
 }
 void _onArCoreViewCreated(ArCoreController controller) {
   arCoreController = controller;
   _addSphere(arCoreController);
   _addCylinder(arCoreController);
   _addCube(arCoreController);
 }
 void _addSphere(ArCoreController controller) {
   final material = ArCoreMaterial(
     color: Color.fromARGB(120, 66, 134, 244),
   );
   final sphere = ArCoreSphere(
     materials: [material],
     radius: 0.1,
   );
   final node = ArCoreNode(
     shape: sphere,
     position: vector.Vector3(0, 0, -1.5),
   );
   controller.addArCoreNode(node);
 }
 void _addCylinder(ArCoreController controller) {
   final material = ArCoreMaterial(
     color: Colors.red,
     reflectance: 1.0,
   );
   final cylinder = ArCoreCylinder(
     materials: [material],
     radius: 0.5,
     height: 0.3,
   );
   final node = ArCoreNode(
     shape: cylinder,
     position: vector.Vector3(0.0, -0.5, -2.0),
   );
   controller.addArCoreNode(node);
 }
 void _addCube(ArCoreController controller) {
   final material = ArCoreMaterial(
     color: Color.fromARGB(120, 66, 134, 244),
     metallic: 1.0,
   );
   final cube = ArCoreCube(
     materials: [material],
     size: vector.Vector3(0.5, 0.5, 0.5),
   );
   final node = ArCoreNode(
     shape: cube,
     position: vector.Vector3(-0.5, 0.5, -3.5),
   );
   controller.addArCoreNode(node);
 }
 @override
 void dispose() {
   arCoreController.dispose();
   super.dispose();
 }
}

If you have any doubt about this augment reality in flutters. If you want any software consultations and services, Don’t hesitate to contact us through the given email. Airo global software will always be your digital partner.

E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

Zeplin is a well-designed curriculum that feels lightweight but is really pretty robust. I'd say it's proper to call it the industry standard for delivering off designs to engineering. Here's a quick walkthrough.

What is Zeplin?

Zeplin is a collaboration device for UI designers and front-end developers to help teams with the design hand-off, allowing designers to upload their wireframe designs from Sketch and add them to project folders in Zeplin.

Why should anyone use Zeplin?

One should use Zeplin for the below reasons -

  1. Once you build mockups on the sketch, all you have to do is transport the artboards on Zeplin with the select a single button.
  2. Zeplin provides you to club added artboards into a group and arrange them according to your choice which will be repeated in every other user who is a member of the project.
  3. That being said, various users can run on a project and add comments or bookmark any particular mockup.
  4. It follows version control very effectively and updates mockups accordingly.

How to use Zeplin to automatically generate measures, styles, and assets?

  • Download Zeplin and create an account
    Go over to zeplin.io to build a Zeplin information and connect the Mac app. You get 1 project for free.
  • Start a new project in Zeplin
    Once you've established Zeplin on your Mac, keep your project type.
  • Choose your pixel density
    If you're running with the standard iPhone artboard in Sketch, you're running in 1x.
  • Export your artboard from Sketch to Zeplin
    With the artboard chosen, use the easy-to-remember shortcut to transport the artboard to Zeplin.
  • View your mockup in Zeplin
    In Zeplin you can agree on any element in your plan to get all of its features: position, spacing, color, text styles, etc. They even provide you with a nice "copy" button so you can simply take the exact copy you've written, eliminating any room for error in spelling.
  • Share the specs with your developer
    If you'd like to share a single screen, you can quickly grab a link from the right-hand panel when observing an original screen in Zeplin.

However, I'd suggest going back to the Project Dashboard view in Zeplin, where you can request the developer to the project using their email address.

Those are the basics of Zeplin, and frankly, there's not much difference to it, which is excellent. Try it as a free account and see if it improves your workflow. Zeplin also has a Slack combination that will suggest channels when innovative designs are combined or changed. I've found it to be a bit overkill, but if you're into that sort of thing, then go for it!

If you have any doubt about the above topic. Don’t hesitate to contact us through the below email. Airo Global Software will be your digital partner.

E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

enter image description here

There are multiple social login features to use in Android apps. Here we will know about social login using Facebook, so we need to integrate the Facebook SDK in the project to make use of Facebook login.

What are the steps needed to build a Facebook login page?

First thing you need to do is to have a Facebook developer account and then build a new app. Install android studio and open or create a new project where you want to include Facebook login. In your project, include the following code in your Project.

buildscript{
    repositories {
        jcenter()
    }
}

Now, add the following code in Module:app with the new version of Facebook Login SDK in it.

dependencies {
     implementation 'com.facebook.android:facebook-android-sdk:5.0.0'
}

Sync the project Now start with app -> res -> values -> strings.xml file to include the lines and replace the [APP_ID] with your APP_ID, which you can get from Facebook Developer console. Open app -> manifest -> manifest file and add this line outside of the application. Include the meta-data element inside the app element in AndroidManifest.xml file. Now first thing you need is Key Hash, so include these lines in the activity class before Facebook login code:

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

...
  
    public void
    printHashKey()
{
  
    // Add code to print out the key hash
    try {
  
        PackageInfo info
            = getPackageManager().getPackageInfo(
                "com.android.facebookloginsample",
                PackageManager.GET_SIGNATURES);
  
        for (Signature signature : info.signatures) {
  
            MessageDigest md
                = MessageDigest.getInstance("SHA");
            md.update(signature.toByteArray());
            Log.d("KeyHash:",
                  Base64.encodeToString(                      md.digest(),
                      Base64.DEFAULT));
        }
    }
  
    catch (PackageManager.NameNotFoundException e) {
    }
  
    catch (NoSuchAlgorithmException e) {
    }
}

Now run the application. You will see Key Hash value in logcat, save this for later needs. Go to Facebook Developers console and choose setting -> Basic -> Add Platform and a popup will open up to select a platform. Select Android as a platform. Include your project package name under ‘Google Play Package Name’. Add the class name where login will be implemented in projects like ‘LoginActivity’ and also include the key hash value under ‘Key Hashes’. Now in android studio, include this personalised button in your *.xml layout file:

Include this code in app -> res -> styles.xml :

You can personalize this button instead of an above custom button, you can use the Facebook button also as Facebook LoginButton. Make a file named ‘bg_button_facebook.xml’ in app -> res -> drawable folder Now make a button in *.java file and some syntax to initialize Facebook SDK :

// Declare variables
private Button mButtonFacebook;
  
private CallbackManager callbackManager;
private LoginManager loginManager;
 ...
      @Override
    protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
     ...
          mButtonFacebook
        = findViewById(R.id.button_facebook);
    FacebookSdk.sdkInitialize(MainActivity.this);
    callbackManager = CallbackManager.Factory.create();
    facebookLogin();
    ...
          mButtonFacebook.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v)
            {
                loginManager.logInWithReadPermissions(
                    MainActivity.this,
                    Arrays.asList(
                        "email",
                        "public_profile",
                        "user_birthday"));
            }
        });
    ...
}
 ...

Add ‘facebookLogin’ option outside onCreate() in the java file. This is the program code for Facebook login response.

public void facebookLogin()
{
      loginManager
        = LoginManager.getInstance();
    callbackManager
        = CallbackManager.Factory.create();
      loginManager
        .registerCallback(
            callbackManager,
            new FacebookCallback() {
                  @Override
                public void onSuccess(LoginResult loginResult)
                {
                    GraphRequest request = GraphRequest.newMeRequest(
                          loginResult.getAccessToken(),
                         new GraphRequest.GraphJSONObjectCallback() {
                              @Override
                            public void onCompleted(JSONObject object,
                                                    GraphResponse response)
                            {
                                  if (object != null) {
                                    try {
                                        String name = object.getString("name");
                                        String email = object.getString("email");
                                        String fbUserID = object.getString("id");
                                          disconnectFromFacebook();
  
                                        // do action after Facebook login success
                                        // or call your API
                                    }
                                    catch (JSONException | NullPointerException e) {
                                        e.printStackTrace();
                                    }
                                }
                            }
                        });
  
                    Bundle parameters = new Bundle();
                    parameters.putString(
                        "fields",
                        "id, name, email, gender, birthday");
                    request.setParameters(parameters);
                    request.executeAsync();
                }
                  @Override
                public void onCancel()
                {
                    Log.v("LoginScreen", "---onCancel");
                }
                  @Override
                public void onError(FacebookException error)
                {
                    // here write code when get error
                    Log.v("LoginScreen", "----onError: "
                                             + error.getMessage());
                }
            });
}

Now include another needed option ‘disconnectFromFacebook’ for login , similarly add this to onCreate. This is used to disconnect applications from Facebook as there is no need to stay connected.

public void disconnectFromFacebook()
{
    if (AccessToken.getCurrentAccessToken() == null) {
        return; // already logged out
    }
  
    new GraphRequest(
        AccessToken.getCurrentAccessToken(),
        "/me/permissions/",
        null,
        HttpMethod.DELETE,
        new GraphRequest
            .Callback() {
                @Override
                public void onCompleted(GraphResponse graphResponse)
                {
                    LoginManager.getInstance().logOut();
                }
            })
        .executeAsync();
}

Include ‘onActivityResult’ option onCreate in same activity:

@Override
protected void onActivityResult(int requestCode,
                                int resultCode,
                                Intent data)
{
      // add this line
    callbackManager.onActivityResult(
        requestCode,
        resultCode,
        data);
      super.onActivityResult(requestCode,
                           resultCode,
                           data);
}

Now you are finished with the coding. Run your application in your emulator. You can now login with Facebook also in your application. If you have any questions about the above topic or have to get services and consultations and get the best Android application services. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your strong digital partner. E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

How Geofencing define the Dart API?

Before signing any platform-specific code, I’ll first want to determine the Dart API for the geofencing plugin. Since Android and ios, several have their own APIs for designating and managing geofencing events, I want the Dart interface to present a reduced geofencing abstraction that is harmonious with both programs. Without going into too much detail about Android and iOS APIs, the following approximately represents the Dart interface that I’ll use for my plugin:

abstract class GeofenceRegion {
 /// The ID associated with the geofence.
 ///
 /// This ID identifies the geofence and is required to delete a
 /// specific geofence.
 final String id;

 /// The location (center point) of the geofence.
 final Location location;

 /// The radius around `location` that is part of the geofence.
 final double radius;

 /// Listen to these geofence events.
 final List triggers;

 /// Android-specific settings for a geofence.
 final AndroidGeofencingSettings androidSettings;

 GeofenceRegion(
   this.id, double latitude, double longitude, this.radius, this.triggers,
   {AndroidGeofencingSettings androidSettings});
}

abstract class GeofencingPlugin {
 /// Initialize the plugin and request relevant permissions from the user.
 static Future initialize() async;

 /// Register for geofence events for a [GeofenceRegion].
 ///
 /// `region` is the geofence region to register with the system.
 /// `callback` is the method to be called when a geofence event associated
 /// with `region` occurs.
 static Future registerGeofence(
   GeofenceRegion region,
   void Function(List id, Location location, GeofenceEvent event) callback);

 /// Stop receiving geofence events for a given [GeofenceRegion].
 static Future removeGeofence(GeofenceRegion region);


 /// Stop receiving geofence events for an identifier associated with a
 /// geofence region.
 static Future removeGeofenceById(String id) async;
}

This interface provides the below programmers to users of the plugin: The ability to create instances of GeofenceRegion, which include the emerges and radius of a geofence, a unique ID, and a collection of geofencing programmers to listen for. Since Android gives a richer set of lists for explaining geofences than iOS, Android-specific opportunities are made getting through the chosen androidSettings property. GeofencingPlugin.registerGeofence makes for the registration of a GeofenceRegion instance with a callback that is involved when a geofence event for that area is got. GeofencingPlugin.removeGeofence and GeofencingPlugin.removeGeofenceById will not a GeofenceRegion from triggering more events. Overall, this mode is rather simple and action-agnostic, making the plugin simple to act on both Android and iOS. Dart surronding execution This segment covers how to set up your isolate for experience execution. You will discover how to reference callbacks, and how to use the callback dispatcher. Referencing Callbacks Now that the Dart interface is defined, start figuring plumbing to communicate with the platform-particular divisions of the plugin. For example, the following program initializes the geofencing plugin and displays the geofences:

abstract class GeofencingPlugin {

 static const MethodChannel _channel =

     const MethodChannel('plugins.flutter.io/geofencing_plugin');

 static Future initialize() async {


   final callback = PluginUtilities.getCallbackHandle(callbackDispatcher);


   await _channel.invokeMethod('GeofencingPlugin.initializeService',


       [callback.toRawHandle()]);


 }

 static Future registerGeofence(


     GeofenceRegion region,


     void Function(List id, Location location, GeofenceEvent event)


         callback) {


   if (Platform.isIOS &&


       region.triggers.contains(GeofenceEvent.dwell) &&


       (region.triggers.length == 1)) {


     throw UnsupportedError("iOS does not support 'GeofenceEvent.dwell'");


   }


   final args = [


     PluginUtilities.getCallbackHandle(callback).toRawHandle()


   ];


   args.addAll(region._toArgs());
   _channel.invokeMethod('GeofencingPlugin.registerGeofence', args);


 }

 /*


 * … `removeGeofence` methods here …


 */


}

If you’ve previously created Flutter plugins and are common with MethodChannel, this should look is wanted, for the most part. However, the two calls to PluginUtilities.getCallbackHandle might outstanding. In order to provoke a Dart callback as a result of a surrounding event, you must take a handle that is passed among Dart and platform code while also keeping for lookup of the callback across platform threads and Dart. Retrieving a CallbackHandle for a method from PluginUtilities.getCallbackHandle has the bad effect of multiplying a callback cache within the Flutter engine. These cache maps details needed to wanted callbacks to raw integer handles, which are easy hashes added aimed at the properties of the callback. This cache persists across publishes, but be know that callback lookups may lose if the callback is renamed or moved and PluginUtilities.getCallbackHandle is not called for the updated version of callback. In the code that given, two instances of CallbackHandle are accessed one for the callback, which is assisted with a GeofenceRegion, and another for an option of the name callbackDispatcher. The callbackDispatcher method, the entry point of the background loneliness, is the reason for preprocessing raw geofence event data, seeing up callbacks via PluginUtilities.getCallbackFromHandle, and invoking them for registered geofences. The Callback Dispatcher As told at the end of the previous section, This pattern access for acting the initialization needed to establish connection channels with acting code while also allowing for the formation of non-trivial interfaces for callback options. For this geofencing plugin, the callback dispatcher planning is as follows:

void callbackDispatcher() {

 const MethodChannel _backgroundChannel =
    MethodChannel('plugins.flutter.io/geofencing_plugin_background');

 WidgetsFlutterBinding.ensureInitialized();

 _backgroundChannel.setMethodCallHandler((MethodCall call) async {


   final args = call.arguments;


   final Function callback = PluginUtilities.getCallbackFromHandle(


       CallbackHandle.fromRawHandle(args[0]));


   assert(callback != null);

   // 3.2. Preprocess arguments.

   final triggeringGeofences = args[1].cast();

   final locationList = args[2].cast();

   final triggeringLocation = locationFromList(locationList);


   final GeofenceEvent event = intToGeofenceEvent(args[3]);

   callback(triggeringGeofences, triggeringLocation, event);

 });
 _backgroundChannel.invokeMethod('GeofencingService.initialized');


}

As you can see, on the formation of callbackDispatcher only four methods are performed. a MethodChannel is made for listening to options from the plugin. Next, WidgetsFlutterBinding.ensureInitialized() is known to initialize the state required to connect with the Flutter engine. At this point, the MethodCall handler is set to work with plugin programmers before at last notifying the action portion of the plugin that the background makes it is mentioned and starting the handling events. Once the plugin is created transform programmers to the callback dispatcher, the callback given to the plugin user can be invoked. First, PluginUtilities.getCallbackFromHandle is known to take a moment of the callback assisted with the provoked geofencing program using the raw callback to hold. Next, the raw materials from the MethodCall are made into: A moment of List for the IDs of the geofences that were provoked. The moment that Location describes the current area of the machine An instance of the GeofenceEvent enum represents whether the machine has typed, exited, or dwelled within the provoked geofences. Then give this info as rules to our callback.

Background execution: Android For the Android installation of the plugin, I’ll be required to make the following sections: The GeofencingPlugin class, which is created with the Flutter engine in order to get and handle method calls built from Dart code A GeofencingBroadcastReceiver, which is provoked by the system on a geofence event The GeofencingService, which made the background isolate, merges the callback dispatcher defined earlier and processes geofence programmes invoking the callback dispatcher. Creating Geofences In order to influence options, select an instance of MethodChannel on the same channel from the past, and then register the GeofencingPlugin instance with this channel in the implementation of onAttachedToEngine:

override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {

 mContext = binding.getApplicationContext()

 mGeofencingClient = LocationServices.getGeofencingClient(mContext!!)


 val channel = MethodChannel(binding.getBinaryMessenger(), "plugins.flutter.io/geofencing_plugin")


 channel.setMethodCallHandler(this)


}

In order to manage these needs, onMethodCall is required to install:

override fun onMethodCall(call: MethodCall, result: Result) {




 val args = call.arguments>()


 when(call.method) {


   "GeofencingPlugin.initializeService" -> {


     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {


       mActivity?.requestPermissions(REQUIRED_PERMISSIONS, 12312)


     }


     // Simply stores the callback handle for the callback dispatcher


     initializeService(mContext!!, args)


     result.success(true)


   }


   "GeofencingPlugin.registerGeofence" -> registerGeofence(mContext!!,


           mGeofencingClient!!,


           args,


           result,


           true)


   "GeofencingPlugin.removeGeofence" -> removeGeofence(mContext!!,


           mGeofencingClient!!,


           args,


           result)


   else -> result.notImplemented()


 }


}

At last, include the skill to register geofences

@JvmStatic

private fun getGeofencingRequest(geofence: Geofence, initialTrigger: Int): GeofencingRequest {


 return GeofencingRequest.Builder().apply {


   setInitialTrigger(initialTrigger)


   addGeofence(geofence)


 }.build()

}
@JvmStatic


private fun getGeofencePendingIndent(context: Context, callbackHandle: Long): PendingIntent {


val intent = Intent(context, GeofencingBroadcastReceiver::class.java)


       .putExtra(CALLBACK_HANDLE_KEY, callbackHandle)


return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)


}

// TODO(bkonyi): Reregister geofences after reboot


// https://developer.android.com/training/location/geofencing


@JvmStatic


private fun registerGeofence(context: Context,


                             geofencingClient: GeofencingClient,


                             args: ArrayList<*>?,


                             result: Result?) {


 val callbackHandle = args!![0] as Long


 val id = args[1] as String


 val lat = args[2] as Double


 val long = args[3] as Double


 val radius = (args[4] as Number).toFloat()


 val fenceTriggers = args[5] as Int


 val initialTriggers = args[6] as Int


 val expirationDuration = (args[7] as Int).toLong()


 val loiteringDelay = args[8] as Int


 val notificationResponsiveness = args[9] as Int


 val geofence = Geofence.Builder()


         .setRequestId(id)


         .setCircularRegion(lat, long, radius)

         .setTransitionTypes(fenceTriggers)

         .setLoiteringDelay(loiteringDelay)
         .setNotificationResponsiveness(notificationResponsiveness)
         .setExpirationDuration(expirationDuration)
         .build()
 // Ensure permissions are set properly.

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
        (context.checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)

                 == PackageManager.PERMISSION_DENIED)) {
   val msg = "'registerGeofence' requires the ACCESS_FINE_LOCATION permission."
   Log.w(TAG, msg)
   result?.error(msg, null, null)

 }
 ofencingClient.addGeofences(getGeofencingRequest(geofence, initialTriggers),

         getGeofencePendingIndent(context, callbackHandle))?.run {

   addOnSuccessListener {
     Log.i(TAG, "Successfully added geofence")
     result?.success(true)
   }
   addOnFailureListener {
     Log.e(TAG, "Failed to add geofence: $it")
     result?.error(it.toString(), null, null)
   }
 }
}

Scheduling the geofencing service:

class GeofencingBroadcastReceiver : BroadcastReceiver() {
 companion object {
   private const val TAG = "GeofencingBroadcastReceiver"
 }
 override fun onReceive(context: Context, intent: Intent) {
   FlutterMain.startInitialization(context)
   FlutterMain.ensureInitializationComplete(context, null)
   GeofencingService.enqueueWork(context, intent)
 }
}

Handling Geofence Events using the below code:

private fun startGeofencingService(context: Context) {
 synchronized(sServiceStarted) {
   mContext = context
   // dispatcher.
   if (sBackgroundFlutterEngine == null) {
     val callbackHandle = context.getSharedPreferences(

        GeofencingPlugin.SHARED_PREFERENCES_KEY,

         Context.MODE_PRIVATE)
         .getLong(GeofencingPlugin.CALLBACK_DISPATCHER_HANDLE_KEY, 0)

     if (callbackHandle == 0L) {

       Log.e(TAG, "Fatal: no callback registered")
       return
     }
     val callbackInfo = FlutterCallbackInformation.lookupCallbackInformation(callbackHandle)

     if (callbackInfo == null) {

       Log.e(TAG, "Fatal: failed to find callback")

       return

     }

     sBackgroundFlutterEngine = FlutterEngine(context)

     val args = DartCallback(

       context.getAssets(),

       FlutterMain.findAppBundlePath(context)!!,

       callbackInfo

     )
     sBackgroundFlutterEngine!!.getDartExecutor().executeDartCallback(args)

   }

 }
 mBackgroundChannel = MethodChannel(sBackgroundFlutterEngine!!.getDartExecutor().getBinaryMessenger(),

     "plugins.flutter.io/geofencing_plugin_background")

 mBackgroundChannel.setMethodCallHandler(this)

}

After startGeofencingService is completed execution, onHandleWork is called by the machine with the Intent that was lined up earlier:

 val locationList = listOf(location.latitu
override fun onHandleWork(intent: Intent) {

 val callbackHandle = intent.
   getLongExtra(GeofencingPlugin.CALLBACK_HANDLE_KEY, 0)
 val geofencingEvent = GeofencingEvent.fromIntent(intent)
 if (geofencingEvent.hasError()) {
   Log.e(TAG, "Geofencing error: ${geofencingEvent.errorCode}")

   return
 }
 val geofenceTransition = geofencingEvent.geofenceTransition
 val triggeringGeofences = geofencingEvent.triggeringGeofences.map {
   it.requestId
 }

 val location = geofencingEvent.triggeringLocation

de,
   location.longitude)
 val geofenceUpdateList = listOf(callbackHandle,
   triggeringGeofences,
   locationList,
   geofenceTransition)
  
 synchronized(sServiceStarted) {
   if (!sServiceStarted.get()) {
    
     queue.add(geofenceUpdateList)
   } else {
     
     mBackgroundChannel.invokeMethod("", geofenceUpdateList)
   }
 }
}

You have to write the below code next:

override fun onMethodCall(call: MethodCall, result: Result) {

 if (call.method == "GeofencingService.initialized") {

   synchronized(sServiceStarted) {

     while (!queue.isEmpty()) {

       mBackgroundChannel.invokeMethod("", queue.remove())

     }

     sServiceStarted.set(true)

     result.success(null)

   }

 } else {

   result.notImplemented()
 }
}

At this point, the GeofencingService is fully initialized and any geofencing events that have lined up are sent to the callback dispatcher. Background execution: iOS Now that the geofencing plugin implementation for Android is completed, the same geofencing program is required to be implemented for iOS. Initializing the plugin using the below code

+ (void)registerWithRegistrar:(NSObject *)registrar {

 @synchronized(self) {

   if (instance == nil) {

     NSLog(@"Registering with registrar");

     instance = [[GeofencingPlugin alloc] init:registrar];

     [registrar addApplicationDelegate:instance];

   }

 }

}

Additional state for the plugin is created when the GeofencingPlugin instance is build during plugin registration:

- (instancetype)init:(NSObject *)registrar {

 self = [super init];

 NSAssert(self, @"super init cannot be nil");

 _persistentState = [NSUserDefaults standardUserDefaults];

 _locationManager = [[CLLocationManager alloc] init];

 [_locationManager setDelegate:self];

 [_locationManager requestAlwaysAuthorization];

 _locationManager.accessBackgroundLocationUpdates = YES;

 _headlessRunner = [[FlutterEngine alloc]

                       initWithName:@"GeofencingIsolate"

                       project:nil

                       allowHeadlessExecution:YES];


 _registrar = registrar;

 _mainChannel = [FlutterMethodChannel
                 methodChannelWithName:@"plugins.flutter.io/geofencing_plugin"


                 binaryMessenger:[registrar messenger]];

 [registrar addMethodCallDelegate:self channel:_mainChannel];
 _callbackChannel =
   [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/geofencing_plugin_background"

     binaryMessenger:_headlessRunner];
 return self;

}

Starting the callback dispatcher:

- (void)startGeofencingService:(int64_t)handle {

 NSLog(@"Initializing GeofencingService");


 [self setCallbackDispatcherHandle:handle];

 FlutterCallbackInformation *info = [FlutterCallbackCache lookupCallbackInformation:handle];


 NSAssert(info != nil, @"failed to find callback");

 NSString *entrypoint = info.callbackName;

 NSString *uri = info.callbackLibraryPath;
 [_headlessRunner runWithEntrypointAndLibraryUri:entrypoint libraryUri:uri];
 NSAssert(registerPlugins != nil, @"failed to set registerPlugins");
 registerPlugins(_headlessRunner);
 [_registrar addMethodCallDelegate:self channel:_callbackChannel];
}

Handling method calls:

- (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result {
 NSArray *arguments = call.arguments;
 if ([@"GeofencingPlugin.initializeService" isEqualToString:call.method]) {
   NSAssert(arguments.count == 1,
   @"Invalid argument count for 'GeofencingPlugin.initializeService'");
   [self startGeofencingService:[arguments[0] longValue]];
   result(@(YES));
 } else if ([@"GeofencingService.initialized" isEqualToString:call.method]) {
   // Ignored on iOS.
   result(nil);
 } else if ([@"GeofencingPlugin.registerGeofence" isEqualToString:call.method]) {
   [self registerGeofence:arguments];
   result(@(YES));
 } else if ([@"GeofencingPlugin.removeGeofence" isEqualToString:call.method]) {

   result(@([self removeGeofence:arguments]));
 } else {
   result(FlutterMethodNotImplemented);
 }
}

Registering geofences:

- (void)registerGeofence:(NSArray *)arguments {
 NSLog(@"RegisterGeofence: %@", arguments);
 int64_t callbackHandle = [arguments[0] longLongValue];
 NSString *identifier = arguments[1];
 double latitude = [arguments[2] doubleValue];
 double longitude = [arguments[3] doubleValue];
 double radius = [arguments[4] doubleValue];
 CLCircularRegion *region =
   [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(latitude, longitude)
     radius:radius
     identifier:identifier];
 region.notifyOnEntry = YES;
 region.notifyOnExit = YES;
 [self setCallbackHandleForRegionId:callbackHandle regionId:identifier];
 [self->_locationManager startMonitoringForRegion:region];
}

For Handling geofence events use the below code:

- (void)sendLocationEvent:(CLRegion *)region eventType:(int)event {
 NSAssert([region isKindOfClass:[CLCircularRegion class]], @"region must be CLCircularRegion");
 CLLocationCoordinate2D center = region.center;
 int64_t handle = [self getCallbackHandleForRegionId:region.identifier];
 [_callbackChannel
   invokeMethod:@""
   arguments:@[
     @(handle),
     @[ region.identifier ],
     @[ @(center.latitude), @(center.longitude) ],
     @(event)
   ]
 ];
}
- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region {
 [self sendLocationEvent:region eventType:kEnterEvent];
}
- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region {
 [self sendLocationEvent:region eventType:kExitEvent];
}

For Geofence events in a suspended state below code:

- (BOOL)application:(UIApplication *)application
 didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

 // Check to see if we're being launched due to a location event.

 if (launchOptions[UIApplicationLaunchOptionsLocationKey] != nil) {

   // Restart the headless service.


   [self startGeofencingService:[self getCallbackDispatcherHandle]];
 }
 return YES;
}

To get Permissions: Android use the below code:





To get Permissions in iOS:

UIRequiredDeviceCapabilities

 

   location-services

   gps

   armv7

 

 UIBackgroundModes

 

   location

 

NSLocationAlwaysAndWhenInUseUsageDescription

 YOUR DESCRIPTION HERE

 NSLocationWhenInUseUsageDescription

 YOUR DESCRIPTION HERE

These descriptions are shown to the person who uses them when the app requests access to themarea.

#include "AppDelegate.h"
#include "GeneratedPluginRegistrant.h"

// Add the import for the GeofencingPlugin.

#import 

void registerPlugins(NSObject* registry) {

 [GeneratedPluginRegistrant registerWithRegistry:registry];

}

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application

   didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

 // Register the plugins with the AppDelegate


 registerPlugins(self);

 // Set registerPlugins as a callback within GeofencingPlugin. This access

 // for the Geofencing plugin to register the plugins with the background

 // FlutterEngine instance created to handle events. If this step is skipped,

 // other plugins will not work in the geofencing callbacks!

 [GeofencingPlugin setPluginRegistrantCallback:registerPlugins];

 // Override point for customization after application launch.

 return [super application:application didFinishLaunchingWithOptions:launchOptions];

}

@end

Bringing it all together:

Future initialize() async {

 // Perform other initialization

 // …

 // Initialize the geofencing plugin.

 await GeofencingManager.initialize();

}

Widget _proximityTriggerToggle() => Container(

   padding: const EdgeInsets.fromLTRB(26.0, 2.5, 26.0, 2.5),

   child: Row(

     mainAxisAlignment: MainAxisAlignment.spaceBetween,

     children: [

       const Text('Proximity Trigger',

           style: TextStyle(fontWeight: FontWeight.bold, fontSize: 16.0)),

       Switch(

         value: _proximityTriggerEnabled,

         onChanged: (bool state) async {

           setState(() {

             _proximityTriggerEnabled = state;

           });

           if (state) {

             await GeofencingManager.registerGeofence(

                 GeofenceTrigger.homeRegion,

                 GeofenceTrigger.homeGeofenceCallback);

           } else {

             await GeofencingManager.removeGeofence(

                 GeofenceTrigger.homeRegion);

           }

         },

       ),

     ],

   )

 );

abstract class GeofenceTrigger {

 static final _androidSettings = AndroidGeofencingSettings(

     initialTrigger: [GeofenceEvent.exit],

     notificationResponsiveness: 0,

     loiteringDelay: 0);

 static bool _isInitialized = false;

 static final homeRegion = GeofenceRegion(

     'home', HOME_LAT, HOME_LONG, 300.0, [GeofenceEvent.enter],

     androidSettings: _androidSettings);

 static Future homeGeofenceCallback(

     List id, Location location, GeofenceEvent event) async {

   // Check to see if this is the first time the callback is being called.

   if (!_isInitialized) {

     // Re-initialize state required to communicate with the garage door

     // server.

     await initialize();

     _isInitialized = true;

   }

   if (event == GeofenceEvent.enter) {

     await GarageDoorRemote.openDoor();

   }

 }

}

At last, you execute a dart in the background with flutter plugin and geofencing

If you have any questions about the above topic or have to get services and consultations to setup flutter and dart plugins. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your digital solution. E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
ounder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

enter image description here

We all understand that ASP.NET MVC is a great stage that allows us to build and maintain web applications in a much easier manner related to form-based web applications. There are a few things in MVC-based web applications that run a little more uncomfortably than standard web applications, one of them is routing.

Until now, there has been a routing table that you can set either in the Global. asax or in the RouteConfig.cs and all incoming calls would look it up to determine the rendering of a targeted view.

Here is the code that you might have seen previously to have note-variable routes in MVC 4 in the following example of the Route collection object.

routes.MapRoute( 
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Product",
action = "List", id = UrlParameter.Optional }
);

What is the necessity for this new routing methodology?

There was nothing really incorrect with the previous method of routing and in fact, you can however use it in MVC 5 or use this new routing method in connection with the old one.

Here are a few benefits of attribute-based routing,

  • Helps developers in the debugging / troubleshooting form by providing data about routes.
  • Decreases the chances for mistakes, if a route is changed incorrectly in RouteConfig.cs then it may affect the whole application's routing.
  • May decouple controller and business names from route entirely.
  • Simple to map two routes guiding to the same action.

Let's see specifically how we can configure it and see it working.

First, we will need to enable attribute-based routing on our MVC web application that can be made by only one line. All you want to do is put this line in the RegisterRoutes method of the application.

public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
tes.MapMvcAttributeRoutes(); //Enables Attribute Based Routing
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Product", action = "List", id = UrlParameter.Optional }
);
}

Now, here is how you can use attribute-based routing on a particular action method.

[Route("products/{id?}")]
public ActionResult Details(string id)
{
if (string.IsNullOrEmpty(id))
{
return View("List", GetProductList());
}
return View("Details", GetProductDetails());
}

As shown in the method above, the Route is determined on a Details action method that lets users enter the product specifications page either by of these paths,

/Product/Details/Id or /products/id

You might have recognized the problem mark in the route above, all it means is that the id is an arbitrary parameter of the route and hence the business process logic checks if the id is null. It will show you the result listing page.

Route Prefixes

Route Prefixes are blank but the prefix for any route that we need to apply, all we need to do is to determine the route prefix on a controller so that all the action plans inside it can follow the prefix.

[RoutePrefix("products")]
public class ProductController : Controller  
{
//This will be translated to /products
[Route]
public ActionResult List()
{
return View();
}
//This will be translated to /products/2
[Route("{id?}")]
public ActionResult Details(string id)
{
if (string.IsNullOrEmpty(id))
{
return View("List");
}
return View("Details");
}
}

Route Constraints

Route constraints are zero but a set of practices that you can set on your routing model/parameters that users want to follow when entering the established routes.

The way to determine a constraint is by using the ":" character, let's have a look at the example below.

//route gets called as /products/productname
[Route("products/{id:alpha}")]
public ActionResult GetProduct(string name) 
{
return View();
}
//route gets called as /products/2  
[Route("products/{id:int}")]
 public ActionResult GetProduct(int id)
{
return View();
}

Now your strength has recognized in the example above that though the system name is equal the route's parameter has some restrictions on it. In other words, the first order will be called if the route is located with a string as a parameter and the second method will be called if the route is obtained with an integer in the route parameter.

You can also define your system route limitations using an IRouteConstraint interface.

Route Areas

A Route area is zero but the way to define the area in a route, essentially just to let the route know that the controller goes to some area.

[RouteArea("business")]
[RoutePrefix("products")]
public class ProductController : Controller
{
//This will be translated to /business/products/list 
[Route]
public ActionResult List()
{
return View();
}
}

If you have any questions about the above topic or have to get services and consultations and get the best ASP.Net MVC Application Development Services. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your digital solution. E-mail id: [email protected]

enter image description here

Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/

enter image description here

In this blog, we will integrate the Firebase Authentication for Google Sign-In in our Android application using Google and Firebase APIs.

What is firebase authentication?

Firebase Authentication ensures backend services for we can simply use the SDKs and in-built UI libraries to authenticate the person that is used in the android app. Most of the apps need the identity of the person that is using, and after knowing their activity status, the app saves the user's data safely in the cloud. It targets building a safe authentication system.

Using Firebase Authentication, we will authenticate the log-in of Google, Facebook, GitHub and more.

What are the steps to create and configure the android app on the google firebase account?

  • The first step is to create a firebase developer account and after installing it ‘Go to console’.
  • Select the option 'Add project'.
  • Complete the project name and select the analytics area, cloud Firestore location, accept the controller terms and select 'Create project'.
  • When your new project is completely ready select 'Continue'.
  • The next step is to click on the android platform SDK.
  • The next step is to Register your app to Firebase by providing the required app information and clicking on 'Register app'.
  • The next step is to download the 'google-services.json' file to integrate it into the Android app and select 'Next.
  • The next step is to add the Firebase SDK dependencies in the .gradle folders of your app and select 'Sync now' in the IDE and select the option 'Next'.

BUILD GRADLE (PROJECT):

dependencies { 
classpath 'com.android.tools.build:gradle:3.0.1'
classpath 'com.google.gms:google-services:4.0.1'
// in the individual module build. Gradle files  
}

BUILD GRADLE(MODULE):

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])  
 implementation 'com.android.support:appcompat-v7:27.1.1'
  implementation 'com.android.support.constraint:constraint-layout:1.1.3'
 testImplementation 'junit:junit:4.12'
 androidTestImplementation 'com.android.support.test:runner:1.0.2' 
androidTestImplementation 
'com.android.support.test.espresso:espresso-core:3.0.2' 
implementation 'com.google.firebase:firebase-auth:16.0.3' 
 implementation 'com.google.firebase:firebase-core:16.0.3'
 implementation 'com.google.android.gms:play-services-auth:16.0.0'  
  implementation 'com.github.bumptech.glide:glide:3.7.0' 
}
apply : 'com.google.gms.google-services' 

What should I do in androidmanifest.xml?

First, add internet permission:
<uses-permission android:name="android.permission.INTERNET" />
  • Execute your app to verify the installation configuration, if everything is alright it shows a success message and then select the 'Continue to console'.
  • Next step you need to know that on the console page click on Authentication -gt; Sign-in method -gt;Google -gt; Enable and at last select on 'Save'.

Give an example of android firebase authentication with a google sign-in example?

Add the below code in an activity_main.xml file. In this activity, we use the custom Google Sign-in button:

<?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="example.javatpoint.com.firebasegooglelogin.MainActivity">
   <TextView 
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp" 
android:textSize="20dp"
 android:text="This is main activity, sign in to move next activity." /> 

   <com.google.android.gms.common.SignInButton
android:layout_width="match_parent"
 android:layout_height="wrap_content"
android:id="@+id/sign_in_button"
 android:layout_marginLeft="20dp" 
android:layout_marginRight="20dp" 
 android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp">
  </com.google.android.gms.common.SignInButton>
</RelativeLayout> 

The next step is to add your web client id in the string.xml file.

<resources>
<string name="app_name">Firebase Google Login</string>
<string name="web_client_id">xxxxxxxx..place your web client id </string>
</resources> 

Next, add the below code in MainActivity.java class

package example.javatpoint.com.firebasegooglelogin;
import android.content.Intent; 
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle; 
import android.util.Log;
import android.view.View; 
import android.widget.Toast;  

import com.google.android.gms.auth.api.Auth; 
import com.google.android.gms.auth.api.signin.GoogleSignInAccount; 
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.common.ConnectionResult;  
import com.google.android.gms.common.SignInButton; 
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.tasks.OnCompleteListener; 
import com.google.android.gms.tasks.Task; 
import com.google.firebase.auth.AuthCredential;
import com.google.firebase.auth.AuthResult; 
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;  
import com.google.firebase.auth.GoogleAuthProvider; 

OnConnectionFailedListener {  

   private static final String TAG = "MainActivity";  
private SignInButton signInButton;
private GoogleApiClient googleApiClient; 
private static final int RC_SIGN_IN = 1;
String name, email; 
  String idToken; 
private FirebaseAuth firebaseAuth;
 private FirebaseAuth.AuthStateListener authStateListener; 

@Override
protected void onCreate(Bundle savedInstanceState) {  
super.onCreate(savedInstanceState); 
setContentView(R.layout.activity_main);  
firebaseAuth = com.google.firebase.auth.FirebaseAuth.getInstance(); 
 authStateListener = new FirebaseAuth.AuthStateListener(){  
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
  // Get signedIn user 
FirebaseUser user = firebaseAuth.getCurrentUser(); 
//if user is signed in, we call a helper method to save the user details to Firebase 
if (user != null) { 
// User is signed in 
 Log.d(TAG, "onAuthStateChanged:signed_in:" + user.getUid());  
 } else { 
// User is signed out
 Log.d(TAG, "onAuthStateChanged:signed_out");  
}
  }  
 };

GoogleSignInOptions gso =  new
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
.requestIdToken(getString(R.string.web_client_id))//you can also use R.string.default_web_client_id
 .requestEmail()
.build(); 
 googleApiClient=new GoogleApiClient.Builder(this)
 .enableAutoManage(this,this)
.addApi(Auth.GOOGLE_SIGN_IN_API,gso)
 .build(); 

signInButton = findViewById(R.id.sign_in_button);
signInButton.setOnClickListener(new View.OnClickListener() {  
@Override 
public void onClick(View view) {  
 Intent intent = Auth.GoogleSignInApi.getSignInIntent(googleApiClient); 
startActivityForResult(intent,RC_SIGN_IN); 
 }  
 });  
  } 

@Override
public void onConnectionFailed(@NonNull ConnectionResult
connectionResult) { 
  }  
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
 super.onActivityResult(requestCode, resultCode, data); 
 if(requestCode==RC_SIGN_IN){ 
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
handleSignInResult(result);  
 } 
 }

private void handleSignInResult(GoogleSignInResult result){  
 if(result.isSuccess()){
GoogleSignInAccount account = result.getSignInAccount();
  idToken = account.getIdToken();
 name = account.getDisplayName(); 
 email = account.getEmail(); 
AuthCredential credential = GoogleAuthProvider.getCredential(idToken, null); 
firebaseAuthWithGoogle(credential); 
 }else{  

Log.e(TAG, "Login Unsuccessful. "+result); 
Toast.makeText(this, "Login Unsuccessful", Toast.LENGTH_SHORT).show();
 }
 } 
 private void firebaseAuthWithGoogle(AuthCredential credential){ 
firebaseAuth.signInWithCredential(credential)
 .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
 @Override
 public void onComplete(@NonNull Task<AuthResult> task) {

Log.d(TAG, "signInWithCredential:onComplete:" + task.isSuccessful());

   if(task.isSuccessful()){
Toast.makeText(MainActivity.this, "Login successful", Toast.LENGTH_SHORT).show(); 
gotoProfile();
  }else{  
   Log.w(TAG, "signInWithCredential" + task.getException().getMessage()); 
 task.getException().printStackTrace();
  Toast.makeText(MainActivity.this, "Authentication failed.",  
                                Toast.LENGTH_SHORT).show();
  }  
 }
 });
}
  private void gotoProfile(){ 
 Intent intent = new Intent(MainActivity.this, ProfileActivity.class);
 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
 startActivity(intent);  
 finish();
 } 
 @Override
 protected void onStart() {  
super.onStart();
  if (authStateListener != null){  
 FirebaseAuth.getInstance().signOut();
 }
  firebaseAuth.addAuthStateListener(authStateListener); 
 } 
@Override 
  protected void onStop() {
super.onStop(); 
 if (authStateListener != null){ 
firebaseAuth.removeAuthStateListener(authStateListener);
 }
 }
 }

The next step is to add the below code in the profile_activity.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"  
tools:context="example.javatpoint.com.firebasegooglelogin.ProfileActivity">
    <LinearLayout
 android:layout_width="match_parent" 
android:layout_height="match_parent"
 android:gravity="center"
 android:orientation="vertical">
<ImageView
android:layout_width="80dp"
android:layout_height="80dp"
android:id="@+id/profileImage" 
   /> 
  <TextView  
android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:id="@+id/name" 
android:text="name" 
 android:textSize="20dp"
android:layout_marginTop="20dp"/>
   <TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content" 
android:id="@+id/email"
android:textSize="20dp"
android:text="email"
 android:layout_marginTop="20dp"/>  
  <TextView  

android:layout_width="wrap_content"

android:layout_height="wrap_content"
 android:id="@+id/userId" 
android:textSize="20dp"
 android:text="id" 
android:layout_marginTop="20dp"/>
<Button
android:layout_width="wrap_content" 
android:layout_height="wrap_content"
android:id="@+id/logoutBtn"
 android:text="Logout"
android:layout_marginTop="30dp"/> 
 </LinearLayout> 
</RelativeLayout>

Next, we have to add profileActivity.java

package example.javatpoint.com.firebasegooglelogin;
import android.content.Intent;
import android.support.annotation.NonNull; 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;  
import android.view.View;  
import android.widget.Button;
import android.widget.ImageView; 
import android.widget.TextView; 
import android.widget.Toast;

import com.bumptech.glide.Glide;
import com.google.android.gms.auth.api.Auth; 
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult; 
import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.OptionalPendingResult;  
import com.google.android.gms.common.api.ResultCallback;  
import com.google.android.gms.common.api.Status;
import com.google.firebase.auth.FirebaseAuth;  

public class ProfileActivity extends AppCompatActivity implements
GoogleApiClient.OnConnectionFailedListener { 
Button logoutBtn;
TextView userName,userEmail,userId;
 ImageView profileImage; 
private GoogleApiClient googleApiClient;
private GoogleSignInOptions gso;  
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile); 
  logoutBtn = findViewById(R.id.logoutBtn); 
userName = findViewById(R.id.name);
userEmail = findViewById(R.id.email);
 userId = findViewById(R.id.userId); 
profileImage = findViewById(R.id.profileImage); 
gso =  new 
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN) 
.requestEmail() 
 .build();  
  googleApiClient=new GoogleApiClient.Builder(this) 
 .enableAutoManage(this,this)
 .addApi(Auth.GOOGLE_SIGN_IN_API,gso)
 .build();  
    logoutBtn.setOnClickListener(new View.OnClickListener() {  
  @Override  
 public void onClick(View view) { 
 FirebaseAuth.getInstance().signOut();
Auth.GoogleSignInApi.signOut(googleApiClient).setResultCallback(
 new ResultCallback<Status>() { 
 @Override
 public void onResult(Status status) { 
 if (status.isSuccess()){ 
gotoMainActivity();
 }else{ 
Toast.makeText(getApplicationContext(),"Session not close",Toast.LENGTH_LONG).show(); 
}
} 
 });
 }
  });  
 }
 @Override 
 protected void onStart() {
 super.onStart();
OptionalPendingResult<GoogleSignInResult> opr= Auth.GoogleSignInApi.silentSignIn(googleApiClient);  
  if(opr.isDone()){  
GoogleSignInResult result=opr.get();  
handleSignInResult(result); 
  }else{
opr.setResultCallback(new ResultCallback<GoogleSignInResult>() { 
@Override
 public void onResult(@NonNull GoogleSignInResult googleSignInResult)
{ 
handleSignInResult(googleSignInResult);
  } 
});  
  }
  }
  private void handleSignInResult(GoogleSignInResult result){  
  if(result.isSuccess()){
GoogleSignInAccount account=result.getSignInAccount();  
userName.setText(account.getDisplayName());
userEmail.setText(account.getEmail());  
 userId.setText(account.getId());
try{
Glide.with(this).load(account.getPhotoUrl()).into(profileImage);  
  }catch (NullPointerException e){ 
Toast.makeText(getApplicationContext(),"image not found",Toast.LENGTH_LONG).show(); 
 }
 }else{  
gotoMainActivity(); 
}  
}  
private void gotoMainActivity(){ 
 Intent intent=new Intent(this,MainActivity.class); 
startActivity(intent); 
} 
@Override 
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {  
   } 
   } 

If you have any questions about the above topic or have to get services and consultations and get the best android application development services. Feel free to contact us. AIRO GLOBAL SOFTWARE will be your strong digital partner. E-mail id: [email protected]

enter image description here Author - Johnson Augustine
Chief Technical Director and Programmer
Founder: Airo Global Software Inc
LinkedIn Profile: www.linkedin.com/in/johnsontaugustine/