LocationSettingsRequest对话框启用GPS - 跳过onActivityResult()
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LocationSettingsRequest对话框启用GPS - 跳过onActivityResult()相关的知识,希望对你有一定的参考价值。
我的应用程序的一部分需要位置服务,因此如果当前关闭位置,应用程序将提示用户启用它。 Here是我如何做到的:(也见于this Stack Overflow答案)
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>()
{
@Override
public void onResult(LocationSettingsResult result)
{
final Status status = result.getStatus();
final LocationSettingsStates = result.getLocationSettingsStates();
switch (status.getStatusCode())
{
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
...
Log.d("onResult", "SUCCESS");
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
Log.d("onResult", "RESOLUTION_REQUIRED");
try
{
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(OuterClass.this, REQUEST_LOCATION);
}
catch (SendIntentException e)
{
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
...
Log.d("onResult", "UNAVAILABLE");
break;
}
}
});
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
// This log is never called
Log.d("onActivityResult()", Integer.toString(resultCode));
final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode)
{
case REQUEST_LOCATION:
switch (resultCode)
{
case Activity.RESULT_OK:
{
// All required changes were successfully made
break;
}
case Activity.RESULT_CANCELED:
{
// The user was asked to change settings, but chose not to
break;
}
default:
{
break;
}
}
break;
}
}
这段代码效果很好,但onActivityResult()
总是被跳过。无论用户是否从Yes
按No
,back
或Dialog
,onActivityResult()
都不会运行。
我需要android来调用onActivityResult()
,所以如果用户选择不打开位置服务,我可以适当地处理它。
谷歌的开发者页面(以及上面的代码)明确表示应该调用onActivityResult()
。任何人都知道为什么会被跳过?
我也不知道这一行的目的是什么:
final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
谢谢!
编辑:关于我的应用程序结构的基本信息:
- 此代码包含在
onResume()
的Fragment
方法中,该方法实现GoogleApiClient.ConnectionCallbacks
,GoogleApiClient.OnConnectionFailedListener
和LocationListener
以接收位置更新。例子看到here。 - 在
onLocationChanged()
,Fragment
将有一个自定义的View
调用invalidate()
并重新绘制自己的更新信息。
看起来主要的问题是你拥有片段中的所有代码,并且由于startResolutionForResult()
需要传入一个Activity,因此Activity会获得onActivityResult()
回调。
解决这个问题的一种方法是使用here描述的技术,当结果进入时,从Activity中手动调用Fragment的onActivityResult()
方法。
我刚才有这个简单的例子。
首先,Activity添加了Fragment,并且还具有将onActivityResult()
的结果传递给Fragment的功能:
public class MainActivity extends AppCompatActivity{
LocationFragment lFrag;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lFrag = LocationFragment.newInstance();
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, lFrag).commit();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == LocationFragment.REQUEST_LOCATION){
lFrag.onActivityResult(requestCode, resultCode, data);
}
else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
这是Fragment,它包含显示对话框和处理结果的所有功能。在这个简单的例子中,我只使用Toast消息来验证它是否按预期工作。请注意,我在这里从您的问题中的代码所做的主要更改是使用getActivity()
来获取调用startResolutionForResult()
所需的Activity引用。
public class LocationFragment extends Fragment
implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
PendingResult<LocationSettingsResult> result;
final static int REQUEST_LOCATION = 199;
public static LocationFragment newInstance() {
LocationFragment fragment = new LocationFragment();
return fragment;
}
public LocationFragment() {
// Required empty public constructor
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
mGoogleApiClient.connect();
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_location, container, false);
}
@Override
public void onResume() {
super.onResume();
}
@Override
public void onConnected(Bundle bundle) {
mLocationRequest = LocationRequest.create();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(30 * 1000);
mLocationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
result = LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
@Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
//final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
//...
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(
getActivity(),
REQUEST_LOCATION);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
//...
break;
}
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
Log.d("onActivityResult()", Integer.toString(resultCode));
//final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode)
{
case REQUEST_LOCATION:
switch (resultCode)
{
case Activity.RESULT_OK:
{
// All required changes were successfully made
Toast.makeText(getActivity(), "Location enabled by user!", Toast.LENGTH_LONG).show();
break;
}
case Activity.RESULT_CANCELED:
{
// The user was asked to change settings, but chose not to
Toast.makeText(getActivity(), "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
break;
}
default:
{
break;
}
}
break;
}
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
以下是可视化结果,如果禁用了位置模式,则首先显示对话框:
然后,如果用户单击否,结果将从活动传递到片段,片段显示Toast:
当用户单击“是”但具有成功结果并启用“位置模式”时,同样如此:
请注意,在Activity中保留所有这些功能可能是更好的选择,然后在结果进入时调用Fragment中的公共方法。
这是完整的代码,用于保持Activity中的功能。当然,在此解决方案中,您需要在调用onActivityResult()
之后向Fragment中添加一个调用以更新位置模式的状态。
public class MainActivity extends AppCompatActivity
implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
PendingResult<LocationSettingsResult> result;
final static int REQUEST_LOCATION = 199;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
以上是关于LocationSettingsRequest对话框启用GPS - 跳过onActivityResult()的主要内容,如果未能解决你的问题,请参考以下文章
LocationSettingsRequest对话框启用GPS - 跳过onActivityResult()
启用 GPS 的 LocationSettingsRequest 对话框 - 跳过了 onActivityResult()
当我们从顶部状态栏启用位置时,如何关闭LocationSettingsRequest对话框?
Android Fused LocationSettingsRequest 从 startResolutionForResult 中删除“从不”选项