使用GPS定位技术

3
在启动活动时,GPS被启用,并获取用户的纬度、经度并将其作为Geopoint报告给解析。问题在于,GPS持续在后台运行,并不断向Parse报告位置。我只希望GPS获取位置信息一次,然后立即停止,因为我自己已经注意到,在一天内使用了大约20k个Parse请求,我认为这是因为它在后台持续运行。以下是活动代码:
public class MoodActivity extends Activity {

    private FeedbackDialog feedBack;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mood);
        feedBack = new FeedbackDialog(this, "");
         LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
           LocationListener mlocListener = new MyLocationListener();

           mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener);







        final TextView teating = (TextView) this.findViewById(R.id.tdinning);
        teating.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                MoodActivity.this.startActivity(new Intent(MoodActivity.this, CasualEventsActivity.class));
            }
        });

        final ImageView ieating = (ImageView) this.findViewById(R.id.idinning);
        ieating.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                MoodActivity.this.startActivity(new Intent(MoodActivity.this, CasualEventsActivity.class));
            }
        });

        final TextView tdrinks = (TextView) this.findViewById(R.id.tcasual);
        tdrinks.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                MoodActivity.this.startActivity(new Intent(MoodActivity.this, CasualEventsActivity.class));
            }
        });

        final ImageView idrinks = (ImageView) this.findViewById(R.id.icasual);
        idrinks.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                MoodActivity.this.startActivity(new Intent(MoodActivity.this, CasualEventsActivity.class));
            }
        });

        final TextView tshows = (TextView) this.findViewById(R.id.tshows);
        tshows.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                MoodActivity.this.startActivity(new Intent(MoodActivity.this, EntertainmentEventsActivity.class));
            }
        });

        final ImageView ishows = (ImageView) this.findViewById(R.id.ishows);
        ishows.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                MoodActivity.this.startActivity(new Intent(MoodActivity.this, EntertainmentEventsActivity.class));
            }
        });

        final TextView tarts = (TextView) this.findViewById(R.id.tculture);
        tarts.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                MoodActivity.this.startActivity(new Intent(MoodActivity.this, CultureEventsActivity.class));
            }
        });

        final ImageView iarts = (ImageView) this.findViewById(R.id.iculture);
        iarts.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                MoodActivity.this.startActivity(new Intent(MoodActivity.this, CultureEventsActivity.class));
            }
        });

        final Button viewall = (Button) this.findViewById(R.id.brandom);
        viewall.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                MoodActivity.this.startActivity(new Intent(MoodActivity.this, CasualEventsActivity.class));
            }
        });
    }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main_activity_actions, menu);
        getActionBar().setDisplayShowTitleEnabled(false);



        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle presses on the action bar items
        switch (item.getItemId()) {
            case R.id.pageExperience:
                openPageExperience();
                return true;
            case R.id.pageMessaging:
                openPageMessage();
                return true;

            case R.id.pageEventsBooking:
                openPageBook();
                return true;

            case R.id.pageProfile:
                openPageProfile();
                return true;

            case R.id.pageReport:
                openPageReport();
                return true;

            case R.id.pageAbout:
                openPageAbout();
                return true;

            case R.id.pageLogout:
                openPageLogout();
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void openPageLogout() {
        // TODO Auto-generated method stub
        //Now call logout
        ParseUser.logOut();
        Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
        startActivity(intent);
    }



    private void openPageAbout() {
        // TODO Auto-generated method stub

    }

    private void openPageReport() {
        // TODO Auto-generated method stub
        FeedbackSettings feedbackSettings = new FeedbackSettings();

        //SUBMIT-CANCEL BUTTONS
        feedbackSettings.setCancelButtonText("No");
        feedbackSettings.setSendButtonText("Send");

        //DIALOG TEXT
        feedbackSettings.setText("Hey, would you like to give us some feedback so that we can improve your experience?");
        feedbackSettings.setYourComments("Type your question here...");
        feedbackSettings.setTitle("Feedback Dialog Title");

        //TOAST MESSAGE
        feedbackSettings.setToast("Thank you so much!");
        feedbackSettings.setToastDuration(Toast.LENGTH_SHORT);  // Default
        feedbackSettings.setToastDuration(Toast.LENGTH_LONG);

        //RADIO BUTTONS
        feedbackSettings.setRadioButtons(false); // Disables radio buttons
        feedbackSettings.setBugLabel("Bug");
        feedbackSettings.setIdeaLabel("Idea");
        feedbackSettings.setQuestionLabel("Question");

        //RADIO BUTTONS ORIENTATION AND GRAVITY
        feedbackSettings.setOrientation(LinearLayout.HORIZONTAL); // Default
        feedbackSettings.setOrientation(LinearLayout.VERTICAL);
        feedbackSettings.setGravity(Gravity.RIGHT); // Default
        feedbackSettings.setGravity(Gravity.LEFT);
        feedbackSettings.setGravity(Gravity.CENTER);

        //SET DIALOG MODAL
        feedbackSettings.setModal(true); //Default is false

        //DEVELOPER REPLIES
        feedbackSettings.setReplyTitle("Message from the Developer");
        feedbackSettings.setReplyCloseButtonText("Close");
        feedbackSettings.setReplyRateButtonText("RATE!");

        //DEVELOPER CUSTOM MESSAGE (NOT SEEN BY THE END USER)
        feedbackSettings.setDeveloperMessage("This is a custom message that will only be seen by the developer!");
        feedBack.show();
    }

    private void openPageProfile() {
        // TODO Auto-generated method stub
        Intent intent = new Intent(this, profileDetailsActivity.class);
        startActivity(intent);

    }

    private void openPageBook() {
        // TODO Auto-generated method stub

    }

    private void openPageMessage() {
        // TODO Auto-generated method stub

    }

    private void openPageExperience() {
        // TODO Auto-generated method stub
        Intent intent = new Intent(this, MoodActivity.class);
        startActivity(intent);
    }

    public class MyLocationListener implements LocationListener {

        @Override
        public void onLocationChanged(Location loc) {
            // TODO Auto-generated method stub
            double lati = loc.getLatitude();
            double longi = loc.getLongitude();

            ParseUser currentUser = ParseUser.getCurrentUser();
            currentUser.saveInBackground();

            ParseGeoPoint point = new ParseGeoPoint(lati, longi);
            currentUser.put("location", point);

            currentUser.saveInBackground(new SaveCallback() {
                @Override
                public void done(ParseException e) {
                    setProgressBarIndeterminateVisibility(false);

                    if (e == null) {
                        // Success!

                    } else {

                    }
                }
            });

        }

           @Override
           public void onProviderDisabled(String provider) {
               // TODO Auto-generated method stub
               Toast.makeText(getApplicationContext(),"Gps Disabled",Toast.LENGTH_SHORT).show();

           }

           @Override
           public void onProviderEnabled(String provider) {
               // TODO Auto-generated method stub
               Toast.makeText(getApplicationContext(),"Gps Enabled",Toast.LENGTH_SHORT).show();


           }

           @Override
           public void onStatusChanged(String provider, int status, Bundle extras) {
               // TODO Auto-generated method stub

           }
          }
}

