简体   繁体   English

我想在启动后从另一个服务调用服务方法,但我不知道如何创建服务的对象

[英]I want to call service method from another service after boot but I don't know how to make an object of the service

I'm starting a service when device boots & from that service I want to call method of another service to start fetching location again. 我正在启动服务,当设备启动并从该服务我想调用另一个服务的方法再次开始获取位置。 i started another service called from the service called when boot completed here i started the service but i want to call the method of another service 我启动了另一个从服务调用的服务,当启动完成时,我启动了服务,但我想调用另一个服务的方法

This is BootService called when device boot 这是在设备启动时调用的BootService

public int onStartCommand(Intent intent, int flags, int startId) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        startForegroundService(new 
    Intent(this,LocationUpdatesService.class));
    } 
    else {
            startService(new Intent(this, LocationUpdatesService.class));
        }
        Log.d("rez","running ok");
        return START_NOT_STICKY;
     }

This is the LocationUpdatesService which i want to call 这是我想要调用的LocationUpdatesService

public class LocationUpdatesService extends Service {
    String dateTIme;
    private static final String PACKAGE_NAME =   "com.google.android.gms.location.sample.locationupdatesforegroundservice";
    private static final String TAG = "resPOINT";
    private static final String CHANNEL_ID = "channel_01";
    static final String ACTION_BROADCAST = PACKAGE_NAME + ".broadcast";
    static final String EXTRA_LOCATION = PACKAGE_NAME + ".location";
    private static final String EXTRA_STARTED_FROM_NOTIFICATION = PACKAGE_NAME +
            ".started_from_notification";
    private final IBinder mBinder = new LocalBinder();
    private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 1000 * 10;
    private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
            UPDATE_INTERVAL_IN_MILLISECONDS / 2;
    private boolean mChangingConfiguration = false;
    private NotificationManager mNotificationManager;
    private LocationRequest mLocationRequest;
    private FusedLocationProviderClient mFusedLocationClient;
    private LocationCallback mLocationCallback;
    private Handler mServiceHandler;
    Double latitude, longitude;
    GeoFire geoFire;
    FirebaseFirestore db;

    public LocationUpdatesService() {
    }
    @Override
    public void onCreate() {
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);

        mLocationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                super.onLocationResult(locationResult);
                onNewLocation(locationResult.getLastLocation());
            }
        };

        createLocationRequest();
        getLastLocation();

        HandlerThread handlerThread = new HandlerThread(TAG);
        handlerThread.start();
        mServiceHandler = new Handler(handlerThread.getLooper());
        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            CharSequence name = getString(R.string.app_name);
            NotificationChannel mChannel =
                    new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT);

            mNotificationManager.createNotificationChannel(mChannel);
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        boolean startedFromNotification = intent.getBooleanExtra(EXTRA_STARTED_FROM_NOTIFICATION,
                false);

        if (startedFromNotification) {
            removeLocationUpdates();
            stopSelf();
        }     
        return START_NOT_STICKY;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mChangingConfiguration = true;
    }


    @SuppressWarnings("deprecation")
    @Override
    public IBinder onBind(Intent intent) {
        // Called when a client (MainActivity in case of this sample) comes to the foreground
        // and binds with this service. The service should cease to be a foreground service
        // when that happens.
        stopForeground(true);
        mChangingConfiguration = false;

        // Register Firestore when service will restart
        db = FirebaseFirestore.getInstance();
        return mBinder;
    }


    @SuppressWarnings("deprecation")
    @Override
    public void onRebind(Intent intent) {
        // Called when a client (MainActivity in case of this sample) returns to the foreground
        // and binds once again with this service. The service should cease to be a foreground
        // service when that happens.
        stopForeground(true);
        mChangingConfiguration = false;

        // Register Firestore when service will restart
        db = FirebaseFirestore.getInstance();
        super.onRebind(intent);
    }


    @SuppressWarnings("deprecation")
    @Override
    public boolean onUnbind(Intent intent) {
        // Called when the last client (MainActivity in case of this sample) unbinds from this
        // service. If this method is called due to a configuration change in MainActivity, we
        // do nothing. Otherwise, we make this service a foreground service.
        if (!mChangingConfiguration && Utils.requestingLocationUpdates(this)) {
            /*
            if (Build.VERSION.SDK_INT == Build.VERSION_CODES.O) {
                mNotificationManager.startServiceInForeground(new Intent(this,
                        LocationUpdatesService.class), NOTIFICATION_ID, getNotification());
            } else {
                startForeground(NOTIFICATION_ID, getNotification());
            }
             */

            startForeground(NOTIFICATION_ID, getNotification());
        }
        return true; // Ensures onRebind() is called when a client re-binds.
    }



    @SuppressWarnings("deprecation")
    @Override
    public void onDestroy() {
        mServiceHandler.removeCallbacksAndMessages(null);
    }

    public void requestLocationUpdates() {
        Utils.setRequestingLocationUpdates(this, true);
        startService(new Intent(getApplicationContext(), LocationUpdatesService.class));
        try {
            mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                    mLocationCallback, Looper.myLooper());
        } catch (SecurityException unlikely) {
            //no location permission
            Utils.setRequestingLocationUpdates(this, false);
        }
    }

    /** Removes location updates. Note that in this sample we merely log the */
    public void removeLocationUpdates() {
        try {
            mFusedLocationClient.removeLocationUpdates(mLocationCallback);
            Utils.setRequestingLocationUpdates(this, false);
            stopSelf();
        } catch (SecurityException unlikely) {
            Utils.setRequestingLocationUpdates(this, true);
            //Lost location permission. Could not remove updates
        }
    }

    /** Returns the {@link NotificationCompat} used as part of the foreground service. */
    private Notification getNotification() {
        Intent intent = new Intent(this, LocationUpdatesService.class);

        CharSequence text = Utils.getLocationText(mLocation);

        // Extra to help us figure out if we arrived in onStartCommand via the notification or not.
        intent.putExtra(EXTRA_STARTED_FROM_NOTIFICATION, true);

        // The PendingIntent that leads to a call to onStartCommand() in this service.
        /*PendingIntent servicePendingIntent = PendingIntent.getService(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);*/
        // The PendingIntent to launch activity.
        /*PendingIntent activityPendingIntent = PendingIntent.getActivity(this, 0,
                new Intent(this, MainActivity.class), 0);*/

        dateTIme = Utils.getLocationTitle(this);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                /*.addAction(R.drawable.ic_launch, getString(R.string.launch_activity),
                        activityPendingIntent)
                .addAction(R.drawable.ic_cancel, getString(R.string.remove_location_updates),
                        servicePendingIntent)*/
                .setContentText(text)
                .setContentTitle(dateTIme)
                .setOngoing(true)
                .setPriority(Notification.PRIORITY_HIGH)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setTicker(text)
                .setWhen(System.currentTimeMillis());

        // Set the Channel ID for Android O.
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId(CHANNEL_ID); // Channel ID
        }

        return builder.build();
    }

    private void getLastLocation() {
        try {
            mFusedLocationClient.getLastLocation()
                    .addOnCompleteListener(new OnCompleteListener<Location>() {
                        @Override
                        public void onComplete(@NonNull Task<Location> task) {
                            if (task.isSuccessful() && task.getResult() != null) {
                                mLocation = task.getResult();
                            }
                        }
                    });
        } catch (SecurityException unlikely) {
            //no loc permission
        }
    }

    private void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    }

    /**
     * Class used for the client Binder.  Since this service runs in the same process as its
     * clients, we don't need to deal with IPC.
     */
    public class LocalBinder extends Binder {
        LocationUpdatesService getService() {
            return LocationUpdatesService.this;
        }
    }

    /**
     * Returns true if this is a foreground service.
     *
     * @param context The {@link Context}.
     */
    public boolean serviceIsRunningInForeground(Context context) {
        ActivityManager manager = (ActivityManager) context.getSystemService(
                Context.ACTIVITY_SERVICE);
        for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(
                Integer.MAX_VALUE)) {
            if (getClass().getName().equals(service.service.getClassName())) {
                if (service.foreground) {
                    return true;
                }
            }
        }
        return false;
    }

    private void onNewLocation(Location location) {
        mLocation = location;

        // Notify anyone listening for broadcasts about the new location.
        Intent intent = new Intent(ACTION_BROADCAST);
        intent.putExtra(EXTRA_LOCATION, location);
        LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);

        // Update notification content if running as a foreground service.
        if (serviceIsRunningInForeground(this)) {
            mNotificationManager.notify(NOTIFICATION_ID, getNotification());

            // Getting location when notification was call.
            latitude = location.getLatitude();
            longitude = location.getLongitude();

            // Here using to call Save to serverMethod
            SavetoServer();
        }
    }

    /** Save a value in realtime to firestore when user in background*/

    private void SavetoServer(){
        FirebaseFirestoreSettings settings = new FirebaseFirestoreSettings.Builder()
                .setPersistenceEnabled(true)
                .setCacheSizeBytes(FirebaseFirestoreSettings.CACHE_SIZE_UNLIMITED)
                .build();
        db.setFirestoreSettings(settings);
        //rez save data in cloud
        Map<String , Object> victim = new HashMap<>();
        victim.put("LatLong" , latitude+", "+longitude);
        victim.put("DateTime" , dateTIme);

        db.collection("Rahul")
                .document("Victim1")
                .collection("Location")
                .add(victim);
    }
}

The LocationUpdatesService should run specific method itself. LocationUpdatesService应该自己运行特定的方法。 You can include some bundle values in the Intent to specify which method you want to run (if several avilable and you want to differentiate them) and pass parameters(if required). 您可以在Intent包含一些包值,以指定要运行的方法(如果有几个可用,并且您希望区分它们)并传递参数(如果需要)。

So, for example: 所以,例如:

  1. In service from the snippet: 从代码片段服务:
Intent intent = Intent(this,LocationUpdatesService.class));
intent.setAction("my_method_1");
intent.putExtra("ARGUMENT_FOR_METHOD_1", 12345L);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    startForegroundService(intent);
} else {
    startService(intent);
}
  1. In LocationUpdatesService : LocationUpdatesService
public int onStartCommand(Intent intent, int flags, int startId) {
  String action = intent.getAction();
  if ("my_method_1".equals(action)) {
     myMethod1(intent.getLong("ARGUMENT_FOR_METHOD_1", 0L));
  } /// and so on
}

Notes: 笔记:

  • In code above, I used Action to specify method and add Long extra 在上面的代码中,我使用Action来指定方法并添加Long extra
  • I suppose, LocationUpdatesService extends Service 我想, LocationUpdatesService扩展了Service

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何以“意图”从另一个服务方法调用服务方法? - How to call a service method from another service method with "intent"? MVVM-改造服务类,我不知道,此方法是什么意思 - Mvvm - retrofit service class, I don't know, what this method mean 如何从另一个服务调用AccessibilityService方法? - How call a AccessibilityService method from another service? 我想调用一个stock.setPrice()方法,但我不知道如何 - I want to call a stock.setPrice() method but I don't know how 如何从另一个方法将@FormParam传递给RESTful服务? - How can I pass an @FormParam to a RESTful service from another method? 如何从spring boot服务层调用java类方法 - How to call a java class method from spring boot service layer 如何从另一个Web服务调用一个Web服务(在同一个WAR中) - How can I call one web-service from another web-service (within in the same WAR) 我可以绑定到其他服务的服务吗? - Can I bind to a service from another service? 我可以在 Spring Boot 中从服务中显式调用自定义验证器吗? - Can I explicitly call custom validator from service in Spring Boot? Spring Boot - 如何仅通过提供的服务类名称从服务类调用方法? - Spring Boot - How to call method from a service class just by the provided service class name?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM