com.shollmann.igcparser.ui.activity.IGCFilesActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.shollmann.igcparser.ui.activity.IGCFilesActivity.java

Source

/*
 * MIT License
 *
 * Copyright (c) 2017 Santiago Hollmann
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.shollmann.igcparser.ui.activity;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.PopupMenu;
import android.support.v7.widget.RecyclerView;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.crashlytics.android.Crashlytics;
import com.shollmann.android.igcparser.Parser;
import com.shollmann.android.igcparser.model.IGCFile;
import com.shollmann.android.igcparser.util.Logger;
import com.shollmann.android.igcparser.util.Utilities;
import com.shollmann.igcparser.R;
import com.shollmann.igcparser.events.FileClickEvent;
import com.shollmann.igcparser.events.RateUsClickedEvent;
import com.shollmann.igcparser.tracking.TrackerHelper;
import com.shollmann.igcparser.ui.adapter.FilesAdapter;
import com.shollmann.igcparser.ui.view.RateUsView;
import com.shollmann.igcparser.util.Comparators;
import com.shollmann.igcparser.util.Constants;
import com.shollmann.igcparser.util.PreferencesHelper;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

public class IGCFilesActivity extends AppCompatActivity
        implements MenuItem.OnMenuItemClickListener, PopupMenu.OnMenuItemClickListener {

    private static final int EXTERNAL_STORAGE_PERMISSION_REQUEST = 1001;
    private RateUsView viewRateUs;
    private LinearLayout layoutLoading;
    private LinearLayout layoutEmpty;
    private RecyclerView recyclerView;
    private TextView txtLoading;
    private ProgressBar progress;
    private FilesAdapter adapter;
    private List<IGCFile> listFiles = new ArrayList<>();
    private File lastSearchedPath;
    private boolean isSearching = true;
    private PreferencesHelper preferencesHelper;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_igc_files);
        findViews();
        preferencesHelper = new PreferencesHelper(getApplicationContext());
        setupFilesList();
        checkForStoragePermission();
    }

    private void setupRateUsView() {
        if (!preferencesHelper.isRated() && preferencesHelper.getViewedFlightCountForRate() >= preferencesHelper
                .getMinFlightsViewedToRate()) {
            viewRateUs.setVisibility(View.VISIBLE);
        } else {
            viewRateUs.setVisibility(View.GONE);
        }
    }

    private void setupFilesList() {
        recyclerView.setHasFixedSize(true);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        adapter = new FilesAdapter(listFiles);
        recyclerView.setAdapter(adapter);
    }

    private void findViews() {
        recyclerView = (RecyclerView) findViewById(R.id.files_recyclerview);
        layoutLoading = (LinearLayout) findViewById(R.id.files_layout_loading);
        layoutEmpty = (LinearLayout) findViewById(R.id.files_layout_empty_state);
        txtLoading = (TextView) findViewById(R.id.files_loading_text);
        progress = (ProgressBar) findViewById(R.id.files_loading_progress);
        viewRateUs = (RateUsView) findViewById(R.id.view_rate_us);
    }

    private List<IGCFile> getListIGCFiles(File parentDir) {
        List<IGCFile> inFiles = new ArrayList<>();
        Queue<File> files = new LinkedList<>();
        try {
            files.addAll(Arrays.asList(parentDir.listFiles()));
            while (!files.isEmpty()) {
                File file = files.remove();
                if (!Utilities.isUnlikelyIGCFolder(file)) {
                    if (file != null && file.isDirectory()) {
                        files.addAll(Arrays.asList(file.listFiles()));
                    } else if (file != null && (file.getName().toLowerCase().endsWith(".igc"))) {
                        inFiles.add(Parser.quickParse(Uri.parse(file.getAbsolutePath())));
                    }
                }
            }
            Collections.sort(inFiles, Comparators.compareByDate);
        } catch (Throwable t) {
            final String message = "Couldn't open files";
            Crashlytics.log(message);
            Crashlytics.logException(t);
            Logger.logError(message);
        }

        return inFiles;
    }

    @Override
    public void onStart() {
        super.onStart();
        EventBus.getDefault().register(this);
    }

    @Override
    public void onStop() {
        super.onStop();
        EventBus.getDefault().unregister(this);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(FileClickEvent event) {
        TrackerHelper.trackTapFile();
        Intent intent = new Intent(this, FlightPreviewActivity.class);
        intent.putExtra(Constants.FILE_TO_LOAD_PATH, event.getFile().getAbsoluteFile().toString());
        startActivity(intent);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMessageEvent(RateUsClickedEvent event) {
        viewRateUs.setVisibility(View.GONE);
    }

    @Override
    public boolean onCreateOptionsMenu(final Menu menu) {
        getMenuInflater().inflate(R.menu.files_menu, menu);
        MenuItem menuSearchEntireSdCard = menu.findItem(R.id.menu_search_sdcard);
        MenuItem menuRefresh = menu.findItem(R.id.menu_refresh);
        MenuItem menuAbout = menu.findItem(R.id.menu_about);
        MenuItem menuShare = menu.findItem(R.id.menu_share);
        MenuItem menuSettings = menu.findItem(R.id.menu_settings);

        ImageView viewAttach = (ImageView) menu.findItem(R.id.menu_sort).getActionView();
        viewAttach.setBackgroundResource(R.drawable.drawable_sort_icon);
        viewAttach.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showSortDialog(v);
            }

        });

        menuSearchEntireSdCard.setOnMenuItemClickListener(this);
        menuRefresh.setOnMenuItemClickListener(this);
        menuAbout.setOnMenuItemClickListener(this);
        menuShare.setOnMenuItemClickListener(this);
        menuSettings.setOnMenuItemClickListener(this);
        return super.onCreateOptionsMenu(menu);
    }

    private void showSortDialog(View v) {
        TrackerHelper.trackSortDialog();
        PopupMenu popup = new PopupMenu(this, v);
        MenuInflater inflater = popup.getMenuInflater();
        inflater.inflate(R.menu.sort_menu, popup.getMenu());
        popup.setOnMenuItemClickListener(this);
        popup.show();
    }

    @Override
    public boolean onMenuItemClick(MenuItem menuItem) {
        if (isSearching) {
            Toast.makeText(this, R.string.search_flights_wait, Toast.LENGTH_LONG).show();
            return false;
        }
        switch (menuItem.getItemId()) {
        case R.id.menu_refresh:
            TrackerHelper.trackRefresh();
            searchForFiles(listFiles.isEmpty() ? Utilities.getXCSoarDataFolder() : lastSearchedPath);
            break;
        case R.id.menu_search_sdcard:
            TrackerHelper.trackSearchSdCard();
            searchForFiles(Utilities.getSdCardFolder());
            break;
        case R.id.menu_share:
            TrackerHelper.trackShareApp();
            shareApp();
            break;
        case R.id.menu_sort_glider:
            TrackerHelper.trackSortByGlider();
            sortBy(Comparators.compareByGlider);
            break;
        case R.id.menu_sort_pilot:
            TrackerHelper.trackSortByPilot();
            sortBy(Comparators.compareByPilot);
            break;
        case R.id.menu_sort_date:
            TrackerHelper.trackSortByDate();
            sortBy(Comparators.compareByDate);
            break;
        case R.id.menu_about:
            TrackerHelper.trackAbout();
            Intent intent = new Intent(this, AboutActivity.class);
            startActivity(intent);
            break;
        case R.id.menu_settings:
            TrackerHelper.trackSettings();
            intent = new Intent(this, SettingsActivity.class);
            startActivity(intent);
            break;
        }
        return false;
    }

    private void searchForFiles(File path) {
        listFiles.clear();
        adapter.notifyDataSetChanged();
        txtLoading.setText(getString(R.string.searching_igc_files));
        showProgressViews();
        new FindIGCFilesAsyncTask(this).execute(path);
    }

    private void showProgressViews() {
        layoutEmpty.setVisibility(View.GONE);
        layoutLoading.setVisibility(View.VISIBLE);
        progress.setVisibility(View.VISIBLE);
    }

    private void sortBy(Comparator<IGCFile> comparator) {
        if (!isSearching) {
            Collections.sort(listFiles, comparator);
            adapter.notifyDataSetChanged();
        }
    }

    private void checkForStoragePermission() {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            txtLoading.setClickable(false);
            ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.READ_EXTERNAL_STORAGE },
                    EXTERNAL_STORAGE_PERMISSION_REQUEST);

        } else {
            new FindIGCFilesAsyncTask(this).execute(Utilities.getSdCardFolder());
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[],
            @NonNull int[] grantResults) {
        switch (requestCode) {
        case EXTERNAL_STORAGE_PERMISSION_REQUEST: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                new FindIGCFilesAsyncTask(this).execute(Utilities.getSdCardFolder());
            } else {
                layoutEmpty.setVisibility(View.GONE);
                progress.setVisibility(View.GONE);
                txtLoading.setClickable(true);
                txtLoading.setText(R.string.need_storage_access);
                txtLoading.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        checkForStoragePermission();
                    }
                });
            }
        }
        }
    }

    private void shareApp() {
        try {
            Intent sendIntent = new Intent();
            sendIntent.setAction(Intent.ACTION_SEND);
            sendIntent.putExtra(Intent.EXTRA_TEXT, getResources().getString(R.string.share_app_link));
            sendIntent.setType("text/plain");
            startActivity(sendIntent);
        } catch (Throwable t) {
            Toast.makeText(this, R.string.sorry_error_happen, Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        setupRateUsView();
    }

    private class FindIGCFilesAsyncTask extends AsyncTask<File, Void, Boolean> {
        WeakReference<IGCFilesActivity> activity;

        FindIGCFilesAsyncTask(IGCFilesActivity activity) {
            this.activity = new WeakReference<>(activity);
        }

        protected Boolean doInBackground(File... file) {
            isSearching = true;
            lastSearchedPath = file[0];
            listFiles = getListIGCFiles(file[0]);
            return file[0].getAbsolutePath().equals(Utilities.getSdCardFolder().getAbsolutePath());
        }

        protected void onProgressUpdate(Void... something) {
        }

        protected void onPostExecute(Boolean isEntireFolder) {
            if (activity.get() != null) {
                handleFinishFilesLoad(isEntireFolder);
            }
        }

        private void handleFinishFilesLoad(Boolean isEntireFolder) {
            if (!listFiles.isEmpty()) {
                layoutLoading.setVisibility(RecyclerView.GONE);
                adapter.setDataset(listFiles);
                adapter.notifyDataSetChanged();
            } else {
                if (!isEntireFolder) {
                    final String message = "No IGC files found on XCSoar folder. Searching on other folders";
                    Logger.log(message);
                    Crashlytics.log(message);
                    txtLoading.setText(getString(R.string.searching_igc_files));
                    new FindIGCFilesAsyncTask(activity.get()).execute(Utilities.getSdCardFolder());
                } else {
                    viewRateUs.setVisibility(View.GONE);
                    layoutLoading.setVisibility(View.GONE);
                    layoutEmpty.setVisibility(View.VISIBLE);
                    TrackerHelper.trackNoFilesFound();
                }
            }
            isSearching = false;
        }
    }
}