当前位置: 首页 > 知识库问答 >
问题:

位置服务和主活动之间的通信

钱欣然
2023-03-14

你好,Stackoverflow社区,我是android新手,正在学习如何实现基于位置的服务<我成功地实现了一个速度计应用程序,它可以测量当前速度、总距离和总行驶时间。

现在,我想添加一个附加功能,如果速度增加40公里/小时,我会打开图片并使用前置摄像头拍照。

我对实现这一点感到困惑,因为location是作为一个单独的LocationService类提供的。我看了很多例子,但我无法将其应用到我的代码中。

我尝试使用Intent将速度变量传递回主活动,但无法继续,因为我的速度变量会不断变化。

我还尝试为textfield放置一个监听器,以便监视它,但效率很低。

这是我的MainActivity.java

package com.example.location;

public class MainActivity extends AppCompatActivity {

    LocationService myService;
    static boolean status;
    LocationManager locationManager;
    static TextView dist, time, speed, satellite;
    Button start, pause, stop;
    static long startTime, endTime;
    static ImageView image,imageView;
    static ProgressDialog locate;
    static int p = 0;
    private static final int REQUEST_CODE_PERMISSION = 2;
    String mPermission = Manifest.permission.ACCESS_FINE_LOCATION;

    private Uri file;

    private ServiceConnection sc = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            LocationService.LocalBinder binder = (LocationService.LocalBinder) service;
            myService = binder.getService();
            status = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            status = false;
        }
    };

    void bindService() {
        if (status == true)
            return;
        Intent i = new Intent(getApplicationContext(), LocationService.class);
        bindService(i, sc, BIND_AUTO_CREATE);
        status = true;
        startTime = System.currentTimeMillis();
    }

    void unbindService() {
        if (status == false)
            return;
        Intent i = new Intent(getApplicationContext(), LocationService.class);
        unbindService(sc);
        status = false;
    }

    @Override
    protected void onResume() {
        super.onResume();

    }

    @Override
    protected void onStart() {
        super.onStart();

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (status == true)
            unbindService();
    }

    @Override
    public void onBackPressed() {
        if (status == false)
            super.onBackPressed();
        else
            moveTaskToBack(true);
    }


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        dist = (TextView) findViewById(R.id.distancetext);
        time = (TextView) findViewById(R.id.timetext);
        speed = (TextView) findViewById(R.id.speedtext);

        start = (Button) findViewById(R.id.start);
        pause = (Button) findViewById(R.id.pause);
        stop = (Button) findViewById(R.id.stop);

        image = (ImageView) findViewById(R.id.image);


        imageView = (ImageView)this.findViewById(R.id.imageView1);


        start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                //The method below checks if Location is enabled on device or not. If not, then an alert dialog box appears with option
                //to enable gps.

                if (checkGPS() == false){
                    requestGPS();

                }

                requestcamera();
                locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

                if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {

                    return;
                }

                if (status == false)
                    //Here, the Location Service gets bound and the GPS Speedometer gets Active.
                    bindService();
                locate = new ProgressDialog(MainActivity.this);
                locate.setIndeterminate(true);
                locate.setCancelable(false);
                locate.setMessage("Getting Location...");
                locate.show();
                start.setVisibility(View.GONE);
                pause.setVisibility(View.VISIBLE);
                pause.setText("Pause");
                stop.setVisibility(View.VISIBLE);


            }
        });

        pause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (pause.getText().toString().equalsIgnoreCase("pause")) {
                    pause.setText("Resume");
                    p = 1;

                } else if (pause.getText().toString().equalsIgnoreCase("Resume")) {
                    if (checkGPS() == false){
                        requestGPS();
                    }
                    locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
                    if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                        //Toast.makeText(this, "GPS is Enabled in your devide", Toast.LENGTH_SHORT).show();
                        return;
                    }
                    pause.setText("Pause");
                    p = 0;

                }
            }
        });


        stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (status == true)
                    unbindService();
                start.setVisibility(View.VISIBLE);
                pause.setText("Pause");
                pause.setVisibility(View.GONE);
                stop.setVisibility(View.GONE);
                p = 0;
            }
        });

    }





    private boolean checkGPS() {
        int result = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);

        //If permission is granted returning true
        if (result == PackageManager.PERMISSION_GRANTED)
            return true;

        //If permission is not granted returning false
        return false;
    }

    private void requestcamera(){
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);
        }
    }

    private void requestGPS() {
        ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION);
        if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
                (MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION);

        }
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            showGPSDisabledAlertToUser();

        }

    }

    private void showGPSDisabledAlertToUser() {
        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
        alertDialogBuilder.setMessage("Enable GPS to use application")
                .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);
                                startActivity(callGPSSettingIntent);
                            }
                        });
        alertDialogBuilder.setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                    }
                });
        AlertDialog alert = alertDialogBuilder.create();
        alert.show();
    }





}

这是我的定位服务。Java语言


