Fixed Critical bug on Travel Mate Android app

in #utopian-io6 years ago (edited)

A must-have app for those interested in travel. The app provides users with various features from choosing the correct destination to making all the bookings and to easily organising the trip.
While travelling from one place to another, there are a lot of factors to be considered to make the trip a memorable one. This platform helps the traveller with anything and everything that he or she might need, from the moment he or she plans the journey till the time he or she is back home happy and content.

Repository

https://github.com/project-travel-mate/Travel-Mate

Bug Fixes

Description
Every time app opens favourite cities page(Destinations) will be shown, user visit Destinations page, an API call is made. This experience was really bad for users as well as app performance is concern.

Steps to reproduce

  • Go to the navigation drawer. Click Destinations
  • Go to some other fragment. Come to Destinations again.
  • Again the API call is made.

Expected behaviour
The information should be saved locally.

What was the solution?

  • Created a local database (using Room persistence library)

There are three major components in Room:

  1. Database is a holder class that uses annotation to define the list of entities and database version. This class content defines the list of DAOs.

/**
 * Created by Santosh on 05/09/18.
 */
@Database(entities = {City.class}, version = 1, exportSchema = false)
@TypeConverters({Converters.class})
public abstract class AppDataBase extends RoomDatabase {
    private static AppDataBase instance;
    public abstract CityDao cityDao();
    public static AppDataBase getAppDatabase(Context context) {
        if (instance == null) {
            instance = Room.databaseBuilder(context.getApplicationContext(),
                    AppDataBase.class,
                    "city-travel-mate-db")
                    .allowMainThreadQueries()
                    .build();
        }
        return instance;
    }
 }
  1. Entity represents data for a single table row, constructed using an annotated java data object. Each entity is persisted into its own table.

/**
 * Model class for city object
 */
@Entity (tableName = "city")
public class City implements Serializable {
    @Ignore
    public final List<String> mInterests = new ArrayList<>();
    @PrimaryKey
    @NonNull
    public String mId;
    @ColumnInfo (name = "city_latitude")
    public String mLatitude;
    @ColumnInfo (name = "city_longitude")
    public String mLongitude;
    @ColumnInfo (name = "city_funfact")
    public int mFunFactsCount;
    @ColumnInfo (name = "city_background")
    public int mBackgroundColor;
    @ColumnInfo(name = "city_avatar")
    public String mAvatar;
    @ColumnInfo (name = "city_nickname")
    public String mNickname;
    @ColumnInfo (name = "city_description")
    public String mDescription;
    public City() {
    }
 }
  1. DAO (Data Access Object) defines the method that access the database, using annotation to bind SQL to each method.

/**
 * Created by Santosh on 05/09/18.
 */
@Dao
public interface CityDao {
    @Insert
    void insert(City... city);
    @Update
    void update(City... city);
    @Delete
    void delete(City... city);
    @Query("Select * FROM city")
    City[] loadAll();
    @Query("DELETE FROM city")
    void deleteAll();
}

Reference:
https://medium.freecodecamp.org/room-sqlite-beginner-tutorial-2e725e47bfab
https://medium.com/@ajaysaini.official/building-database-with-room-persistence-library-ecf7d0b8f3e9

If the database is empty, fetch response & fill the db. (Set an expiration time. 24 hours for the database, after which it is deleted & has been filled again).If the database has information, use that to fill the layout on Destinations page.


// Check local city data
mDatabase = AppDataBase.getAppDatabase(mActivity);
List<City> mCities = Arrays.asList(mDatabase.cityDao().loadAll());
if (checkCachedCities(mCities)) {
    fetchCitiesList();
} else {
    FlipSettings settings = new FlipSettings.Builder().defaultPage().build();
    lv.setAdapter(new CityAdapter(mActivity, mCities, settings));
    lv.setOnItemClickListener((parent, mView, position, id1) -> {
        City city = (City) lv.getAdapter().getItem(position);
        Intent intent = FinalCityInfoActivity.getStartIntent(mActivity, city);
        startActivity(intent);
    });
}

/**
 * Check cached cities with expiration time 24 hours
 * @param mCities
 **/
private boolean checkCachedCities(List<City> mCities) {
    if (mCities.size() == 0 || is24Hours()) {
        return true;
    } else {
        return false;
    }
}

/**
 * Check time more than 24 hours
 **/
private boolean is24Hours() {
    long mMillisPerDay = 24 * 60 * 60 * 1000L;
    boolean mMoreThanDay = false;
    Date mCurrentDate = new Date();
    try {
        String mDateString = mSharedPreferences.getString(LAST_CACHE_TIME, "");
        if (!mDateString.isEmpty()) {
            Date mExpiry = mFormat.parse(mDateString);
            mMoreThanDay = Math.abs(mCurrentDate.getTime() - mExpiry.getTime()) > mMillisPerDay;
            //Delete record cached before 24 hours
            if (mMoreThanDay) {
                mDatabase.cityDao().deleteAll();
            }
        }
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return mMoreThanDay;
}

If the database is empty, fetch response & fill the db. (Set an expiration time. 24 hours for the database, after which it is deleted & has been filled again).If the database has information, used that to fill the layout on Destinations page.

GitHub Account

Merged Code

https://github.com/santoshhiremani

Sort:  

Thank you for your contribution. When you are taking references from other website either write it after > in a new paragraph or write it in your words. The post quality can be improved, by explaining only the required and main code and not the whole code along with formatting it well.

Your contribution has been evaluated according to Utopian policies and guidelines, as well as a predefined set of questions pertaining to the category.

To view those questions and the relevant answers related to your post, click here.


Need help? Write a ticket on https://support.utopian.io/.
Chat with us on Discord.
[utopian-moderator]

Thank you for your review, @codingdefined!

So far this week you've reviewed 4 contributions. Keep up the good work!

Hi @hiremani!

Your post was upvoted by @steem-ua, new Steem dApp, using UserAuthority for algorithmic post curation!
Your post is eligible for our upvote, thanks to our collaboration with @utopian-io!
Feel free to join our @steem-ua Discord server

Congratulations @hiremani! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

You got your First payout

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @steemitboard:

SteemitBoard - Witness Update
SteemFest³ - SteemitBoard support the Travel Reimbursement Fund.

Support SteemitBoard's project! Vote for its witness and get one more award!

Hey, @hiremani!

Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!

Get higher incentives and support Utopian.io!
Simply set @utopian.pay as a 5% (or higher) payout beneficiary on your contribution post (via SteemPlus or Steeditor).

Want to chat? Join us on Discord https://discord.gg/h52nFrV.

Vote for Utopian Witness!

Congratulations @hiremani! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :

Award for the total payout received

Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word STOP

Do not miss the last post from @steemitboard:

SteemitBoard - Witness Update

Support SteemitBoard's project! Vote for its witness and get one more award!

Coin Marketplace

STEEM 0.18
TRX 0.16
JST 0.029
BTC 62797.54
ETH 2442.85
USDT 1.00
SBD 2.68