方向更改时出现多个 Smart Lock 对话框
Multiple Smart Lock dialogs on orientation change
我最近将 Google 的 Smart Lock for Passwords 功能集成到我的应用程序中,几乎一切都如预期的那样顺利 运行。
只有一个小问题我还不能解决:在 ResultCallback#onResult
中,如果 status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED
以下命令会导致出现一个 Google 分辨率对话框,即询问是否通过 Smart Lock 保存凭据(见附图)或使用哪些凭据,如果 Smart Lock 中已经保存了多个凭据:
status.startResolutionForResult(getActivity(), REQUEST_CODE_READ);
当呈现分辨率对话框时,用户进行了一些方向更改,然后分辨率对话框成倍增加,每个对话框都与其他对话框重叠。作为用户,您首先看不到对话框有多个副本,但如果您关闭第一个(通过点击“从不”或“保存密码”),那么最上面的对话框就会消失,下面会显示另一个相同的对话框。
您可以通过在 activity 开始和停止之间保持一些状态来处理这个问题。
参见 sample code 中 mIsResolving
变量的使用。调用onSaveInstanceState()
时保存是否已经有pending dialog并在onCreate()
中恢复,如果有则避免再次调用API,清除状态一次onActivityResult()
是收到的意图。
private void resolveResult(Status status, int requestCode) {
// We don't want to fire multiple resolutions at once since that can result
// in stacked dialogs after rotation or another similar event.
if (mIsResolving) {
Log.w(TAG, "resolveResult: already resolving.");
return;
}
if (status.hasResolution()) {
try {
status.startResolutionForResult(MainActivity.this, requestCode);
mIsResolving = true;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
...
if (savedInstanceState != null) {
mIsResolving = savedInstanceState.getBoolean(KEY_IS_RESOLVING);
}
...
@Override
protected void onSaveInstanceState(Bundle outState) {
...
outState.putBoolean(KEY_IS_RESOLVING, mIsResolving);
...
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
...
mIsResolving = false;
...
这是许多应用程序的常见缺陷,因此我们将研究是否可以在 Play 服务层支持此状态,但目前,使用 activity 的布尔值是当前和通用的维持分辨率状态的建议。
我知道,这是一个老问题,但最近我不得不解决这个问题,在我的情况下,我在自定义 class 中使用 status.startResolutionForResult()
,但我没有任何访问权限到 onSaveInstanceState()
(我可以使用接口进行一些自定义回调,但我不想这样做),但在我的自定义 class 中,我有一个 activity 的实例,所以总是在调用之前startResolutionForResult()
我正在检查 mActivity.hasWindowFocus()
以查看 activity 是否失去焦点,因为对话框显示,如果它是真的,那么我调用 startResolutionForResult()
,否则我什么都不做
@Override
public void onResult(@NonNull LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()){
case LocationSettingsStatusCodes.SUCCESS:
getLocation();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
if (mActivity.hasWindowFocus()) {
try {
status.startResolutionForResult(mActivity, SETTINGS_CHECK);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
mReceiver.unableToObtainLocation();
break;
}
}
我最近将 Google 的 Smart Lock for Passwords 功能集成到我的应用程序中,几乎一切都如预期的那样顺利 运行。
只有一个小问题我还不能解决:在 ResultCallback#onResult
中,如果 status.getStatusCode() == CommonStatusCodes.RESOLUTION_REQUIRED
以下命令会导致出现一个 Google 分辨率对话框,即询问是否通过 Smart Lock 保存凭据(见附图)或使用哪些凭据,如果 Smart Lock 中已经保存了多个凭据:
status.startResolutionForResult(getActivity(), REQUEST_CODE_READ);
当呈现分辨率对话框时,用户进行了一些方向更改,然后分辨率对话框成倍增加,每个对话框都与其他对话框重叠。作为用户,您首先看不到对话框有多个副本,但如果您关闭第一个(通过点击“从不”或“保存密码”),那么最上面的对话框就会消失,下面会显示另一个相同的对话框。
您可以通过在 activity 开始和停止之间保持一些状态来处理这个问题。
参见 sample code 中 mIsResolving
变量的使用。调用onSaveInstanceState()
时保存是否已经有pending dialog并在onCreate()
中恢复,如果有则避免再次调用API,清除状态一次onActivityResult()
是收到的意图。
private void resolveResult(Status status, int requestCode) {
// We don't want to fire multiple resolutions at once since that can result
// in stacked dialogs after rotation or another similar event.
if (mIsResolving) {
Log.w(TAG, "resolveResult: already resolving.");
return;
}
if (status.hasResolution()) {
try {
status.startResolutionForResult(MainActivity.this, requestCode);
mIsResolving = true;
...
@Override
protected void onCreate(Bundle savedInstanceState) {
...
if (savedInstanceState != null) {
mIsResolving = savedInstanceState.getBoolean(KEY_IS_RESOLVING);
}
...
@Override
protected void onSaveInstanceState(Bundle outState) {
...
outState.putBoolean(KEY_IS_RESOLVING, mIsResolving);
...
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
...
mIsResolving = false;
...
这是许多应用程序的常见缺陷,因此我们将研究是否可以在 Play 服务层支持此状态,但目前,使用 activity 的布尔值是当前和通用的维持分辨率状态的建议。
我知道,这是一个老问题,但最近我不得不解决这个问题,在我的情况下,我在自定义 class 中使用 status.startResolutionForResult()
,但我没有任何访问权限到 onSaveInstanceState()
(我可以使用接口进行一些自定义回调,但我不想这样做),但在我的自定义 class 中,我有一个 activity 的实例,所以总是在调用之前startResolutionForResult()
我正在检查 mActivity.hasWindowFocus()
以查看 activity 是否失去焦点,因为对话框显示,如果它是真的,那么我调用 startResolutionForResult()
,否则我什么都不做
@Override
public void onResult(@NonNull LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()){
case LocationSettingsStatusCodes.SUCCESS:
getLocation();
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
if (mActivity.hasWindowFocus()) {
try {
status.startResolutionForResult(mActivity, SETTINGS_CHECK);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
mReceiver.unableToObtainLocation();
break;
}
}