简体   繁体   中英

Android Fragment argument bundle: getString returning null when key exists

I am pretty confident I'm missing something simple here. Apologies in advance, I'm new to Android.

So far my app sends a request to the Strava OAuth server, which returns to my app's implicit deep link via the callback URI I used in the request. I'm trying to get the 'code' and the 'scope' arguments that are passed with the callback URI passed to the fragment. The argument received is this, found via getArguments.

Bundle[{android-support-nav:controller:deepLinkIntent=Intent { act=android.intent.action.VIEW cat=[android.intent.category.BROWSABLE] dat=myapp://localhost/fibonacci/itemFragment?state=&code=d37efb9e5b66325ddd34614c41550dd1c00d8444&scope=read,activity:read_all,read_all flg=0x1440c000 cmp=com.example.fibonacci/.MainActivity (has extras) }}]

When I inspect the bundle variable while debugging I also see a hierarchy that includes this:

bundle -> mMap -> value[0] -> mData -> uriString

The uriString is a subset of the overall bundle derived from the arguments to the Fragment:

myapp://localhost/fibonacci/itemFragment?state=&code=d37efb9e5b66325ddd34614c41550dd1c00d8444&scope=read,activity:read_all,read_all

The code I've been experimenting with is below (see onCreate() ). I'm obviously doing something in a way that is too naive, because it is returning null for the things I'm trying to get out of the argument bundle. If there's a page in the Android documentation that I've overlooked I'd appreciate a link or suggestion.

Thanks!

package com.example.fibonacci;

import android.content.Context;
import android.os.Bundle;

import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.fibonacci.dummy.DummyContent;

/**
 * A fragment representing a list of Items.
 */
public class ItemFragment extends Fragment {

    // TODO: Customize parameter argument names
    private static final String ARG_COLUMN_COUNT = "column-count";
    private static final String ARG_STRAVA_CODE = "code";
    private static final String ARG_STRAVA_SCOPE = "scope";
    private static final String ARG_STRAVA_URISTRING = "uriString";

    // TODO: Customize parameters
    private int mColumnCount = 1;
    private String mCode = null;
    private String mScope = null;
    private String mUriString = null;

    /**
     * Mandatory empty constructor for the fragment manager to instantiate the
     * fragment (e.g. upon screen orientation changes).
     */
    public ItemFragment() {
    }

    // TODO: Customize parameter initialization
    @SuppressWarnings("unused")
    public static ItemFragment newInstance(int columnCount) {
        ItemFragment fragment = new ItemFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_COLUMN_COUNT, columnCount);
        fragment.setArguments(args);
        return fragment;
    }

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

        // Get arguments
        if (getArguments() != null) {
            mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);

            Bundle bundle = getArguments();

            mUriString = bundle.getString(ARG_STRAVA_URISTRING);
            mCode = bundle.getString(ARG_STRAVA_CODE);
            mScope = bundle.getString(ARG_STRAVA_SCOPE);
        }

        // GET the refresh and short-lived access token

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_item_list, container, false);

        // Set the adapter
        if (view instanceof RecyclerView) {
            Context context = view.getContext();
            RecyclerView recyclerView = (RecyclerView) view;
            if (mColumnCount <= 1) {
                recyclerView.setLayoutManager(new LinearLayoutManager(context));
            } else {
                recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
            }
            recyclerView.setAdapter(new MyItemRecyclerViewAdapter(DummyContent.ITEMS));
        }
        return view;
    }
}

Edit: I also don't understand why the 'column-count' argument doesn't show up in the bundle. That one was auto-created by the Fragment template I chose, but I would expect it to be in the overall bundle.

What I was missing was that the Bundle had a full Intent object inside of it. I had to query the Intent from the fragment's Activity with the code below:

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

        // Get arguments
        if (getArguments() != null) {
            mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);

            Bundle bundle = getArguments();

            Intent intent = getActivity().getIntent();
            Uri data = intent.getData();
            mCode = data.getQueryParameter(ARG_STRAVA_CODE);
            mScope = data.getQueryParameter(ARG_STRAVA_SCOPE);
        }

        // GET the refresh and short-lived access token

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM