我很难理解我做错了什么,所以我希望你能帮助我。
内容:
我正在使用Android Studio构建一个Android应用程序,以控制和监控我家中的物联网设备。我从Navigation Drawer Activity示例开始,因此我有3个片段和一个导航抽屉:
主页片段(“Accueil”):出现第一个片段,其中包含两个用于创建通知的测试按钮
**运动片段(“监视摄像机”):显示摄像机流网络视图的片段
**** Jmeter 板片段(“表格边框”)*:显示另一个web视图片段
Navigation drawer
Home fragment
我目前正在使用一个通知,该通知会直接打开我的应用进入Motion片段。为此,我使用了一个额外的通知发送的pendingIntent。根据它的值,在MainActivity的 onCreate 函数中,navController会被强制显示所请求的片段。在我的情况下,我希望通知显示Motion片段(“Camera de surveillance”)。
Notification
Intent intent = getIntent();
String fragmentName = intent.getStringExtra(FRAGMENTNAME);
if (fragmentName == null) fragmentName = "";
switch (fragmentName) {
case "motion":
navController.navigate(R.id.nav_motion);
break;
case "dashboard":
navController.navigate(R.id.nav_dashboard);
break;
case "home":
default:
navController.navigate(R.id.nav_home);
break;
}
那么接下来,测试:我打开我的应用程序,点击测试按钮“按钮1”以显示通知,关闭我的应用程序,点击通知,宾果!Motion片段首先打开!这工作得很完美...至少我是这么想的。
问题:
通过这样做,我得到了一个奇怪的行为时,应用程序已经从通知打开:我无法到达家园碎片。
在导航抽屉中,点击“Accueil”菜单打开Home片段,打开Motion片段(“Camera de surveillance”)。要查看Home片段,我需要退出应用程序并再次打开它。
我猜想,单击导航抽屉上的“Accueil”按钮以显示Home片段会重置MainActivity并调用 onCreate 函数,但这对我来说没有意义,因为该函数是创建应用程序时的第一个回调函数,而不是之后调用的,对吗?有人知道实际发生了什么吗?我如何才能获得所需的行为?
**编辑:**经过一些调试,使用通知作为指示器,我发现MainActivity的onCreate函数在启动时只被调用一次。此外,当导航抽屉处于“怪异行为”状态时,单击“返回”导航按钮将返回Home片段,并纠正导航抽屉的“怪异行为”。
我用来改变第一个片段的函数是导航控制器中的“navigate”函数,它将Home片段中的函数保存在内存中(真正的第一个显示的片段),我导航到了Motion片段。因此,只要我没有通过按“Back”按钮返回导航回栈,它就会在内存中保存以下内容:当我单击Home片段时,我导航到Motion片段。
我需要找到一种方法来删除导航历史记录,或者找到另一种方法来在开始时显示Motion片段。
完整文件源:
MainActivity.java
public class MainActivity extends AppCompatActivity {
public static final String FRAGMENTNAME = "com.mrxana91dev.maisonpaul.fragmentstartname";
public NotificationManagerCompat notificationManagerCompat;
private AppBarConfiguration mAppBarConfiguration;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.appBarMain.toolbar);
binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = binding.drawerLayout;
NavigationView navigationView = binding.navView;
// Passing each menu ID as a set of Ids because each
// menu should be considered as top level destinations.
mAppBarConfiguration = new AppBarConfiguration.Builder(
R.id.nav_home, R.id.nav_motion, R.id.nav_dashboard)
.setOpenableLayout(drawer)
.build();
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
NavigationUI.setupWithNavController(navigationView, navController);
this.notificationManagerCompat = NotificationManagerCompat.from(this);
// ADDED CODE TO CHANGE FIRST FRAGMENT DEPENDING ON FRAGMENTNAME EXTRA
Intent intent = getIntent();
String fragmentName = intent.getStringExtra(FRAGMENTNAME);
if (fragmentName == null) fragmentName = "";
switch (fragmentName) {
case "motion":
navController.navigate(R.id.nav_motion);
break;
case "dashboard":
navController.navigate(R.id.nav_dashboard);
break;
case "home":
default:
navController.navigate(R.id.nav_home);
break;
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
return NavigationUI.navigateUp(navController, mAppBarConfiguration)
|| super.onSupportNavigateUp();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_settings:
Intent intent = new Intent(this, SettingsActivity.class);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
家庭片段.java
public class HomeFragment extends Fragment {
public static final String EXTRA_FRAGMENT = "com.mrxana91dev.maisonpaul.fragmentstartname";
private FragmentHomeBinding binding;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
HomeViewModel homeViewModel =
new ViewModelProvider(this).get(HomeViewModel.class);
binding = FragmentHomeBinding.inflate(inflater, container, false);
View root = binding.getRoot();
final TextView textView = binding.textHome;
final TextView textView2 = binding.textView2;
homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
homeViewModel.getText2().observe(getViewLifecycleOwner(), textView2::setText);
final Button testButton1 = binding.testButton1;
final Button testButton2 = binding.testButton2;
testButton1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendOnChannel1();
}
});
testButton2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sendOnChannel2();
}
});
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
private void sendOnChannel1() {
String title = "Maison Paul - Test notification";
String message = "Mouvement repéré !";
MainActivity mainActivity = (MainActivity) getActivity();
Intent intent = new Intent(mainActivity, MainActivity.class);
intent.putExtra(EXTRA_FRAGMENT, "motion");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(mainActivity, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_MUTABLE);
Notification notification = new NotificationCompat.Builder(mainActivity, NotificationApp.CHANNEL_1_ID)
.setSmallIcon(R.drawable.ic_baseline_home_24)
.setContentTitle(title)
.setContentText(message)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
int notificationId = 1;
mainActivity.notificationManagerCompat.notify(notificationId, notification);
}
private void sendOnChannel2() {
String title = "Maison Paul - Test notification";
String message = "Notification from channel 2 !";
MainActivity mainActivity = (MainActivity) getActivity();
Notification notification = new NotificationCompat.Builder(mainActivity, NotificationApp.CHANNEL_2_ID)
.setSmallIcon(R.drawable.ic_menu_camera)
.setContentTitle(title)
.setContentText(message)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setCategory(NotificationCompat.CATEGORY_PROMO) // Promotion.
.build();
int notificationId = 2;
mainActivity.notificationManagerCompat.notify(notificationId, notification);
}
}
1条答案
按热度按时间js81xvg61#
好吧!我知道了。
我必须通过创建两个操作来更改导航菜单(mobile_navigation. xml)中的一些内容:
这两个动作都是使用popUpTo和popUpToInclusive设置的。
移动的导航.xml(提取)
然后,我使用相应的操作,而不是直接使用导航片段的id作为“navigate”函数的参数。
主活动.java -创建时(提取)
在所有这些更改之后,单击通知仍会按预期显示Motion片段,而单击导航抽屉中的“Accueil”按钮会按预期显示Home片段。
解决了!