此答案假设您的服务是“已启动”服务。如果它是绑定服务或意向服务,请在评论中指出,我将更新此处包含的描述和代码。
我建议的解决方案是实现如下所示的活动来处理分辨率 UI。更换onConnectionFailed()
使用此代码在您的服务中的方法将解析处理移交给ResolverActivity
:
@Override
public void onConnectionFailed(ConnectionResult result) {
Intent i = new Intent(this, ResolverActivity.class);
i.putExtra(ResolverActivity.CONNECT_RESULT_KEY, result);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
将如下所示的活动添加到您的应用程序中。当您的服务中的连接请求失败时,连接结果是Parcelable
,传递给活动。该活动处理分辨率 UI,并在完成后将状态作为 Intent Extra 返回给服务。您需要修改服务中的代码onStartCommand()
检查 Intent 中的额外内容,以确定是否第一次调用它来启动服务,或者从 Intent 接收解析状态ResolverActivity
.
此方法的增强功能是发布带有PendingIntent
for ResolverActivity
而不是立即启动活动。这将使用户可以选择推迟解决连接故障。
public class ResolverActivity extends AppCompatActivity {
public static final String TAG = "ResolverActivity";
public static final String CONNECT_RESULT_KEY = "connectResult";
public static final String CONN_STATUS_KEY = "connectionStatus";
public static final int CONN_SUCCESS = 1;
public static final int CONN_FAILED = 2;
public static final int CONN_CANCELLED = 3;
// Request code to use when launching the resolution activity
private static final int REQUEST_RESOLVE_ERROR = 1111;
private static final String ERROR_CODE_KEY = "errorCode";
private static final String DIALOG_FRAG_TAG = "errorDialog";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(TAG, "onCreate()");
// No content needed.
//setContentView(R.layout.activity_main);
Intent i = getIntent();
ConnectionResult result = i.getParcelableExtra(CONNECT_RESULT_KEY);
if (result.hasResolution()) {
try {
Log.i(TAG, "Starting error resolution...");
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch (IntentSender.SendIntentException e) {
// There was an error with the resolution intent.
sendStatusToService(CONN_FAILED);
finish();
}
} else {
// Show dialog using GooglePlayServicesUtil.getErrorDialog()
ErrorDialogFragment.newInstance(result.getErrorCode())
.show(getSupportFragmentManager(), DIALOG_FRAG_TAG);
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent result) {
if (requestCode == REQUEST_RESOLVE_ERROR) {
if (resultCode == RESULT_OK) {
Log.i(TAG, "onActivityResult(): Connection problem resolved");
sendStatusToService(CONN_SUCCESS);
} else {
sendStatusToService(CONN_CANCELLED);
Log.w(TAG, "onActivityResult(): Resolution cancelled");
}
// Nothing more to do in this activity
finish();
}
}
private void sendStatusToService(int status) {
Intent i = new Intent(this, MyGoogleApiService.class);
i.putExtra(CONN_STATUS_KEY, status);
startService(i);
}
// Fragment to display an error dialog
public static class ErrorDialogFragment extends DialogFragment {
public static ErrorDialogFragment newInstance(int errorCode) {
ErrorDialogFragment f = new ErrorDialogFragment();
// Pass the error that should be displayed
Bundle args = new Bundle();
args.putInt(ERROR_CODE_KEY, errorCode);
f.setArguments(args);
return f;
}
@Override
@NonNull
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Get the error code and retrieve the appropriate dialog
int errorCode = getArguments().getInt(ERROR_CODE_KEY);
return GooglePlayServicesUtil.getErrorDialog(
errorCode, getActivity(), REQUEST_RESOLVE_ERROR);
}
@Override
public void onDismiss(DialogInterface dialog) {
Log.i(TAG, "Dialog dismissed");
}
}
}