public class LocationService extends Service implements
        LocationListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    private static final long INTERVAL = 1000 * 2;
    private static final long FASTEST_INTERVAL = 1000 * 1;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    Location mCurrentLocation, lStart, lEnd;
    static double distance = 0;
    double speed;
    int data;
    private static final int CAMERA_REQUEST = 1888;

    private static final int MY_CAMERA_PERMISSION_CODE = 100;

    private final IBinder mBinder = new LocalBinder();

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        createLocationRequest();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        mGoogleApiClient.connect();
        return mBinder;
    }

    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return super.onStartCommand(intent, flags, startId);
    }


    @Override
    public void onConnected(Bundle bundle) {
        try {
            LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, this);
        } catch (SecurityException e) {
        }
    }


    protected void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient, this);
        distance = 0;
    }


    @Override
    public void onConnectionSuspended(int i) {

    }


    @Override
    public void onLocationChanged(Location location) {
        MainActivity.locate.dismiss();
        mCurrentLocation = location;
        if (lStart == null) {
            lStart = mCurrentLocation;
            lEnd = mCurrentLocation;
        } else
            lEnd = mCurrentLocation;


        //Calling the method below updates the  live values of distance and speed to the TextViews.
        speed = location.getSpeed() * 18 / 5;
        updateUI();





    }





    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    public class LocalBinder extends Binder {

        public LocationService getService() {
            return LocationService.this;
        }


    }

    //The live feed of Distance and Speed are being set in the method below .
    private void updateUI() {
        if (MainActivity.p == 0) {
            distance = distance + (lStart.distanceTo(lEnd) / 1000.00);
            MainActivity.endTime = System.currentTimeMillis();
            long diff = MainActivity.endTime - MainActivity.startTime;
            diff = TimeUnit.MILLISECONDS.toMinutes(diff);
            MainActivity.time.setText("Total Time: " + diff + " minutes");
            if (speed > 0.0)
                MainActivity.speed.setText("Current speed: " + new DecimalFormat("#.##").format(speed) + " km/hr");
            else
                MainActivity.speed.setText(".......");

            MainActivity.dist.setText(new DecimalFormat("#.###").format(distance) + " Km's.");
            MainActivity.satellite.setText(" Satellites in use: "+ data);

            lStart = lEnd;

        }

    }


    @Override
    public boolean onUnbind(Intent intent) {
        stopLocationUpdates();
        if (mGoogleApiClient.isConnected())
            mGoogleApiClient.disconnect();
        lStart = null;
        lEnd = null;
        distance = 0;
        return super.onUnbind(intent);
    }
}

任何想法都将不胜感激。

共有1个答案

呼延鸿畅
2023-03-14

我认为您应该在您的服务类中持有一个IBinderMessengerHandler实例,以便能够通过verce与活动进行通信

我建议你读一下这个博客,以便更好地理解。

https://medium.com/@ankit\u aggarwal/ways-to-Communication-between-activity-and-service-6a8f07275297

 类似资料:
  • 我们在ELB日志中看到504个错误,但是在应用程序日志中没有相应的错误。增加了ELB上的空闲超时,可以看到没有任何请求比这更花时间。查看aws留档发现,我们需要将ec2实例的保活时间配置为等于或大于空闲超时,以保持elb和后端服务器之间的连接打开。找不到任何方法来配置elb和后端服务器之间的保活时间。任何这样做的建议都会有帮助 我们使用tomcat ebs作为后端服务器。

  • 我在一个活动和一个服务(位于另一个应用程序中)之间创建了一个通信。当我的服务从活动得到一个调用时,它会生成一个新线程来执行一个任务。通常情况下,完成这个任务需要3秒。 当来自活动的消息来到服务时,我们持有它。并检查此消息的replyTo是否为空。replyTo不为空。(行) 当任务完成时,它通知承载它的类。它将调用方法更新。在handleMessage方法中,replyTo不为空。但是,3秒后,在

  • 单击通知、服务创建新活动和活动创建新服务? 我的应用MainActivity“OnCreate”创建一个“粘性”的服务。 在我的服务中,当有一些通知时,我会发布多个通知。除非用户进入应用程序并阅读通知,否则通知将在那里。在onStartCommand中检查新通知。 按下通知将发送打开MainActivity的意图。 有服务、主要活动和通知。 一段时间后,MainActivity被系统杀死。 单击通

  • 我正在设置一个带有API网关(KONG)和微服务(Spring Boot应用程序)的环境,但我对它们之间的SSL通信有很多疑问/担忧。 我应该将SSL设置放在API网关还是微服务上? 目前,我的微服务应用程序有自己的SSL证书,它通过8443端口在容器中运行。 但是现在实现API网关,我不确定是否必须将其从我的微服务中删除并在API网关中设置,或者将其添加到两者中。 我希望我的微服务和API网关之

  • 问题内容: 简而言之,我有一个独立的ES主实例和一个在我的Java应用程序中创建的客户端节点。如果在客户端节点之前启动了独立ES实例,则客户端节点会正确发现独立ES实例。 我面临的问题是-如果由于某种原因,客户端节点在独立ES实例之前启动,我会看到“ MasterNotDiscoveredException”,这也是可预期的。但是,即使启动独立的ES实例后,我仍然会看到相同的异常。我应该更改一些配

  • 我正在构建一个基于Spring云的微服务ML管道。我有一个数据摄取服务,它(当前)从SQL接收数据,这些数据需要被预测服务使用。 普遍的共识是写入应该使用kafka/Rabbitmq使用基于异步消息的通信。 我不确定的是如何编排这些服务? 我是否应该使用API网关来调用启动管道的摄取?