如果您需要任何澄清,请告诉我。 提前致谢。
更新: 我已经尝试使用单个更新,但似乎不起作用。
在onCreate下。
LocationManager mlocManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
           LocationListener mlocListener = new MyLocationListener();


           mlocManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, mlocListener, Looper.myLooper());

并且

    public class MyLocationListener implements LocationListener {

        @Override
        public void onLocationChanged(Location loc) {
            // TODO Auto-generated method stub
            double lati = loc.getLatitude();
            double longi = loc.getLongitude();

            ParseUser currentUser = ParseUser.getCurrentUser();
            currentUser.saveInBackground();

            ParseGeoPoint point = new ParseGeoPoint(lati, longi);
            currentUser.put("location", point);

            currentUser.saveInBackground(new SaveCallback() {
                @Override
                public void done(ParseException e) {
                    setProgressBarIndeterminateVisibility(false);

                    if (e == null) {
                        // Success!

                    } else {

                    }
                }
            });

        }

           @Override
           public void onProviderDisabled(String provider) {
               // TODO Auto-generated method stub
               Toast.makeText(getApplicationContext(),"Gps Disabled",Toast.LENGTH_SHORT).show();

           }

           @Override
           public void onProviderEnabled(String provider) {
               // TODO Auto-generated method stub
               Toast.makeText(getApplicationContext(),"Gps Enabled",Toast.LENGTH_SHORT).show();


           }

           @Override
           public void onStatusChanged(String provider, int status, Bundle extras) {
               // TODO Auto-generated method stub

           }
          }
}
3个回答

