【问题标题】:Tap on notification to open app destination with Navigation component, incorrect destination点击通知以使用导航组件打开应用程序目的地,目的地不正确
【发布时间】:2020-07-29 06:33:11
【问题描述】:

我正在尝试通过点击通知在导航图中打开特定目的地。我创建了 Pending Intent 如下-

//this code in service to create notification       
OccasionViewerArgs.Builder builderArg = new OccasionViewerArgs.Builder();
builderArg.setPrimaryKey(2);
builderArg.setOccasionClickType("Birthday");
PendingIntent pendingIntent = new NavDeepLinkBuilder(this)
    .setGraph(R.navigation.dashboard_navigation)
    .setDestination(R.id.occasionViewer)
    .setArguments(builderArg.build().toBundle())
    .createPendingIntent();

问题:

当我点击通知时,我希望导航到我的“occasionViewer”片段,这是相同的片段,设置为目的地R.id.occasionViewer,但我正在导航到导航图的开始目的地片段,即“仪表板片段”。

我尝试将目的地更改为同一图中 R.id.addBirthdayFragment 中的其他目的地之一,如下所示 -

PendingIntent pendingIntent = new NavDeepLinkBuilder(this)
    .setGraph(R.navigation.dashboard_navigation)
    .setDestination(R.id.addBirthdayFragment)
    //.setArguments(builderArg.build().toBundle())
    .createPendingIntent();

然后它按预期工作,意味着在通知点击时我正在导航到 addBirthdayFragment。

您能否调查一下,让我知道我在这里做错了什么,任何建议或帮助都会让我开心。

这里是 nav_graph (R.navigation.dashboard_navigation)

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@id/dashboard_navigation"
    app:startDestination="@id/dashboardFragment">

    <fragment
        android:id="@+id/dashboardFragment"
        android:name="buzz.anusmarak.ui.dashboard.DashboardFragment"
        android:label=""
        tools:layout="@layout/fragment_dashboard" >
        <action
            android:id="@+id/action_dashboardFragment_to_addBirthdayFragment"
            app:destination="@id/addBirthdayFragment" />
        <action
            android:id="@+id/action_dashboardFragment_to_occasionViewer"
            app:destination="@id/occasionViewer"/>
    </fragment>
    
    <fragment
        android:id="@+id/addBirthdayFragment"
        android:name="buzz.anusmarak.ui.birthday.AddBirthdayFragment"
        android:label="Add Birthday"
        tools:layout="@layout/fragment_add_birthday" >
        <action
            android:id="@+id/action_addBirthdayFragment_to_dashboardFragment"
            app:destination="@id/dashboardFragment"
            app:popUpTo="@+id/dashboardFragment"
            app:popUpToInclusive="true" />
        <action
            android:id="@+id/action_addBirthdayFragment_to_occasionViewer"
            app:destination="@id/occasionViewer"
            app:popUpTo="@+id/dashboardFragment"
            app:popUpToInclusive="true" />
    </fragment>
    
    <fragment
        android:id="@+id/occasionViewer"
        android:name="buzz.anusmarak.ui.dashboard.occasion_viewer.OccasionViewer"
        android:label=""
        tools:layout="@layout/fragment_occasion_viewer" >
        <argument
            android:name="primaryKey"
            app:argType="integer"
            android:defaultValue="-1" />
        <argument
            android:name="occasionClickType"
            app:argType="string"
            android:defaultValue="default" />
        <action
            android:id="@+id/action_occasionViewer_to_dashboardFragment"
            app:destination="@id/dashboardFragment" />
    </fragment>
</navigation>

感谢您提前付出的努力和时间。

编辑 1

观察者如下

private LiveData<Occasion> occasionLiveData;

        occasionLiveData = AppRoomDatabase.getDatabase(requireContext().getApplicationContext())
                .occasionDao().findOccasionByKey(primaryKey);

        occasionLiveData.observe(getViewLifecycleOwner(), new Observer<Occasion>() {
            @Override
            public void onChanged(Occasion occasion) {
                if (occasion != null) {
                    setupValues(occasion);
                }
            }
        });

方法setupValues(occasion),在这里我使用Occasion 来更新不同的值。

我在 onActivityCreated() 中使用观察者。

编辑 2

场合查看器

