How to use method onNewIntent(Intent intent) inside a Fragment?
Asked Answered
C

4

20

I'm trying to use NFC Hardware from my device. But, the problem is that when I register the Activity to receive the Intent:

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

I receive the result in an Activity instead of a Fragment. Is there a way to handle this result inside a Fragment?

Thanks in advance!

Chaschase answered 5/5, 2015 at 2:33 Comment(0)
L
21

onNewIntent belongs to Activity so you cannot have it in your fragment. What you can do is pass the data to your fragment when it arrives in onNewIntent provided you have the reference to the fragment.

Fragment fragment;  
@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);

    // Check if the fragment is an instance of the right fragment
    if (fragment instanceof MyNFCFragment) {
        MyNFCFragment my = (MyNFCFragment) fragment;
        // Pass intent or its data to the fragment's method
        my.processNFC(intent.getStringExtra());
    }

}
Leandra answered 5/5, 2015 at 3:19 Comment(2)
What is the lifecycle equivalent of onNewIntent in Fragment?Bread
@Bread Fragments don't have launch modes, on top of that they aren't initiated by Intent as opposed to Activity, so there is no equivalent.Kitts
C
3

I fixed my issue the following way:

in MyActivity.java

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}

in MyFragment.java

@Override
public void onStart() {
    super.onStart();
    if (getActivity() != null && getActivity().getIntent().hasExtra(...)) {
        // do whatever needed
    }
}
Ceres answered 7/9, 2020 at 12:23 Comment(0)
P
1

Using LiveData:

Repository:

class IntentRepo  {
    private val _intent = MutableLiveData<Intent>()

    val get: LiveData<Intent> = Transformations.map(_intent) { it!! }

    fun set(intent: Intent) { _intent.value = intent }
}

Activity ViewModel:

class MainViewModel(intentRepo: IntentRepo) : ViewModel() {
    val intent = intentRepo
}

Activity

override fun onNewIntent(intent: Intent?) {
    super.onNewIntent(intent)
    viewModel.intent.set(intent)
}

Fragment

viewModel.intent.get.observe(viewLifecycleOwner, {
    // Your intent: $it
})
Placable answered 12/3, 2021 at 12:20 Comment(0)
A
-1

We handled the call in a more dynamic way to support any fragment, by having in the Activity something like:

// ...

public class ActivityMain extends AppCompatActivity {

    // ...

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        Fragment fragment = getFragment();
        if (fragment != null) {
            try {
                Method method = fragment.getClass().getMethod("onNewIntent", Intent.class);
                method.invoke(fragment, intent);
            } catch (NoSuchMethodException ignored) {
            } catch (IllegalAccessException | InvocationTargetException e) {
                Log.e(TAG, "Failed to call onNewIntent method for class: " + fragment.getClass().getSimpleName());
            }
        }
    }

    public Fragment getFragment() {
        // For NAVIGATION-DRAWER only
        // (replace below logic, if you use View-Pager).

        FragmentManager manager = this.getSupportFragmentManager();
        manager.executePendingTransactions();
        return manager.findFragmentById(R.id.my_main_content);
    }
}

Then in each root Fragment simply listen:

  @SuppressWarnings("unused")
  public void onNewIntent(Intent intent) {
    Log.i("MyTag", "onNewIntent: " + intent);
  }
Aubrey answered 19/10, 2020 at 6:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.