Android onCreateContextMenu Fatal Exception by longclick on ListView item

Issue

I try to create Context Menu for my List View, but when i do “long-click” on List item, application shut down with this trace:

FATAL EXCEPTION: main
java.lang.NullPointerException
at com.android.internal.policy.impl.PhoneWindow$DecorView$ActionModeCallbackWrapper.onCreateActionMode(PhoneWindow.java:2445)
at com.android.internal.app.ActionBarImpl$ActionModeImpl.dispatchOnCreate(ActionBarImpl.java:708)
at com.android.internal.app.ActionBarImpl.startActionMode(ActionBarImpl.java:392)
at android.app.Activity.onWindowStartingActionMode(Activity.java:4380)
at com.android.internal.policy.impl.PhoneWindow$DecorView.startActionMode(PhoneWindow.java:2151)
at com.android.internal.policy.impl.PhoneWindow$DecorView.startActionModeForChild(PhoneWindow.java:2138)
at android.view.ViewGroup.startActionModeForChild(ViewGroup.java:573)
at android.view.ViewGroup.startActionModeForChild(ViewGroup.java:573)
at android.view.ViewGroup.startActionModeForChild(ViewGroup.java:573)
at android.view.View.startActionMode(View.java:3558)
at android.widget.AbsListView.performLongPress(AbsListView.java:2570)
at android.widget.AbsListView$CheckForLongPress.run(AbsListView.java:2530)
at android.os.Handler.handleCallback(Handler.java:605)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4340)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)

I browsed many examples and tutorials, but i can’t found decision.
Android API 14.

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

    linkButton = (Button) findViewById(R.id.link_button);
    debugTxt = (TextView) findViewById(R.id.debugText);     
    lv = (ListView) this.findViewById(R.id.filelist);

    registerForContextMenu(lv);

    linkButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            onClickLink();
        }
    });

    mDbxAcctMgr = DbxAccountManager.getInstance(getApplicationContext(), appKey, appSecret);
}

@Override
protected void onResume() {
    super.onResume();
    if (mDbxAcctMgr.hasLinkedAccount()) {
        showLinkedView();
        doDropboxTest();
    } else {
        showUnlinkedView();
    }
}

private void onClickLink() {
    mDbxAcctMgr.startLink((Activity)this, REQUEST_LINK_TO_DBX);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_LINK_TO_DBX) {
        if (resultCode == Activity.RESULT_OK) {
            doDropboxTest();
        } else {
            debugTxt.setText("Link to Dropbox failed or was cancelled.");
        }
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

private void doDropboxTest() {

try {
        // Create DbxFileSystem for synchronized file access.
        DbxFileSystem dbxFs = DbxFileSystem.forAccount(mDbxAcctMgr.getLinkedAccount());
        items = new ArrayList<String>();

        // Print the contents of the root folder.  This will block until we can
        // sync metadata the first time.
        List<DbxFileInfo> infos = dbxFs.listFolder(DbxPath.ROOT);
        debugTxt.setText("Contents of app folder:\n");

        for (DbxFileInfo info : infos) {
            info.path.toString();
            if (info.isFolder) {
                items.add(info.path.getName() + "/");
            } else {
                items.add(info.path.getName());
            }               
        }                       

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,   android.R.layout.simple_list_item_1, items);

        lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        //lv.setLongClickable(true);
        lv.setAdapter(adapter);   

    } catch (IOException e) {
        debugTxt.setText("Dropbox test failed: " + e);
    }


}

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

<item
    android:id="@+id/edit"
    android:title="@string/edit" />
<item
    android:id="@+id/remove"
    android:title="@string/remove" />
<item
    android:id="@+id/change"
    android:title="@string/change" />

</menu>

Thx for help!

Solution

When you register a View for a context menu with registerForContextMenu(), the Activity is set to receive the onCreateContextMenu() call. Remove the lv.setOnCreateContextMenuListener() call, and move the onCreateContextMenu() method to the Activity.

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

    linkButton = (Button) findViewById(R.id.link_button);
    debugTxt = (TextView) findViewById(R.id.debugText);
    lv = (ListView) this.findViewById(R.id.filelist);

    registerForContextMenu(lv);

    ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
    lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
    lv.setAdapter(adapter);

    linkButton.setOnClickListener(new OnClickListener()
    { 
        @Override
        public void onClick(View v) 
        {
            onClickLink();
        }
    });

    mDbxAcctMgr = DbxAccountManager.getInstance(getApplicationContext(), appKey, appSecret);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
{ //here u set u rute
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.login, menu);
}

Also, you don’t need to call lv.setLongClickable() when you’ve got lv registered for the context menu.

Answered By – Mike M.

Answer Checked By – Mary Flores (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.