public class OccasionViewer extends Fragment implements DatePickerFragment.DatePickerDialogListener
        , MenuItem.OnMenuItemClickListener {

    private static final String TAG = "OccasionViewer";

    private int primaryKey;
    private String occasionClickType;
    private ImageView isImportantImg, makeCall;
    private CircularImageView personImg;
    private LiveData<Occasion> occasionLiveData;
    .....

    public OccasionViewer() {
        // Required empty public constructor
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            primaryKey = OccasionViewerArgs.fromBundle(getArguments()).getPrimaryKey();
            occasionClickType = OccasionViewerArgs.fromBundle(getArguments()).getOccasionClickType();
            Transition sharedElementEnterTransition = TransitionInflater.from(getContext()).inflateTransition(android.R.transition.move);
            setSharedElementEnterTransition(sharedElementEnterTransition);
            postponeEnterTransition();
        }
    }

    @Override
    public void onDestroy() {
        occasionLiveData.removeObservers(this);
        super.onDestroy();
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_occasion_viewer, container, false);
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        occasionLiveData = AppRoomDatabase.getDatabase(requireContext().getApplicationContext())
                .occasionDao().findOccasionByKey(primaryKey);

        occasionLiveData.observe(getViewLifecycleOwner(), new Observer<Occasion>() {
            @Override
            public void onChanged(Occasion occasion) {
                if (occasion != null) {
                    setupValues(occasion);
                }
            }
        });

    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        CollapsingToolbarLayout collapsingToolbarLayout = view.findViewById(R.id.collapsing_toolbar);
        NavController navController = Navigation.findNavController(view);
        Toolbar toolbar = view.findViewById(R.id.toolbar);

        personImg = view.findViewById(R.id.person_img);
        isImportantImg = view.findViewById(R.id.is_important_img);

        toolbar.setTransitionName(occasionClickType+primaryKey+"cardView");
        personImg.setTransitionName(occasionClickType+primaryKey+"imageView");
        isImportantImg.setTransitionName(occasionClickType+primaryKey+"importantView");

        AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
        NavigationUI.setupWithNavController(collapsingToolbarLayout, toolbar, navController, appBarConfiguration);

        .................

    }

    private void setupValues(Occasion occasion) {
        //using occasion to setup values
    }

    // further method for setup different fields
}

编辑 3(一些观察)

我的 DashboardFragment 有一个回收视图,在项目单击时导航到 OccasionViewer,但是当点击通知时,它确实将我带到 DashboardFragment,然后我单击回收视图项目,它会出现此错误:

 --------- beginning of crash
07-30 10:56:57.695 16143-16143/buzz.anusmarak E/AndroidRuntime: FATAL EXCEPTION: main
    Process: buzz.anusmarak, PID: 16143
    java.lang.IllegalArgumentException: Navigation action/destination buzz.anusmarak:id/action_dashboardFragment_to_occasionViewer cannot be found from the current destination Destination(buzz.anusmarak:id/occasionViewer) label= class=buzz.anusmarak.ui.dashboard.occasion_viewer.OccasionViewer
        at androidx.navigation.NavController.navigate(NavController.java:931)
        at androidx.navigation.NavController.navigate(NavController.java:1128)
        at buzz.anusmarak.ui.dashboard.DashboardFragment.onUpcomingOccasionClick(DashboardFragment.java:387)

添加 PSR

在此处查找问题的 PSR..

https://drive.google.com/file/d/1-3yuQU-4YPprZHk5cUGoq20Ck82y3omT/view?usp=sharing

编辑 4(由 AdrianK 解决)

我打电话给startPostponedEnterTransition();如下

private void setupValues(Occasion occasion) {
    matchingOccasion = occasion;
    collapsingToolbarLayout.setTitle(matchingOccasion.getPersonName());
    String personImageID = matchingOccasion.getPersonImage();
    if (!personImageID.isEmpty()) {

    File filepath = requireContext().getExternalFilesDir(null);
    File file = new File(filepath + "/" + personImageID + ".jpeg");
    Picasso.with(requireContext()).load(file)
        .into(personImg, new Callback() {
    @Override
    public void onSuccess() {
        // startPostponedEnterTransition();
    }
    .......

问题已通过以下更改解决 -

public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    ......
    startPostponedEnterTransition();
    ......

再次感谢 AdrianK 花时间研究我的代码。干杯.. !!

【问题讨论】:

  • 您使用的是最新的 Navigation 2.3.0 版本吗?如果是这样,您应该 file an issue 提供一个重现您的问题的项目。
  • @ianhanniballake 感谢您的时间和回复。我正在使用 Navigation 2.3.0 版本。我尝试通过创建一个测试项目来重现这个问题,但它工作正常,我仍然无法弄清楚为什么我在我的实际项目中面临这个问题。测试和实际项目的唯一区别是,数据来自 Room Database 基于传递的参数。
  • 您能否将OccasionViewer 的代码包含在内?您的片段是否在任何地方调用您的 action_occationViewer_to_dashboardFragment 操作(例如在 observe 中)?
  • 您确定在OccasionViewer 中调用startPostponedEnterTransition() 吗?这可能是片段未显示的原因之一,但 navController 认为您已经在那里

标签: android android-jetpack android-architecture-navigation android-jetpack-navigation android-navigation-graph


【解决方案1】:

AdrianK 在Edit 4.中解决的问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 2020-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多