com.joeyturczak.jtscanner.ui.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.joeyturczak.jtscanner.ui.MainActivity.java

Source

package com.joeyturczak.jtscanner.ui;

import android.Manifest;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.design.widget.NavigationView;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import android.widget.Toast;

import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import com.joeyturczak.jtscanner.R;
import com.joeyturczak.jtscanner.models.Asset;
import com.joeyturczak.jtscanner.models.BaseAsset;
import com.joeyturczak.jtscanner.models.TodayData;
import com.joeyturczak.jtscanner.utils.FirebaseUtility;
import com.joeyturczak.jtscanner.utils.Utility;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

/**
 * Copyright (C) 2015 Joey Turczak
 *
 *       Licensed under the Apache License, Version 2.0 (the "License");
 *       you may not use this file except in compliance with the License.
 *       You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *       Unless required by applicable law or agreed to in writing, software
 *       distributed under the License is distributed on an "AS IS" BASIS,
 *       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *       See the License for the specific language governing permissions and
 *       limitations under the License.
 */
public class MainActivity extends AppCompatActivity
        implements ActivityCompat.OnRequestPermissionsResultCallback, ScannerFragment.OnScanCompletedListener,
        ScannerFragment.OnScanEditedListener, ScannerFragment.OnScanDeletedListener {

    private static final int PERMISSION_STORAGE = 1;
    private static final int PERMISSION_CAMERA = 2;

    private static final String SCANNER_FRAGMENT_TAG = "SCANNER_FRAGMENT_TAG";
    private static final String SCAN_LIST_TAG = "SCAN_LIST_TAG";
    private static final String SETTINGS_FRAGMENT_TAG = "SETTINGS_FRAGMENT_TAG";
    private static final String ABOUT_FRAGMENT_TAG = "ABOUT_FRAGMENT_TAG";
    private static final String FILE_LIST_FRAGMENT_TAG = "FILE_LIST_FRAGMENT_TAG";

    private DrawerLayout mDrawerLayout;
    private Toolbar mToolbar;
    private ActionBarDrawerToggle mDrawerToggle;
    private NavigationView mNavigationView;

    private Toast mToast;

    private TodayData mTodayData;

    private DatabaseReference mTodayRef;

    private ChildEventListener mScanCountListener = new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            mTodayData.setCount(dataSnapshot.getValue(Long.class));
            sendDataBroadcast();
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            mTodayData.setCount(dataSnapshot.getValue(Long.class));
            sendDataBroadcast();
        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            mTodayData.setCount(0);
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {
            mTodayData.setCount(0);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    };

    ValueEventListener scanCountValueListener = new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            long scanCount = 0L;

            if (!dataSnapshot.exists()) {
                dataSnapshot.getRef().setValue(scanCount);
            } else {
                scanCount = dataSnapshot.getValue(Long.class);
            }

            mTodayData.setCount(scanCount);
            sendDataBroadcast();
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    };

    private ChildEventListener mScanListener = new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            mTodayData.addAsset(dataSnapshot.getValue(BaseAsset.class));
            mTodayData.addKey(dataSnapshot.getKey());
            sendDataBroadcast();
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            for (int i = 0; i < mTodayData.getKeys().size(); i++) {
                if (mTodayData.getKeys().get(i).equals(dataSnapshot.getKey())) {
                    mTodayData.getAssets().remove(i);
                    mTodayData.getAssets().add(i, new Asset(dataSnapshot.getValue(BaseAsset.class)));
                }
            }
        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {
            mTodayData.removeAsset(new Asset(dataSnapshot.getValue(BaseAsset.class)));
            mTodayData.removeKey(dataSnapshot.getKey());
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        mTodayData = new TodayData();
        setupDatabase();
    }

    @Override
    protected void onStop() {
        super.onStop();

        if (mScanCountListener != null) {
            mTodayRef.child("count").removeEventListener(mScanCountListener);
            mTodayRef.child("scans").removeEventListener(mScanListener);
            mTodayRef.child("count").removeEventListener(scanCountValueListener);
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        if (isStoragePermissionGranted()) {
            makeFileDirs();
        }

        checkCameraPermission();

        mTodayData = new TodayData();

        // Set a Toolbar to replace the ActionBar.
        mToolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(mToolbar);

        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        mDrawerToggle = setupDrawerToggle();

        // Tie DrawerLayout events to the ActionBarToggle
        mDrawerLayout.addDrawerListener(mDrawerToggle);

        // Find our drawer view
        mNavigationView = (NavigationView) findViewById(R.id.nvView);
        // Setup drawer view
        setupDrawerContent(mNavigationView);

        startScannerFragment();
    }

    @Override
    public void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);

        // Sync the toggle state after onRestoreInstanceState has occurred.
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        // Pass any configuration change to the drawer toggles
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            startSettingsFragment();
            return true;
        } else if (id == R.id.action_save_spreadsheet) {
            if (mToast != null) {
                mToast.cancel();
            }
            if (mTodayData.getAssets().isEmpty()) {
                mToast = Toast.makeText(this, R.string.toast_menu_no_data, Toast.LENGTH_SHORT);
            } else {
                mToast = Toast.makeText(this, R.string.toast_menu_saved, Toast.LENGTH_SHORT);
                if (isStoragePermissionGranted()) {
                    Utility.createSpreadsheet(this, mTodayData);
                } else {
                    mToast = Toast.makeText(this, "Grant storage permission and try again", Toast.LENGTH_SHORT);
                }
            }
            mToast.show();
            return false;
        }

        if (id == android.R.id.home) {
            mDrawerLayout.openDrawer(GravityCompat.START);
            return true;
        }

        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        ScannerFragment fragment = (ScannerFragment) getSupportFragmentManager()
                .findFragmentByTag(SCANNER_FRAGMENT_TAG);
        if (fragment != null) {
            return fragment.onKeyDown(keyCode, event);
        } else {
            return false;
        }
    }

    private ActionBarDrawerToggle setupDrawerToggle() {
        return new ActionBarDrawerToggle(this, mDrawerLayout, mToolbar, R.string.navigation_drawer_open,
                R.string.navigation_drawer_close);
    }

    private void setupDrawerContent(NavigationView navigationView) {
        Menu menu = navigationView.getMenu();
        MenuItem menuItem = menu.findItem(R.id.scanner_fragment);
        menuItem.setChecked(true);
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(MenuItem menuItem) {
                selectDrawerItem(menuItem);
                return true;
            }
        });
    }

    public void selectDrawerItem(MenuItem menuItem) {
        // Create a new fragment and specify the planet to show based on
        // position
        if (!menuItem.isChecked()) {

            switch (menuItem.getItemId()) {
            case R.id.scanner_fragment:
                startScannerFragment();
                break;
            case R.id.scan_list_fragment:
                startScanListFragment();
                break;
            case R.id.settings_fragment:
                startSettingsFragment();
                break;
            case R.id.file_list_fragment:
                startFileListFragment();
                break;
            case R.id.about:
                startAboutFragment();
                break;
            default:
                startScannerFragment();
            }

            // Highlight the selected item, update the title, and close the drawer
            setTitle(menuItem.getTitle());
            menuItem.setChecked(true);
        }
        mDrawerLayout.closeDrawers();
    }

    private void showTwoScanErrorDialog() {
        boolean twoScan = Utility.getSharedPreferenceValueBoolean(this, getString(R.string.pref_two_scan_key));

        if (twoScan) {
            AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle(R.string.error_dialog_title_two_scan)
                    .setMessage(R.string.error_dialog_message_two_scan).setIcon(R.drawable.ic_warning_black_24dp)
                    .setNeutralButton(R.string.error_dialog_neutral_two_scan, null).create();
            alertDialog.show();
        }
    }

    @Override
    public void onScanCompleted(BaseAsset asset) {

        long count = mTodayData.getCount() + 1;

        DatabaseReference scanRef = mTodayRef.child("scans").push();

        scanRef.setValue(asset);

        mTodayRef.child("count").setValue(count);

    }

    @Override
    public void onScanEdited(BaseAsset asset, int position) {
        String key = mTodayData.getKeys().get(position);

        DatabaseReference scanRef = mTodayRef.child("scans");

        Query query = scanRef.child(key);

        Map<String, Object> map = new HashMap<>();
        map.put("machine", asset.getMachine());
        map.put("hotBox", asset.getHotBox());
        map.put("coldBox", asset.getColdBox());
        query.getRef().updateChildren(map);
    }

    @Override
    public void onScanDeleted(BaseAsset asset, int position) {
        String key = mTodayData.getKeys().get(position);

        DatabaseReference scanRef = mTodayRef.child("scans");

        Query query = scanRef.child(key);

        query.getRef().removeValue();

        long count = mTodayData.getCount() - 1;

        mTodayRef.child("count").setValue(count);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
            @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
        case PERMISSION_STORAGE:
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                makeFileDirs();
            }
            break;
        }
    }

    public boolean isStoragePermissionGranted() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
                        PERMISSION_STORAGE);
                return false;
            }
        } else {
            return true;
        }
    }

    public boolean checkCameraPermission() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CAMERA },
                        PERMISSION_CAMERA);
                return false;
            }
        } else {
            return true;
        }
    }

    public void makeFileDirs() {
        File externalDir = Environment.getExternalStorageDirectory();
        String externalDirPath = externalDir.getPath();

        File scannerDir = new File(externalDirPath + getString(R.string.file_directory));
        scannerDir.mkdirs();
        scannerDir.setReadable(true);
    }

    private void setupDatabase() {
        mTodayRef = FirebaseUtility.getTodayRef();
        mTodayRef.child("count").addChildEventListener(mScanCountListener);
        mTodayRef.child("count").addValueEventListener(scanCountValueListener);
        Query scanQuery = mTodayRef.child("scans").orderByKey();
        scanQuery.addChildEventListener(mScanListener);
    }

    private void sendDataBroadcast() {
        Intent intent = new Intent("Firebase");
        intent.putExtra("todayData", mTodayData);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }

    public void startScannerFragment() {
        ScannerFragment scannerFragment = ScannerFragment.newInstance(mTodayData);

        getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .replace(R.id.content_frame, scannerFragment, SCANNER_FRAGMENT_TAG).addToBackStack(null).commit();
    }

    public void startScanListFragment() {
        getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .replace(R.id.content_frame, new ScanListFragment(), SCAN_LIST_TAG).addToBackStack(null).commit();
    }

    public void startFileListFragment() {
        getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .replace(R.id.content_frame, new FileListFragment(), FILE_LIST_FRAGMENT_TAG).addToBackStack(null)
                .commit();
    }

    public void startSettingsFragment() {
        getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .replace(R.id.content_frame, new SettingsFragment(), SETTINGS_FRAGMENT_TAG).addToBackStack(null)
                .commit();
    }

    public void startAboutFragment() {
        getSupportFragmentManager().beginTransaction().setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .replace(R.id.content_frame, new AboutFragment(), ABOUT_FRAGMENT_TAG).addToBackStack(null).commit();
    }
}