2
你需要找到一种方法来移除更新,例如:
mlocManager.removeUpdates(mlocListener);

在您发送解析信息之后


谢谢您的回复。我可以绕过那段代码。我应该在onCreate下面添加它吗?mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mlocListener); - code_legend
1
不,我的做法是让我的活动实现LocationListener并在类级别上公开LocationManager,然后在同一类中完成工作,并在onLocationChanged中放置removeupdates,在解析工作之后。 - JRowan
嗨,我注意到removeUpdates存在一个问题,它只获取一次位置,这正是我想要的。我的意思是每次有人启动应用程序时,它会记录其新位置一次,并且每30分钟更新一次位置(因为假设该人从未关闭应用程序并且正在进行公路旅行),而不是连续更新。 - code_legend

1
除了@JRowan所说的之外,您还可以使用:

String provider = LocationManager.getBestProvider(new Criteria(), true);
Location myLocation = LocationManager.getLastKnowLocation(provider);

如果您的位置定时不需要非常精确,也就是说,如果您可以接受位置数据有些过时。

方法链接


感谢您的迅速回复。除了添加建议的代码行外,我需要删除任何代码行吗? - code_legend
使用此代码,您实际上不需要更改任何内容。您只需使用myLocation而不是在onLocationReceived中获取位置即可。对于@JRowan的答案,您需要在完成接收信息并安全存储所有内容后调用removeUpdates - nem035
你好,我注意到removeUpdates的一个问题是它只获取位置一次,这正是我想要的。我的意思是每当有人启动应用程序时,它会记录其新位置一次,并且每30分钟更新一次位置(因为假设此人从未关闭应用程序并处于公路旅行中),而不是连续不断地更新。 - code_legend

1
当您调用LocationManager.requestLocationUpdates()时,系统将通过该调用中提供的LocationListener持续提供位置更新。
如果您只想获取一个位置更新,则有两种选择:
1. 使用LocationManager.requestSingleUpdate() 2. 使用LocationManager.requestLocationUpdates(),但在接收到第一个更新后取消更新。
我将选择第二种,因为您已经有了一些代码。您需要先声明您的变量mLocManager为类字段,而不是在onCreate()中局部声明。然后您需要在您的LocationListener中添加以下代码。
    public class MyLocationListener implements LocationListener {

        @Override
        public void onLocationChanged(Location loc) {

            double lati = loc.getLatitude();
            double longi = loc.getLongitude();

            mlocManager.remoteUpdates(this); // ADD THIS STATEMENT

            // The rest of your code goes here ...

        }

   }

1
@user3907211:很难说requestSingleUpdate()有什么问题。requestLocationUpdates()可以工作吗?你确定你有GPS / WiFi连接吗? - stackoverflowuser2010
1
@user3907211:你可以同时从两个提供者(GPS和网络)获取地理坐标。请参考这个问题:https://dev59.com/e2445IYBdhLWcg3w_PK3 - stackoverflowuser2010
1
@user3907211:要每30分钟获取一次位置,有两种方法。(1)在调用requestLocationUpdates()时,您可以设置minTime参数。请注意,它是以毫秒为单位的。(2)您可以使用单独的OS定时器调用来安排从现在开始30分钟的requestLocationUpdate。当找到地理坐标时,您可以取消requestLocationUpdate,然后设置另一个定时器。请参见:https://dev59.com/a3A75IYBdhLWcg3w186G - stackoverflowuser2010
1
据我理解,网络供应商要求有互联网连接。该供应商获取手机基站和Wi-Fi基站信号,将其发送到谷歌,然后得到地理位置信息。详见:http://blog.shinetech.com/2011/10/14/a-good-look-at-android-location-data/ - stackoverflowuser2010
1
如果用户已启用 Wi-Fi(这与具有网络连接不同),我通常会显示一个 Toast 消息,提示“请启用 WiFi 以提高位置精度”。另请参阅:https://dev59.com/QnA75IYBdhLWcg3wuLjD - stackoverflowuser2010
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接