com.ferid.app.notetake.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.ferid.app.notetake.MainActivity.java

Source

/*
 * Copyright (C) 2016 Ferid Cafer
 *
 * 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.
 */

package com.ferid.app.notetake;

import android.Manifest;
import android.appwidget.AppWidgetManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.speech.RecognizerIntent;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Toast;

import com.ferid.app.notetake.dialogs.PromptDialog;
import com.ferid.app.notetake.interfaces.PromptListener;
import com.ferid.app.notetake.prefs.PrefsUtil;
import com.ferid.app.notetake.utility.DirectoryUtility;
import com.ferid.app.notetake.widget.NoteWidget;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @author Ferid Cafer
 */
public class MainActivity extends AppCompatActivity {
    private Context context;
    private EditText notePad;

    private static final int SPEECH_REQUEST_CODE = 100;
    private static final int REQUEST_EXTERNAL_STORAGE = 101;

    private static final String EXTENSION = ".txt";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        context = this;

        final Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        notePad = findViewById(R.id.notePad);

        setFontSize();

        getText();
    }

    /**
     * Retrieves from preferences
     */
    private void getText() {
        Handler handler = new Handler();
        handler.post(new Runnable() {
            @Override
            public void run() {
                String note = PrefsUtil.getNote(context);

                writeIntoNote(note);
            }
        });
    }

    /**
     * Write a text into notePad Edittext
     * @param note
     */
    private void writeIntoNote(final String note) {
        if (notePad != null) {
            notePad.setText(note);
            notePad.setSelection(notePad.getText().length());
        }
    }

    /**
     * Append note
     * @param note
     */
    private void appendNote(final String note) {
        if (notePad != null) {
            //get the current note which was already written
            String currentNote = notePad.getText().toString();
            //if there is something written before, go to a new line
            if (!currentNote.equals("")) {
                currentNote += "\n";
            }
            //now write
            writeIntoNote(currentNote + note);
        }
    }

    /**
     * Erase but do not save immediately
     */
    private void eraseAll() {
        if (notePad != null) {
            AlertDialog.Builder builderOperation = new AlertDialog.Builder(context);
            builderOperation.setTitle(R.string.eraseAll);
            builderOperation.setMessage(getString(R.string.sure));
            builderOperation.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    notePad.setText("");
                }
            });
            builderOperation.setNegativeButton(getString(R.string.no), null);
            AlertDialog alertDialog = builderOperation.create();
            alertDialog.show();
        }
    }

    /**
     * Saves into preferences
     */
    private void saveText() {
        if (notePad != null) {
            PrefsUtil.setNote(context, notePad.getText().toString());

            updateNoteWidget();
        }
    }

    /**
     * Shares notes
     */
    private void shareNotes() {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("text/plain");
        intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.app_name));
        intent.putExtra(Intent.EXTRA_TEXT, notePad.getText().toString());

        startActivity(Intent.createChooser(intent, getString(R.string.share)));
    }

    /**
     * Voice listener
     */
    private void listenToUser() {
        Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
        intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
        try {
            startActivityForResult(intent, SPEECH_REQUEST_CODE);
        } catch (ActivityNotFoundException e) {
            Toast toast = Toast.makeText(context, getString(R.string.voiceRecognitionNotSupported),
                    Toast.LENGTH_SHORT);
            toast.setGravity(Gravity.CENTER, 0, 0);
            toast.show();
        }
    }

    /**
     * Get file name via asking user
     */
    private void getFileName() {
        final PromptDialog promptDialog = new PromptDialog(context);
        promptDialog.setPositiveButton(getString(R.string.save));
        promptDialog.setOnPositiveClickListener(new PromptListener() {
            @Override
            public void OnPrompt(String promptText) {

                promptDialog.dismiss();

                if (!TextUtils.isEmpty(promptText)) {
                    final String fileName = promptText.trim();

                    if (!isFileExist(fileName)) {
                        saveAs(fileName);
                    } else {
                        Snackbar.make(notePad, getString(R.string.fileAlreadyExists), Snackbar.LENGTH_LONG)
                                .setAction(getString(R.string.overwrite), new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        deleteExistingFile(fileName);

                                        saveAs(fileName);
                                    }
                                }).show();
                    }
                }
            }
        });
        promptDialog.show();
    }

    /**
     * Does the given file name already exist?
     * @param fileName Given file name
     * @return yes or no
     */
    private boolean isFileExist(String fileName) {
        File file = new File(DirectoryUtility.getPathFolder() + fileName + EXTENSION);

        return file.exists();
    }

    /**
     * Delete existing file
     * @param fileName file name
     */
    private void deleteExistingFile(String fileName) {
        File file = new File(DirectoryUtility.getPathFolder() + fileName + EXTENSION);
        if (file.exists()) {
            file.delete();
        }
    }

    /**
     * Save into a file
     */
    private void saveAs(String fileName) {
        boolean isFileOperationSuccessful = true;

        if (DirectoryUtility.isExternalStorageMounted()) {

            DirectoryUtility.createDirectory();

            FileOutputStream outputStream = null;

            try {
                outputStream = new FileOutputStream(
                        new File(DirectoryUtility.getPathFolder() + fileName + EXTENSION));
                outputStream.write(notePad.getText().toString().getBytes());
            } catch (IOException e) {
                isFileOperationSuccessful = false;
            } finally {
                if (outputStream != null) {
                    try {
                        outputStream.flush();
                        outputStream.close();
                    } catch (IOException e) {
                        isFileOperationSuccessful = false;
                    }
                }
            }

            if (isFileOperationSuccessful) {
                Snackbar.make(notePad, getString(R.string.writeSuccess), Snackbar.LENGTH_LONG).show();
            } else {
                Snackbar.make(notePad, getString(R.string.writeError), Snackbar.LENGTH_LONG).show();
            }
        } else {
            Snackbar.make(notePad, getString(R.string.mountExternalStorage), Snackbar.LENGTH_LONG).show();
        }
    }

    /**
     * Ask user to change font size
     */
    private void changeFontSize() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(getString(R.string.fontSize));
        final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
        arrayAdapter.addAll(getResources().getStringArray(R.array.font_sizes));
        builder.setAdapter(arrayAdapter, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int which) {
                switch (which) {
                case 0:
                    PrefsUtil.setFontSize(context, getResources().getInteger(R.integer.font_size_small));
                    break;
                case 1:
                    PrefsUtil.setFontSize(context, getResources().getInteger(R.integer.font_size_medium));
                    break;
                case 2:
                    PrefsUtil.setFontSize(context, getResources().getInteger(R.integer.font_size_large));
                    break;
                default:
                    PrefsUtil.setFontSize(context, getResources().getInteger(R.integer.font_size_medium));
                    break;
                }

                setFontSize();
            }
        });
        AlertDialog alertDialog = builder.create();
        alertDialog.show();
    }

    /**
     * Set font size
     */
    private void setFontSize() {
        notePad.setTextSize(TypedValue.COMPLEX_UNIT_SP, PrefsUtil.getFontSize(context));
    }

    /**
     * Ask for read-write external storage permission
     */
    private void askForPermissionExternalStorage() {
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //permission yet to be granted

            getPermissionExternalStorage();
        } else { //permission already granted
            getFileName();
        }
    }

    /**
     * Request and get the permission for external storage
     */
    private void getPermissionExternalStorage() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

            Snackbar.make(notePad, R.string.grantPermission, Snackbar.LENGTH_LONG)
                    .setAction(R.string.ok, new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            ActivityCompat.requestPermissions(MainActivity.this,
                                    new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
                                    REQUEST_EXTERNAL_STORAGE);
                        }
                    }).show();
        } else {
            ActivityCompat.requestPermissions(MainActivity.this,
                    new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_EXTERNAL_STORAGE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {

        if (requestCode == REQUEST_EXTERNAL_STORAGE) {
            //if request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                getFileName();
            }
        }
    }

    /**
     * Capitalize the first letter of a given text
     * @param text
     * @return
     */
    private String capitalizeFirstLetter(String text) {
        return text.substring(0, 1).toUpperCase() + text.substring(1).toLowerCase();
    }

    @Override
    public void onBackPressed() {
        saveText();

        finish();
    }

    /**
     * Updates note widget
     */
    private void updateNoteWidget() {
        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
        ComponentName thisAppWidget = new ComponentName(context.getPackageName(), this.getClass().getName());
        Intent updateWidget = new Intent(context, NoteWidget.class);
        int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
        updateWidget.setAction(NoteWidget.APP_TO_WID);
        updateWidget.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
        context.sendBroadcast(updateWidget);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.item_save:
            saveText();
            finish();
            return true;
        case R.id.item_delete:
            eraseAll();
            return true;
        case R.id.item_listen:
            listenToUser();
            return true;
        case R.id.item_share:
            shareNotes();
            return true;
        case R.id.item_save_as:
            askForPermissionExternalStorage();
            return true;
        case R.id.item_size:
            changeFontSize();
            return true;
        default:
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (requestCode == SPEECH_REQUEST_CODE && resultCode == RESULT_OK) {

            ArrayList<String> results = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
            String spokenText = results.get(0);

            //capitalize the first letter
            spokenText = capitalizeFirstLetter(spokenText);
            //now append the spoken text
            appendNote(spokenText);

        }

        super.onActivityResult(requestCode, resultCode, data);
    }

}