androidandroid-intentextras

MainActivity puts valid String into Extras for an Intent but the Intent finds null String. What to do?


I am baffled by what's happening.

I put the file name "Help" into the Extras of the Intent that I then immediately start. (There can't be any problems with this first code block. With breakpoint after putExtra, Watch expression helpIntent.getStringExtra(PACKAGE_NAME + ".filename") returned "Help".)

import static com.dslomer64.sqhell.BuildConfig.APPLICATION_ID;
...
public class MainActivity extends Activity
{
  public final static String PACKAGE_NAME       = APPLICATION_ID;
...
  @Override public boolean onOptionsItemSelected(MenuItem item)
  {
    if(item.toString().equals("Help") || item.toString().equals("Acknowledgements"))
    {
      Intent
          helpIntent;
      helpIntent = new Intent(this, HelpActivity.class);

      helpIntent.putExtra(PACKAGE_NAME + ".filename", item.getTitle().toString());

      startActivity(helpIntent);
      return true;
    }
...
}

The fun begins in the spawned Intent:

public class HelpActivity extends Activity
{
...
  public void showHelp(AssetManager assets, String filename)
  {
    try
    {
    ////////////////////////////////////////////
    //                      filename = null ********* #1
       stream = assets.open(filename); 
    ////////////////////////////////////////////    }

    catch (IOException e) { e.printStackTrace(); }
...
  }

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

    Log.w("`````Help", "onCreate--bundle info: " + bundle.toString()) ;
    Log.w("`````Help","onCreate--bundle key: " + bundle.getString("filename") );

     Bundle bundle = getIntent().getExtras();

    setContentView(R.layout.activity_help);

    ////////////////////////////////////////////
    String fn = bundle.getString((PACKAGE_NAME + ".filename"));
    //     fn = null  ***************************** #2
    ////////////////////////////////////////////
    showHelp(getAssets(), fn ); 
  } 

The first sign of trouble (#1) was "filename is empty". Tracing back was easy. Now we're at #2, where--just compare--I use the same basic syntax to try to get the filename "Help" out of the Extras of the Intent. But it's null.

I'm not an expert with Intent but I've successfully used one a few times in the past.

I guess if I supplied a compilable program that shows the error it would be easier. But ...

If nobody spots anything right off, I'll get on that.

But it's straightforward!

But not.

================

EDIT

I added 2 Log statements (see above) and got this output:

    W/`````Help: onCreate--bundle info: 

Bundle[{com.dslomer64.sqhell.filename=Help}]
//////////////////////////////////////^^^^
    W/`````Help: onCreate--bundle key: null

Not sure how this helps since it looks like "Help" is where it should be. And I assume key is null is equivalent to the original problem about filename being null.

============================

EDIT #2: Here's the WHOLE HelpActivity class. If this doesn't help, I'll get on the compilable thing:

package com.dslomer64.sqhell;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;
import android.widget.EditText;
import java.io.IOException;
import java.io.InputStream;
import java.util.Scanner;
import static android.provider.ContactsContract.Directory.PACKAGE_NAME;

public class HelpActivity extends Activity
{
  Scanner     scDict;
  InputStream stream;
  EditText    help;

  public void showHelp(AssetManager assets, String filename)
  {
    help = /*(EditText)*/ findViewById(R.id.txaHelp);
    try
    {
      stream = assets.open(filename);
    }
    catch (IOException e) { e.printStackTrace(); }

    scDict = new Scanner(stream).useDelimiter("\n\r\t ,.:;-( )"); // added (SPACE) recently

    help.getText().clear();
    while(scDict.hasNext())
      help.append(scDict.next());

    hideKeyboard();

    help.setSelection(0);
  }

  @Override
  public void onCreate(Bundle savedInstanceState)
  {

    super.onCreate(savedInstanceState);

    Bundle bundle = getIntent().getExtras();

    setContentView(R.layout.activity_help);

    Log.w("`````Help", "onCreate--bundle info: "  + bundle.toString()) ;
    Log.w("`````Help", "onCreate--bundle key: "   + bundle.getString(PACKAGE_NAME + ".filename"));
    String fn =                                     bundle.getString(PACKAGE_NAME + ".filename");
    showHelp(getAssets(), fn );

  }

}

=========================

In following cricket's advice, I noticed a long line in the importarea:

    import static android.provider.ContactsContract.Directory.PACKAGE_NAME;

I don't remember ever seeing such before. So I took it out and got a few errors, wherever PACKAGE_NAME was used. Since each line had the "red underline" indicating use keypress 'Alt-Enter' for an easy import construction, I found that I HAD TWO CHOICES: the one above and MainActivity.PACKAGE_NAME.

I assume the previous time I did this, I chose the wrong item to import.

All is well.

Spent... too long on this.

Thanks to all who helped and Cricket for steering me in the right direction.

=====================

FINAL EDIT:

All I needed to do all along was delete the long import statement. And also pay attention to what I selected after doing it.

Criminey.

I thought I was doing what Cricket suggested all along. Didn't get the funny import in other classes. Why here????


Solution

  • it looks like "Help" is where it should be.

    It does

    ... key is null

    Its actually the value, but you're getting the value of the key "filename", not PACKAGE_NAME + ".filename", which is what you used in the putExtra.

    The keys don't match, so the value is null

    Suggestion: define your own constant like

    public static final String FILENAME_EXTRA = APPLICATION_ID + ".filename";
    

    and use that in all classes

    Additionally your Scanner and everything requiring the file to be opened should be inside the try block.