Android 从 Android 设置导航回应用程序
Android navigate back to Application from Android Settings
由于 android 从 Android 设置返回的方式,我的用户体验不一致。
在我的应用程序中,用户需要授予我的应用程序访问 ACTION_USAGE_ACCESS_SETTINGS
的权限,我通过以下方式访问它:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
为我的应用程序将设置切换为打开后,我需要用户return 到我的应用程序。据我所知,这样做的唯一方法是让他们按下 phone 上的后退按钮(很想知道是否可以在切换设置后自动 return!!! ?!)。
现在会发生以下两种情况之一:
1) 用户最近未使用android设置,因此尚未打开(即在打开的应用程序抽屉中打开)。第一次按下后退按钮将根据需要将它们带到我的应用程序。
2) 用户最近使用了 android 设置。因此设置已经在应用程序抽屉中打开。现在,当用户按下返回键时,Android 将带他们返回他们最近使用过的每个设置页面(即返回按钮带他们进入 android 设置页面中的历史记录)。可能需要按 2、3 或 4 次后退按钮才能保留 Android 设置,并 return 到我的应用程序。这显然很糟糕UI/UX,我想知道是否有更好的方法?
我注意到在安装 Google 应用程序时,将设置切换为 ON 后,它会自动退出并 returns 到调用该设置的应用程序。能够做到这一点是最理想的,但我就是做不出来。
谢谢!
你可以在这里做一件事。你必须确认你只打开了你需要打开的设置组件....不要打开主设置应用程序。在您想要的设置应用程序中仅打开一个组件。这样一来,只要您按下返回键,就会跳回到您的应用程序。
For example if i want to open bluetooth settings in settings
application, I wont open the main Settings app instead i will open
only bluetooth component of settings. In that way when i press back i
will return to my own app because i haven't open the main setting app so i do not need to navigate in it.
ComponentName cn = new ComponentName("com.android.settings",
"com.android.settings.bluetooth.BluetoothSettings");
您必须确认您只打开了您需要打开的应用设置。不要打开主设置应用程序。仅打开您想要的应用程序设置。这样一来,只要您按下后退键,您就会跳回到您的应用程序。
Uri uri = Uri.fromParts("package", getPackageName(), null);
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(uri);
startActivity(intent);
启动设置后activity您可以运行周期性任务,每隔(例如 500 毫秒)调用一次,并检查是否已授予权限。
使用标志 singleTask/singleInstance 标记您的设置 activity,并在获得许可后启动它。 activity 的现有实例将移至顶部。
我这样做是为了获得通知访问权限。
好的,在尝试了大约一百万种方法之后,我想出了 3 种不同的方法来改善我的问题。
1) 由@CommonsWare 提供,通过删除 FLAG_ACTIVITY_NEW_TASK,它防止了所需的不一致的后退次数,这意味着每次用户只需按两次后退。
2) 在进一步研究标志后,我发现使用三个组合:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(intent);
将所需的背压次数减少到 1 次背压。这样简单合理,用户友好。
3) 在触发设置意图后,使用处理程序持续检查所需的权限。这看起来有点像 hack,我不敢相信没有更好的方法来做到这一点,但它的工作原理与使用 Google 应用程序时完全一样。即,一旦您将开关切换到打开状态,它就会退出 Android 设置页面,并 returns 返回您的应用程序,即您离开的地方。我正在使用:
Handler handler = new Handler();
Runnable checkSettingOn = new Runnable() {
@Override
//@TargetApi(23)
public void run() {
Log.d(TAG, "run: 1");
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.d(TAG, "run: 2");
return;
}
if (isAccessGranted()) {
Log.d(TAG, "run: 3");
//You have the permission, re-launch MainActivity
Intent i = new Intent(MainActivity.this, MainActivity.class);
Log.d(TAG, "run: 4");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
return;
}
handler.postDelayed(this, 200);
}
};
然后,当您触发进入 Android 设置页面的意图时,请务必启动处理程序:
handler.postDelayed(checkSettingOn, 1000);
希望这对遇到类似问题的其他人有所帮助。
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivity(intent);
这也是最简单的导航方式
根据 Ufkoku 的回答,我对权限状态进行了定期检查。为了让用户回来,我使用了 startActivityForResult 和 finishActivity。
示例代码:我将其用于“USAGE_ACCESS_SETTINGS”。
var intent = Intent("android.settings.USAGE_ACCESS_SETTINGS")
intent.data = Uri.fromParts("package", "com.example.app", null)
startActivityForResult(intent,101)
var timer = Timer(true)
timer.scheduleAtFixedRate(object: TimerTask(){
override fun run(){
if(checkUsageAccessPermission()){ // checkUsageAccessPermission() is a helper function
finishActivity(101)
cancel()
}
}
}, 0, 1000)
来自@Geordie Wicks 的解决方案与我正在寻找的很接近,但似乎在启动 intent
之前打开 Android 设置会导致后退按钮将您带到上一个 Android 设置屏幕。
我的解决方案涉及另外两个标志,Intent.FLAG_ACTIVITY_CLEAR_TOP
和 Intent.FLAG_ACTIVITY_CLEAR_TASK
。
您可以定义您的 intent
如下:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
根据我的经验,无论 Android 设置是否事先打开,这将使按下后退按钮将带您返回您的应用程序。
抱歉,如果回答晚了,但我把我的答案留在这里供其他人解决这个问题。对我来说,问题可能出在我们自己身上,而不是来自 Android。例如我有一个监听器,它监听开关的状态
setOnCheckedChangeListener { _, _ ->
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data =
Uri.fromParts(
"package",
navigator.activeFragment?.activity?.packageName,
null
)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
navigator.activeFragment?.startActivity(intent)
}
这段代码发生了什么?
用户转到“设置”,然后返回。如果你在用户返回后设置了一些更新 UI 的东西,那么这将导致多个监听器监听 switch
的变化
override fun onResume() {
super.onResume()
if (!isFirst) {
// Notify that user might have change the notification setting
(binding.rvSetting2.adapter as SettingAdapter).notifyItemChanged(0)
}
isFirst = false
我的解决方案
你可以在listener中添加这一行,这样会移除当前的switch监听器,这样就可以避免switch变化时去setting after和after。
setOnCheckedChangeListener { _, _ ->
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data =
Uri.fromParts(
"package",
navigator.activeFragment?.activity?.packageName,
null
)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
navigator.activeFragment?.startActivity(intent)
// Remove the current listener in case of user went back from Setting and call on bind view holder again
// This cause multiple listener listen to the change of this switch
setOnCheckedChangeListener(null)
}
我知道这只是我个人的解决方案,但如果您分享类似的方法,这可能会有所帮助。
由于 android 从 Android 设置返回的方式,我的用户体验不一致。
在我的应用程序中,用户需要授予我的应用程序访问 ACTION_USAGE_ACCESS_SETTINGS
的权限,我通过以下方式访问它:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
为我的应用程序将设置切换为打开后,我需要用户return 到我的应用程序。据我所知,这样做的唯一方法是让他们按下 phone 上的后退按钮(很想知道是否可以在切换设置后自动 return!!! ?!)。
现在会发生以下两种情况之一:
1) 用户最近未使用android设置,因此尚未打开(即在打开的应用程序抽屉中打开)。第一次按下后退按钮将根据需要将它们带到我的应用程序。
2) 用户最近使用了 android 设置。因此设置已经在应用程序抽屉中打开。现在,当用户按下返回键时,Android 将带他们返回他们最近使用过的每个设置页面(即返回按钮带他们进入 android 设置页面中的历史记录)。可能需要按 2、3 或 4 次后退按钮才能保留 Android 设置,并 return 到我的应用程序。这显然很糟糕UI/UX,我想知道是否有更好的方法?
我注意到在安装 Google 应用程序时,将设置切换为 ON 后,它会自动退出并 returns 到调用该设置的应用程序。能够做到这一点是最理想的,但我就是做不出来。
谢谢!
你可以在这里做一件事。你必须确认你只打开了你需要打开的设置组件....不要打开主设置应用程序。在您想要的设置应用程序中仅打开一个组件。这样一来,只要您按下返回键,就会跳回到您的应用程序。
For example if i want to open bluetooth settings in settings application, I wont open the main Settings app instead i will open only bluetooth component of settings. In that way when i press back i will return to my own app because i haven't open the main setting app so i do not need to navigate in it.
ComponentName cn = new ComponentName("com.android.settings",
"com.android.settings.bluetooth.BluetoothSettings");
您必须确认您只打开了您需要打开的应用设置。不要打开主设置应用程序。仅打开您想要的应用程序设置。这样一来,只要您按下后退键,您就会跳回到您的应用程序。
Uri uri = Uri.fromParts("package", getPackageName(), null);
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(uri);
startActivity(intent);
启动设置后activity您可以运行周期性任务,每隔(例如 500 毫秒)调用一次,并检查是否已授予权限。
使用标志 singleTask/singleInstance 标记您的设置 activity,并在获得许可后启动它。 activity 的现有实例将移至顶部。
我这样做是为了获得通知访问权限。
好的,在尝试了大约一百万种方法之后,我想出了 3 种不同的方法来改善我的问题。
1) 由@CommonsWare 提供,通过删除 FLAG_ACTIVITY_NEW_TASK,它防止了所需的不一致的后退次数,这意味着每次用户只需按两次后退。
2) 在进一步研究标志后,我发现使用三个组合:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(intent);
将所需的背压次数减少到 1 次背压。这样简单合理,用户友好。
3) 在触发设置意图后,使用处理程序持续检查所需的权限。这看起来有点像 hack,我不敢相信没有更好的方法来做到这一点,但它的工作原理与使用 Google 应用程序时完全一样。即,一旦您将开关切换到打开状态,它就会退出 Android 设置页面,并 returns 返回您的应用程序,即您离开的地方。我正在使用:
Handler handler = new Handler();
Runnable checkSettingOn = new Runnable() {
@Override
//@TargetApi(23)
public void run() {
Log.d(TAG, "run: 1");
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
Log.d(TAG, "run: 2");
return;
}
if (isAccessGranted()) {
Log.d(TAG, "run: 3");
//You have the permission, re-launch MainActivity
Intent i = new Intent(MainActivity.this, MainActivity.class);
Log.d(TAG, "run: 4");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);
return;
}
handler.postDelayed(this, 200);
}
};
然后,当您触发进入 Android 设置页面的意图时,请务必启动处理程序:
handler.postDelayed(checkSettingOn, 1000);
希望这对遇到类似问题的其他人有所帮助。
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivity(intent);
这也是最简单的导航方式
根据 Ufkoku 的回答,我对权限状态进行了定期检查。为了让用户回来,我使用了 startActivityForResult 和 finishActivity。
示例代码:我将其用于“USAGE_ACCESS_SETTINGS”。
var intent = Intent("android.settings.USAGE_ACCESS_SETTINGS")
intent.data = Uri.fromParts("package", "com.example.app", null)
startActivityForResult(intent,101)
var timer = Timer(true)
timer.scheduleAtFixedRate(object: TimerTask(){
override fun run(){
if(checkUsageAccessPermission()){ // checkUsageAccessPermission() is a helper function
finishActivity(101)
cancel()
}
}
}, 0, 1000)
来自@Geordie Wicks 的解决方案与我正在寻找的很接近,但似乎在启动 intent
之前打开 Android 设置会导致后退按钮将您带到上一个 Android 设置屏幕。
我的解决方案涉及另外两个标志,Intent.FLAG_ACTIVITY_CLEAR_TOP
和 Intent.FLAG_ACTIVITY_CLEAR_TASK
。
您可以定义您的 intent
如下:
Intent intent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
根据我的经验,无论 Android 设置是否事先打开,这将使按下后退按钮将带您返回您的应用程序。
抱歉,如果回答晚了,但我把我的答案留在这里供其他人解决这个问题。对我来说,问题可能出在我们自己身上,而不是来自 Android。例如我有一个监听器,它监听开关的状态
setOnCheckedChangeListener { _, _ ->
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data =
Uri.fromParts(
"package",
navigator.activeFragment?.activity?.packageName,
null
)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
navigator.activeFragment?.startActivity(intent)
}
这段代码发生了什么?
用户转到“设置”,然后返回。如果你在用户返回后设置了一些更新 UI 的东西,那么这将导致多个监听器监听 switch
的变化 override fun onResume() {
super.onResume()
if (!isFirst) {
// Notify that user might have change the notification setting
(binding.rvSetting2.adapter as SettingAdapter).notifyItemChanged(0)
}
isFirst = false
我的解决方案
你可以在listener中添加这一行,这样会移除当前的switch监听器,这样就可以避免switch变化时去setting after和after。
setOnCheckedChangeListener { _, _ ->
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
intent.data =
Uri.fromParts(
"package",
navigator.activeFragment?.activity?.packageName,
null
)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
navigator.activeFragment?.startActivity(intent)
// Remove the current listener in case of user went back from Setting and call on bind view holder again
// This cause multiple listener listen to the change of this switch
setOnCheckedChangeListener(null)
}
我知道这只是我个人的解决方案,但如果您分享类似的方法,这可能会有所帮助。