Android 使用 AlertDialog 激活 GPS:如何等待用户采取行动?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12044552/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android activate gps with AlertDialog: how to wait for the user to take action?
提问by Dan Dinu
I've read different posts that there is no way to wait for the user to take an action when an AlertDialog
is shown because it blocks the UI.
我读过不同的帖子,当AlertDialog
显示an 时,无法等待用户采取操作,因为它会阻止 UI。
However, apps like Facebook
for example displays the Gps is currently disabled. Do you want to enable gps?alert dialog and wait for the user to press yes/no.
I'm thinking that it's possible to use 2 different activities, first one containing only the gps alert dialog, but this doesn't seem right and definetely doens't seem the way facebook does this.
但是,Facebook
例如显示Gps 之类的应用程序当前已禁用。您要启用 GPS 吗?警报对话框并等待用户按是/否。我认为可以使用 2 种不同的活动,第一种活动仅包含 gps 警报对话框,但这似乎不对,而且绝对不是 facebook 这样做的方式。
Can anyone tell me how can i achieve this?
谁能告诉我如何实现这一目标?
This is my code:
这是我的代码:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
InitializeComponents();
EnableGPSIfPossible();
ListAsync lAsync = new ListAsync(this);
lAsync .execute();
}
private void EnableGPSIfPossible()
{
final LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if ( !manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
buildAlertMessageNoGps();
}
}
private void buildAlertMessageNoGps() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Yout GPS seems to be disabled, do you want to enable it?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(@SuppressWarnings("unused") final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, @SuppressWarnings("unused") final int id) {
dialog.cancel();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
So, in my code the AsynTask
starts imediately without waiting for the user to activate the gps. (which is a normal behaviour)
因此,在我的代码中,AsynTask
无需等待用户激活 gps 即可立即启动。(这是正常行为)
Thank you!
谢谢!
采纳答案by Dan Dinu
I managed to get this to work.I got inspired by this article here which i found on stackoverlfow. http://developmentality.wordpress.com/2009/10/31/android-dialog-box-tutorial/
我设法让这个工作。我从这篇文章中得到了启发,这篇文章是我在 stackoverlfow 上找到的。http://developmentality.wordpress.com/2009/10/31/android-dialog-box-tutorial/
I basically moved the logic that i needed to execute on the "Yes" and "Cancel" buttons of the alert Dialog. After performing logic needed for Yes and Cancel buttons i start the asyncronous logic execution.
我基本上移动了我需要在警报对话框的“是”和“取消”按钮上执行的逻辑。在执行 Yes 和 Cancel 按钮所需的逻辑后,我开始异步逻辑执行。
Here's my code:
这是我的代码:
public interface ICommand
{
void execute();
}
The two concrete Commands used for Enable Gps and Cancel buttons of the alert Dialog:
用于警报对话框的启用 Gps 和取消按钮的两个具体命令:
public class CancelCommand implements ICommand
{
protected Activity m_activity;
public CancelCommand(Activity activity)
{
m_activity = activity;
}
public void execute()
{
dialog.dismiss();
//start asyncronous operation here
}
}
public class EnableGpsCommand extends CancelCommand
{
public EnableGpsCommand( Activity activity) {
super(activity);
}
public void execute()
{
// take the user to the phone gps settings and then start the asyncronous logic.
m_activity.startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
super.execute();
}
}
And now, from the Activity:
现在,从活动:
//returns true if the GpsProviderIsDisabled
//false otherwise
private boolean EnableGPSIfPossible()
{
final LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if ( !manager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
buildAlertMessageNoGps();
return true;
}
return false;
}
private void buildAlertMessageNoGps()
{
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Yout GPS seems to be disabled, do you want to enable it?")
.setCancelable(false)
.setPositiveButton("Yes", new CommandWrapper(new EnableGpsCommand(this)))
.setNegativeButton("No", new CommandWrapper(new CancelCommand(this)));
final AlertDialog alert = builder.create();
alert.show();
}
Now from the Activity OnCreate methodi just call:
现在从 Activity OnCreate 方法中调用:
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.newfriendlist);
InitializeComponents();
if (!EnableGPSIfPossible())
{
//then gps is already enabled and we need to do StartFriendRetrievalAsync from here.
//otherwise this code is being executed from the EnableGpsIfPossible() logic.
//Asyncronous logic here.
}
}
I really hope this will help you when you get stuck at this point :).
我真的希望这会在您陷入困境时对您有所帮助:)。
Cheers
干杯
回答by Alexis C.
What you can actually do is this :
你实际上可以做的是:
GPSManager.java :
GPSManager.java :
public class GPSManager {
private Activity activity;
private LocationManager mlocManager;
private LocationListener gpsListener;
public GPSManager(Activity activity) {
this.activity = activity;
}
public void start() {
mlocManager = (LocationManager) activity
.getSystemService(Context.LOCATION_SERVICE);
if (mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
setUp();
findLoc();
} else {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
activity);
alertDialogBuilder
.setMessage("GPS is disabled in your device. Enable it?")
.setCancelable(false)
.setPositiveButton("Enable GPS",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int id) {
Intent callGPSSettingIntent = new Intent(
android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
activity.startActivity(callGPSSettingIntent);
}
});
alertDialogBuilder.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = alertDialogBuilder.create();
alert.show();
}
}
public void setUp() {
gpsListener = new GPSListener(activity, mlocManager);
}
public void findLoc() {
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1, 1,
gpsListener);
if (mlocManager.getLastKnownLocation(LocationManager.GPS_PROVIDER) == null)
Toast.makeText(activity, "LAST Location null", Toast.LENGTH_SHORT)
.show();
else {
gpsListener.onLocationChanged(mlocManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER));
}
}
}
GPSListener.java :
GPSListener.java :
public class GPSListener implements LocationListener {
private Activity activity;
private LocationManager lm;
private int numberOfUpdates;
public static final int MAX_NUMBER_OF_UPDATES = 10;
public GPSListener(Activity activity, LocationManager lm) {
this.activity = activity;
this.lm = lm;
}
@Override
public void onLocationChanged(Location loc) {
if (numberOfUpdates < MAX_NUMBER_OF_UPDATES) {
numberOfUpdates++;
Log.w("LAT", String.valueOf(loc.getLatitude()));
Log.w("LONG", String.valueOf(loc.getLongitude()));
Log.w("ACCURACY", String.valueOf(loc.getAccuracy() + " m"));
Log.w("PROVIDER", String.valueOf(loc.getProvider()));
Log.w("SPEED", String.valueOf(loc.getSpeed() + " m/s"));
Log.w("ALTITUDE", String.valueOf(loc.getAltitude()));
Log.w("BEARING", String.valueOf(loc.getBearing() + " degrees east of true north"));
String message;
if (loc != null) {
message = "Current location is: Latitude = "
+ loc.getLatitude() + ", Longitude = "
+ loc.getLongitude();
// lm.removeUpdates(this);
} else
message = "Location null";
Toast.makeText(activity, message, Toast.LENGTH_SHORT).show();
} else {
lm.removeUpdates(this);
}
}
@Override
public void onProviderDisabled(String provider) {
Toast.makeText(activity, "Gps Disabled", Toast.LENGTH_SHORT).show();
}
@Override
public void onProviderEnabled(String provider) {
Toast.makeText(activity, "Gps Enabled", Toast.LENGTH_SHORT).show();
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
}
And then from your activity :
然后从您的活动中:
GPSManager gps = new GPSManager(
yourActivity.this);
gps.start();
回答by Bucks
I done that by using simple function but without displaying an alert box i redirected usercontrol to setting page
我通过使用简单的功能来做到这一点,但没有显示警告框,我将用户控件重定向到设置页面
Here is the function i used
这是我使用的功能
public void isGPSEnable(){
LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
boolean enabled = service
.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!enabled) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
}
回答by Deepak Gupta
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
final String action = Settings.ACTION_LOCATION_SOURCE_SETTINGS;
final String message = "your message";
builder.setMessage(message)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int id) {
getActivity().startActivity(new Intent(action));
d.dismiss();
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface d, int id) {
d.cancel();
}
});
builder.create().show();
回答by Mabrouki Fakhri
(sorry for my english) I was shearing for a solution when i saw your question and your question give the answer.
(对不起我的英语)当我看到你的问题并且你的问题给出了答案时,我正在寻找解决方案。
The problem is that the activity continue the launching while the dialog alert is open, and when the user press "YES" a new activity will start "Settings of gps.." when the user back to the first activity after setting ON his gps or just ignored you, this same activity will not do any update or consider that something (like gps on) has happen because it's already loaded, so you have to listen to the updates and apply changes or just restart the activity when the user "back" , for me i just added :
问题是活动在对话框警报打开时继续启动,当用户按下“是”时,当用户在设置了他的 gps 后返回第一个活动时,一个新活动将启动“gps 设置 ..”或只是忽略了你,同样的活动不会做任何更新或认为已经发生了某些事情(例如 GPS 开启),因为它已经加载,所以你必须听取更新并应用更改,或者在用户“返回”时重新启动活动,对我来说,我刚刚补充说:
<activity
...
android:noHistory="true"
... /> </activity>
now, everytime the user press the "Back button" your activity will restart considering the new updates it worked for me, hope that this can help you or helpl anyone else
现在,每次用户按下“返回按钮”时,您的活动都会重新启动,考虑到它对我有用的新更新,希望这可以帮助您或帮助其他人