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

标签 java android service background broadcastreceiver

当设备启动时我正在启动一项服务,并且我想从该服务调用另一个服务的方法以再次开始获取位置。 我启动了另一个服务,该服务是从启动完成时调用的服务调用的,这里我启动了该服务,但我想调用另一个服务的方法

这是设备启动时调用的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;
     }

这是我要调用的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);
    }
}

最佳答案

LocationUpdatesService 本身应该运行特定的方法。您可以在 Intent 中包含一些 bundle 值,以指定要运行的方法(如果有多个可用并且您想要区分它们)并传递参数(如果需要)。

例如:

  1. 代码 fragment 中的服务:
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);
}
  • 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
    }
    

    注释:

    • 在上面的代码中,我使用 Action 来指定方法并添加 Long 额外
    • 我想,LocationUpdatesService 扩展了 Service

    关于java - 我想在启动后从另一个服务调用服务方法,但我不知道如何创建该服务的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56201314/

    相关文章:

    java - 创建连接时抛出 SQLException。

    java 命令行 类 IllegalAcessError

    android - 是否有任何 API 或方法可以在您的应用程序中获取 whatsapp 聊天消息

    java - 短信应用程序 - List_item 错误

    c++ - 有没有办法从服务中运行可执行文件?

    Java Gson : Deserializing complex JSON string

    java - 通过使用 java Field getType() 方法进行转换,将对象从一种类型转换为另一种类型

    c++ - QtService 无法启动

    Java/安卓 : Reading/writing a byte array over a socket

    java - 获取 Android 手机上的用户行为(应用历史、浏览历史等)