2

I'm working on my first app. Got everything set up and working correctly, except displaying a random quote from a text file. Clicking the button shows weird characters (diamonds, question marks, etc) and not the actual text except for the placeholder off and on.

I followed the github source correctly as far as I know.

package drewstephensdesigns.com.dailyquotes;

import android.content.Intent;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.ShareActionProvider;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Random;

public class MainActivity extends AppCompatActivity {

    private TextView mTextView;

    private String STATE_DQ;
    private static String TEXT_VALUE = "";
    private ShareActionProvider mShareActionProvider;

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

        mTextView = (TextView) findViewById(R.id.dq_view);
        //Adds scrolling to the TextView
        mTextView.setMovementMethod(ScrollingMovementMethod.getInstance());
    }

    //Code to save state on orientation change
    @Override
    public void onSaveInstanceState(Bundle outState) {
        mTextView = (TextView) findViewById(R.id.dq_view);
        outState.putString(STATE_DQ, mTextView.getText().toString());
        super.onSaveInstanceState(outState);
    }

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

        mTextView = (TextView) findViewById(R.id.dq_view);
        mTextView.setText(STATE_DQ);
    }

    private AssetManager getApplicationAssets() {
        // open random quotes file
        AssetManager assetmanager = getAssets();
        return assetmanager;
    }

    private String getAssetPath(AssetManager assetmanager) {
        String[] dirs = null;
        String[] files = null;
        String path = null;

        try {
            dirs = assetmanager.list("");   //get list of files / dirs from the project 'assets' directory
            files = assetmanager.list(dirs[2]); //Directories are listed in alphabetical order so fetch the 'txt' directory
            path = dirs[2].toString() + "/" + files[0].toString();  //construct the path (there is only 1 file in the dir)
        } catch (IOException e) {
            e.printStackTrace();
        }
        return path;
    }

    // Get the path for the random quote file
    private InputStreamReader getQuoteReader() throws IOException {
        // open random quotes file
        AssetManager assets = getApplicationAssets();
        String path = null;
        path = getAssetPath(assets);
        InputStream inputStream = null;

        try {
            inputStream = assets.open(path);
            Log.v("QotD path", path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        InputStreamReader textReader = new InputStreamReader(inputStream);
        return textReader;
    }

    // Get the total number of lines in the file
    private int getFileLineCount(InputStreamReader textReader) {
        BufferedReader br = new BufferedReader(textReader);
        int lineCount = 0;
        try {
            while ((br.readLine()) != null) {
                lineCount++;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return lineCount; // total number of lines in the text file
    }

    // Return a random line number from where to get the
    // corresponding quote string
    private int getRandomLineNumber(int totalLines) {
        Random rand = new Random();
        return rand.nextInt(totalLines);
    }

    private String getRandomQuote(int lineToFetch)
            throws IOException {
        //1. get path
        AssetManager assets = getApplicationAssets();
        String path = null;
        path = getAssetPath(assets);

        //2. open assets
        InputStream stream = assets.open(path);
        InputStreamReader randomQuote = new InputStreamReader(stream);

        //3. Get BufferedReader object
        BufferedReader buf = new BufferedReader(randomQuote);

        String quote = null;
        String line = null;
        int currLine = 0;

        //4. Loop through using the new InputStreamReader until a match is found
        while ((line = buf.readLine()) != null && currLine < lineToFetch) {
            currLine++;
        }

        //Got the quote
        quote = line;

        //Clean up
        randomQuote.close();
        buf.close();

        return quote;
    }

    // Set the EditText widget to display the new random quote
    private void displayQuote(String quote) {
        TextView quoteDisplay = (TextView) findViewById(R.id.dq_view);
        TEXT_VALUE = quote;
        quoteDisplay.setText(TEXT_VALUE);
    }

    // onClick handler for the button click
    public void fetch_quote(View view) throws IOException {
        // open random quotes file
        InputStreamReader textReader = getQuoteReader();

        final int totalLines = getFileLineCount(textReader);
        int lineToFetch = 0;
        String quote = null;

        // We want to get the quote at the following line number
        lineToFetch = getRandomLineNumber(totalLines);

        quote = getRandomQuote(lineToFetch);

        displayQuote(quote);
    }

    @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);
        MenuItem shareItem = menu.findItem(R.id.menu_item_share);
        mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(shareItem);
        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
        switch(item.getItemId()){
            case R.id.menu_item_share:
                if(TEXT_VALUE == "") {
                    Toast.makeText(this, "Nothing to share! First generate a quote by clicking the button", Toast.LENGTH_SHORT).show();
                } else {
                    Intent shareIntent = new Intent(Intent.ACTION_SEND);
                    shareIntent.setType("text/plain");
                    shareIntent.putExtra(Intent.EXTRA_TEXT, TEXT_VALUE);
                    shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Thought you might like this interesting Quote");
                    startActivity(Intent.createChooser(shareIntent, "Share the quote via..."));
                }
                break;

            case R.id.action_settings:
                Toast.makeText(getApplicationContext(), "Settings not yet implemented", Toast.LENGTH_LONG).show();
                break;
            case R.id.action_about:
                Intent aboutIntent = new Intent(this, AboutActivity.class);
                startActivity(aboutIntent);
                break;
            default:
                break;
        }

        return super.onOptionsItemSelected(item);
    }
}

This is what I see:

App Screen Shot of weird stuff

ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96
  • 3
    Are you sure you are trying to read a **plain text** file? or are you trying to read a doc, a zip, an xls, an image or a database file? – Phantômaxx Aug 07 '16 at 09:47
  • The file is saved as randomquotes.txt, so as far as I know it's a regular text file. – Andrew Stephens Aug 07 '16 at 09:53
  • 3
    A .txt *file extension* doesn't make a file a plain text file. You can give a file whichever extension you want (or nothing or even multiple extensions) and this doesn't alter its contents. What happens if you try to open that file in a text editor? – Phantômaxx Aug 07 '16 at 09:56
  • 1
    I got it working. I had a font folder in there. I think that was causing the problem because it is working now! Woohoo!!!! – Andrew Stephens Aug 07 '16 at 09:57
  • 1
    @AndrewStephens Good that you found the cause. I recommend you replace the `getAssetPath(..)` helper method in your code by use of [`assetManager.open(String filename)`](https://developer.android.com/reference/android/content/res/AssetManager.html#open(java.lang.String)) to definitively fix the problem. – Barend Aug 07 '16 at 10:03
  • Definitely will. Sorry everyone if this was a rookie mistake. I'm slowly learning, but didn't think the extra folder would have any issues. Thank you for giving me advice and trying to help! Much appreciated fellow developers! – Andrew Stephens Aug 07 '16 at 10:12
  • @AndrewStephens - Please add your resolution as answer and mark as such. Thank you! – Roy Hinkley Aug 07 '16 at 14:05

1 Answers1

0

I had a folder called "fonts" that was not being used. My code was looking for the assets folder with just the randomquote.txt file. Due to the extra folder in there, it was unable to locate the txt file. Deleted the folder since it wasn't being used, saved, boom and progress.