问:
Custom model binding through body in ASP.Net Core
I would like to bind an object in a controller through the body of a HTTP Post.

It works like this

```<code>public class MyModelBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
                throw new ArgumentNullException("No context found");

            string modelName = bindingContext.ModelName;
            if (String.IsNullOrEmpty(modelName)) {
                bindingContext.Result = ModelBindingResult.Failed();
                return Task.CompletedTask;
            }

            string value = bindingContext.ValueProvider.GetValue(modelName).FirstValue;
...
</code>```

The modelName is viewModel (honestly, I don't know why, but it works...)

My controller looks like this

```<code>    [HttpPost]
    [Route("my/route")]
    public IActionResult CalcAc([ModelBinder(BinderType = typeof(MyModelBinder))]IViewModel viewModel)
    {
   ....
</code>```

i.e. it works, when I make this HTTP-Post request

```<code>url/my/route?viewModel=URLparsedJSON
</code>```

I would like however to pass it through the body of the request, i.e.

```<code>public IActionResult Calc([FromBody][ModelBinder(BinderType = typeof(MyModelBinder))]IViewModel viewModel)
</code>```

In my Modelbinder then, the modelName is "" and the ValueProvider yields null... What am I doing wrong?

UPDATE

Example; Assume you have an interface IGeometry and many implementations of different 2D shapes, like Circle: IGeometry or Rectangle: IGeometry or Polygon: IGeometry. IGeometry itself has the method decimal getArea(). Now, my URL shall calculate the area for any shape that implements IGeometry, that would look like this

```<code>    [HttpPost]
    [Route("geometry/calcArea")]
    public IActionResult CalcArea([FromBody]IGeometry geometricObject)
    {
         return Ok(geometricObject.getArea());
         // or for sake of completness
         // return Ok(service.getArea(geometricObject));
    }
</code>```

the problem is, you cannot bind to an interface, that yields an error, you need a class! That's where the custom model binder is used. Assume your IGeometryalso has the following property string Type {get; set;}
the in the custom model binding you would simply search for that Type in the passed json and bind it to the correct implementation. Something like

```<code>if (bodyContent is Rectangle) // that doesn't work ofc, but you get the point
var boundObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Rectangle>(jsonString);
</code>```

ASP.Net EF

In ASP.Net EF the custom model binding looks like this

```<code> public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
</code>```

here you get the body of the HTTPPost request like this

```<code> string json = actionContext.Request.Content.ReadAsStringAsync().Result;
</code>```

in ASP.Net Core you don't have the actionContext, only the bindingContext where I can't find the body of the HTTP Post.

UPDATE 2

Ok, I found the body, see accepted answer. Now inside the controller method I really have an object from type IGeometry (an interface) that is instantiated inside the custom model binder! My controller method looks like this:

```<code>    [HttpPost]
    [Route("geometry/calcArea")]
    public IActionResult CalcArea([FromBody]IGeometry geometricObject)
    {
         return Ok(service.getArea(geometricObject));
    }
</code>```

And my injected service like this

```<code>    public decimal getArea(IGeometry viewModel)
    {
        return viewModel.calcArea();
    }
</code>```

IGeometry on the other hand looks like this

```<code>public interface IGeometry
{
    string Type { get; set; } // I use this to correctly bind to each implementation
    decimal calcArea();
</code>```

...

Each class then simply calculates the area accordingly, so

```<code>public class Rectangle : IGeometry
{
    public string Type {get; set; }
    public decimal b0 { get; set; }
    public decimal h0 { get; set; }

    public decimal calcArea()
    {
        return b0 * h0;
    }
</code>```

or

```<code>public class Circle : IGeometry
{
    public string Type {get; set; }
    public decimal radius { get; set; }

    public decimal calcArea()
    {
        return radius*radius*Math.Pi;
    }
</code>```

答:
I found a solution. The body of a HTTP Post request using ASP.NET Core can be obtained in a custom model binder using this lines of code

```<code>string json;
using (var reader = new StreamReader(bindingContext.ActionContext.HttpContext.Request.Body, Encoding.UTF8))
   json = reader.ReadToEnd();
</code>```

I found the solution after looking at older EF projects. There the body is inside the ActionContext which is passed separately as an argument in the BindModel method. I found that the same ActionContext is part of the ModelBindingContext in ASP.Net Core, where you get an IO.Stream instead of a string (easy to convert :-))

Body:
I would like to bind an object in a controller through the body of a HTTP Post.

It works like this

public class MyModelBinder : IModelBinder
    {
        public Task BindModelAsync(ModelBindingContext bindingContext)
        {
            if (bindingContext == null)
                throw new ArgumentNullException("No context found");

            string modelName = bindingContext.ModelName;
            if (String.IsNullOrEmpty(modelName)) {
                bindingContext.Result = ModelBindingResult.Failed();
                return Task.CompletedTask;
            }

            string value = bindingContext.ValueProvider.GetValue(modelName).FirstValue;
...

The modelName is viewModel (honestly, I don't know why, but it works...)

My controller looks like this

    [HttpPost]
    [Route("my/route")]
    public IActionResult CalcAc([ModelBinder(BinderType = typeof(MyModelBinder))]IViewModel viewModel)
    {
   ....

i.e. it works, when I make this HTTP-Post request

url/my/route?viewModel=URLparsedJSON

I would like however to pass it through the body of the request, i.e.

public IActionResult Calc([FromBody][ModelBinder(BinderType = typeof(MyModelBinder))]IViewModel viewModel)

In my Modelbinder then, the modelName is "" and the ValueProvider yields null... What am I doing wrong?

UPDATE

Example; Assume you have an interface IGeometry and many implementations of different 2D shapes, like Circle: IGeometry or Rectangle: IGeometry or Polygon: IGeometry. IGeometry itself has the method decimal getArea(). Now, my URL shall calculate the area for any shape that implements IGeometry, that would look like this

    [HttpPost]
    [Route("geometry/calcArea")]
    public IActionResult CalcArea([FromBody]IGeometry geometricObject)
    {
         return Ok(geometricObject.getArea());
         // or for sake of completness
         // return Ok(service.getArea(geometricObject));
    }

the problem is, you cannot bind to an interface, that yields an error, you need a class! That's where the custom model binder is used. Assume your IGeometryalso has the following property string Type {get; set;}
the in the custom model binding you would simply search for that Type in the passed json and bind it to the correct implementation. Something like

if (bodyContent is Rectangle) // that doesn't work ofc, but you get the point
var boundObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Rectangle>(jsonString);

ASP.Net EF

In ASP.Net EF the custom model binding looks like this

 public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)

here you get the body of the HTTPPost request like this

 string json = actionContext.Request.Content.ReadAsStringAsync().Result;

in ASP.Net Core you don't have the actionContext, only the bindingContext where I can't find the body of the HTTP Post.

UPDATE 2

Ok, I found the body, see accepted answer. Now inside the controller method I really have an object from type IGeometry (an interface) that is instantiated inside the custom model binder! My controller method looks like this:

    [HttpPost]
    [Route("geometry/calcArea")]
    public IActionResult CalcArea([FromBody]IGeometry geometricObject)
    {
         return Ok(service.getArea(geometricObject));
    }

And my injected service like this

    public decimal getArea(IGeometry viewModel)
    {
        return viewModel.calcArea();
    }

IGeometry on the other hand looks like this

public interface IGeometry
{
    string Type { get; set; } // I use this to correctly bind to each implementation
    decimal calcArea();

...

Each class then simply calculates the area accordingly, so

public class Rectangle : IGeometry
{
    public string Type {get; set; }
    public decimal b0 { get; set; }
    public decimal h0 { get; set; }

    public decimal calcArea()
    {
        return b0 * h0;
    }

or

public class Circle : IGeometry
{
    public string Type {get; set; }
    public decimal radius { get; set; }

    public decimal calcArea()
    {
        return radius*radius*Math.Pi;
    }

Body:
I found a solution. The body of a HTTP Post request using ASP.NET Core can be obtained in a custom model binder using this lines of code

string json;
using (var reader = new StreamReader(bindingContext.ActionContext.HttpContext.Request.Body, Encoding.UTF8))
   json = reader.ReadToEnd();

I found the solution after looking at older EF projects. There the body is inside the ActionContext which is passed separately as an argument in the BindModel method. I found that the same ActionContext is part of the ModelBindingContext in ASP.Net Core, where you get an IO.Stream instead of a string (easy to convert :-))


来源: stackexchange

问:
Using a gitosis git repository with XCode 4
Hi
I've been trying to access my git repository from XCode 4.

Everything works just fine using the command line tools. I can clone my repo using:

```<code>git clone git@example.com:somerepo.git
</code>```

But in XCode, when trying to use:

```<code>ssh://git@example.com:somerepo.git
</code>```

It just keeps asking me for a password, which I don't want to use at all.

The same thing happens with:

```<code>git://git@example.com:somerepo.git
</code>```

Except that i also get a "Connection refused: unable to connect to a socket" error message.

Any idea how to solve this?

答:
Cloning a Git repo through the git protocol (which is what you did in command line) isn't the same than using a ssh+git protocol (which is what you tried first in XCode4)

Only ssh would ask for a password, if no public key is found in your $HOME/.ssh directory.

And if you have access to port 9418 on the server example.com, you don't need ssh to clone (you might need it if there are an authentication layer set on the example.com server though)

The "unable to connect a socke" error is typical of a firewall/proxy issue: see Git error: fatal: unable to connect a socket (Invalid argument).

Check your git config -l: it is possible XCode 4 don't use the exact same setting that your git used in command line.

ContentLicense: CC BY-SA 3.0

Body:
Hi
I've been trying to access my git repository from XCode 4.

Everything works just fine using the command line tools. I can clone my repo using:

git clone git@example.com:somerepo.git

But in XCode, when trying to use:

ssh://git@example.com:somerepo.git

It just keeps asking me for a password, which I don't want to use at all.

The same thing happens with:

git://git@example.com:somerepo.git

Except that i also get a "Connection refused: unable to connect to a socket" error message.

Any idea how to solve this?


问:
Setting value of Date Picker on single onChange
I am trying to set the date for two of my different input types. I tried calling different functions for both input event handler, and it worked. But I want to use more concise way to manage input date. The different approach I tried calling single onChange(), doesn't seem to change my input box value.

Here is my code:

```<code>import React, { Component } from "react";
import axios from "axios";

export default class DatePage extends Component {
  constructor() {
    super();
    this.state = {
      startDate: '',
      endDate: '',
      clicked: false
    };
  }

  componentDidMount() {

    this.setDate();

    this.setState({
        clicked: true
      });
  }

  setDate = (e) => {

    if (this.state.clicked !== true)
    {
      var date = new Date();

      var newdate =
        date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)) + "-" + date.getDate();

      this.setState({
        startDate: newdate,
        endDate: newdate,
        clicked: false
      });
    }

    else
    {

        this.setState({
            [e.target.name]: e.target.value
        });
    }
  };

  render() {
    return (
      <div>

        <label>From</label>
        <input
          type="date"
          name="startdate"
          value={this.state.startDate}
          onChange={this.setDate}

        />

        <label>To</label>
        <input
          type="date"
          name="enddate"
          value={this.state.endDate}
          onChange={this.setDate}
        />
      </div>
    );
  }
}
</code>```

By default,  I am setting the current date and onChange the date selected

答:
You need to correct names in the form.

from:
name="startdate"
to
name="startDate"

Also, here:
name="enddate"
to
name="endDate"

ContentLicense: CC BY-SA 4.0

Body:
I am trying to set the date for two of my different input types. I tried calling different functions for both input event handler, and it worked. But I want to use more concise way to manage input date. The different approach I tried calling single onChange(), doesn't seem to change my input box value.

Here is my code:

import React, { Component } from "react";
import axios from "axios";

export default class DatePage extends Component {
  constructor() {
    super();
    this.state = {
      startDate: '',
      endDate: '',
      clicked: false
    };
  }

  componentDidMount() {

    this.setDate();

    this.setState({
        clicked: true
      });
  }

  setDate = (e) => {

    if (this.state.clicked !== true)
    {
      var date = new Date();

      var newdate =
        date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)) + "-" + date.getDate();

      this.setState({
        startDate: newdate,
        endDate: newdate,
        clicked: false
      });
    }

    else
    {

        this.setState({
            [e.target.name]: e.target.value
        });
    }
  };

  render() {
    return (

        From
        <input
          type="date"
          name="startdate"
          value={this.state.startDate}
          onChange={this.setDate}

        />

        To
        <input
          type="date"
          name="enddate"
          value={this.state.endDate}
          onChange={this.setDate}
        />

    );
  }
}

By default,  I am setting the current date and onChange the date selected


问:
Android Foreground Service onStartCommand doesn't invoke, only onCreate invokes
I have a Foreground service which is defined in manifest and in a different process and I used to call it when my activity runs and everything was working good but suddenly when I want to start the foreground Service the onStartCommand doesn't invoke anymore, only the onCreate method! and I cant see my Log in onStartCommand method...

This is My Service declared in Manifest:

```<code><service
            android:name=".services.ForegroundService"
            android:enabled="true"
            android:exported="false"
            android:process=":ForegroundService" />
</code>```

here is my code, for starting the service :

```<code>private void startServices() {
        new Handler().postDelayed(() -> {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForegroundService(new Intent(MapBoxActivity.this,ForegroundService.class));
            } else {
                startService(new Intent(MapBoxActivity.this,ForegroundService.class));
                Timber.i("service Started!");
            }
            TaskScheduler.schedule(MapBoxActivity.this);
        }, 10*1000);
    }
</code>```

and I call startServices() method in my onCreate method of my Activity...

and here is the code of my Foreground service:

```public class ForegroundService extends Service implements
        SensorEventListener, StepListener , MapboxActivityLocationCallback.MapboxLocationListener {

    private static final String ACTION_STOP_SERVICE = "stop_service";
    public static final String URL_SAVE_PROFILE = "https://www.mohregroup.com/db-mapapa/saveName.php";

    private int countedSteps = 0;
    private Location originLocation;
    private LocationEngine locationEngine;
    private long DEFAULT_INTERVAL_IN_MILLISECONDS = 10 * 60 * 1000L;
    private long DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS * 3;
    private MapboxActivityLocationCallback locationCallback = new MapboxActivityLocationCallback();

    private final SparseArray<MarkerItem> treasuresList = new SparseArray<>();
    private SparseArray<MarkerItem> sawTreasuresList = new SparseArray<>();

    private String JSON_locations = null, JSON_locations_tmp = null, geocodeAddress = null, address;

    //Session Manager
    private SessionManager sessionManager;
    private HashMap<String, Object> user;

    //locationChecker
    private String zone, currentZone;
    private boolean onConnectedFlag = false;

    private MyDbAdapter dbAdapter;

    private int coins , dailySteps;
    private float bagCapacity;

    private SteepDetector steepDetector;

    private BagBroadcastReceiver receiver;

    private PowerManager.WakeLock wakeLock;

    public ForegroundService() {
    }

    @SuppressLint("MissingPermission")
    @Override
    public void onCreate() {
        super.onCreate();
        activateLocationEngine();

        //###########SEND TO SERVER
        registerReceiver(new NetworkStateChecker(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
        //for updated UI!
        BroadcastReceiver sendToServerReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                //TODO : for updated UI!
            }
        };
        registerReceiver(sendToServerReceiver, new IntentFilter(DATA_SAVED_BROADCAST));

        syncProfile();

        //###########SEND TO SERVER

        //TODO : works even screen is off
        PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,":ForegroundService");
        wakeLock.acquire(5000);

        sessionManager = new SessionManager(getApplicationContext());
        user = sessionManager.getUserDetails();
        coins = (int) user.get(SessionManager.getKeyCoin());
        bagCapacity = (float) user.get(SessionManager.getKEY_BagCapacity());
        dailySteps  = (int) user.get(SessionManager.getKEY_Steps());
        Timber.i("foreground_userDetails \n coins: %s \n bagCapacity: %s \n dailySteps: %s" ,
                coins , bagCapacity , dailySteps);

        dbAdapter = new MyDbAdapter(getApplicationContext());

        steepDetector = new SteepDetector();
        steepDetector.registerListener(this);

        SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        if (sensorManager != null) {
            //TODO : make sensors great again!
//            Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
            Sensor sensor2 = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//            if (sensor != null) {
//                sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_UI);
//            } else
                if (sensor2 != null) {
                //we don't have step counter sensor! so we use accelerometer
                sensorManager.registerListener(this, sensor2, SensorManager.SENSOR_DELAY_NORMAL);
            }
        }

        locationAdder();
        receiver = new BagBroadcastReceiver();
        registerReceiver(receiver, new IntentFilter("bag_state"));

        new Handler().postDelayed(this::getAdd, 10 * 1000);

        locationCallback.registerMapboxLocationListener(this);

        updateServer();
    }

    private void getAdd() {
        if (originLocation != null) {
            try {
                address = new GetAddress(originLocation).execute().get();
//                Timber.tag("geocodeR").d("%s \n", address);
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void syncProfile() {
        Handler handler = new Handler();
        handler.post(() -> {
            StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_SAVE_PROFILE,
                    response -> {
                        try {
                            JSONObject obj = new JSONObject(response);
                            if (!obj.getBoolean("error")) {
                                //if there is a success
                                //storing the name to sqlite with status synced
                                dbAdapter.addProfile(countedSteps, PROFILE_SYNCED_WITH_SERVER);
                                Timber.tag("OnResponse").d("synced successfully!");
                            } else {
                                //if there is some error
                                //saving the name to sqlite with status unsynced
                                Timber.tag("OnResponse").d("not synced ");
                                dbAdapter.addProfile(countedSteps, PROFILE_NOT_SYNCED_WITH_SERVER);
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    },
                    error -> {
                        //on error storing the name to sqlite with status unsynced
                        Timber.tag("OnErrorResponse").d("not synced ");
                        dbAdapter.addProfile(countedSteps, PROFILE_NOT_SYNCED_WITH_SERVER);
                    }) {
                @Override
                protected Map<String, String> getParams() {
                    Map<String, String> params = new HashMap<>();
                    params.put("step", String.valueOf(countedSteps));
                    return params;
                }
            };

            VolleySingleton.getInstance(ForegroundService.this).addToRequestQueue(stringRequest);

        });
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        //Step Counter with StepDetector Sensor
        if (event.sensor.getType() == Sensor.TYPE_STEP_DETECTOR
                && event.values[0] == 1.0) {
            countedSteps++;
            int steps;
            int prev_odometer_steps = (int) user.get(SessionManager.getKEY_Steps());
            if (countedSteps > prev_odometer_steps) {
                steps = countedSteps - prev_odometer_steps;
                if ((int) user.get(SessionManager.getKeyCoin()) < (float) user.get(SessionManager.getKEY_BagCapacity())) {
                    BagBroadcastReceiver.isNotified = false;
                    coins += steps;
                }
            }
            if (coins >= ((float) user.get(SessionManager.getKEY_BagCapacity()))) {
                sendBroadcast(new Intent("bag_state"));
                Timber.tag("bag_coins").d("%s", coins);
            }
        } else {
            steepDetector.updateAccel(
                    event.timestamp, event.values[0], event.values[1], event.values[2]);
        }
    }

    private void updateContentProvider() {
        ContentValues contentValues = new ContentValues();
        contentValues.put(MyContentProvider.COINS , coins);
        contentValues.put(MyContentProvider.STEPS , countedSteps);
        getContentResolver().update(MyContentProvider.CONTENT_URI , contentValues , null , null);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }

    @Override
    public void step(long timeNs) {
        countedSteps++;
        if ((int) user.get(SessionManager.getKeyCoin()) < (float) user.get(SessionManager.getKEY_BagCapacity())) {
            BagBroadcastReceiver.isNotified = false;
            coins += 1;
            Timber.i("foreground_updatedCoin: coins: %s \n countedSteps: %s \n steps: %s \n bagC: %s",
                    coins , countedSteps , 1 , bagCapacity);
        }
        //use content provider
        updateContentProvider();
        if (coins >= ((float) user.get(SessionManager.getKEY_BagCapacity()))) {
            sendBroadcast(new Intent("bag_state"));
            Timber.tag("bag_coins").d("%s", coins);
        }
    }

    @Override
    public void onLocationUpdate(Location lastLocation) {
        if (lastLocation != null) {
            originLocation = lastLocation;
            try {
                if (JSON_locations != null && address != null) {
                    JSON_locations = dbAdapter.LocationGetAllData().toString();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @SuppressLint("MissingPermission")
    private void activateLocationEngine() {
        locationEngine = LocationEngineProvider.getBestLocationEngine(this);
        LocationEngineRequest request = new LocationEngineRequest.Builder(DEFAULT_INTERVAL_IN_MILLISECONDS)
                .setFastestInterval(DEFAULT_INTERVAL_IN_MILLISECONDS / 5)
                .setMaxWaitTime(DEFAULT_MAX_WAIT_TIME)
                .setPriority(LocationEngineRequest.PRIORITY_BALANCED_POWER_ACCURACY)
                .build();

        locationEngine.requestLocationUpdates(request, locationCallback, Looper.getMainLooper());
        locationEngine.getLastLocation(locationCallback);

        if (!onConnectedFlag) {
            locationChecker();
            onConnectedFlag = true;
        }
    }

    @Override
    public IBinder onBind(@NonNull Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null &&
                ACTION_STOP_SERVICE.equals(intent.getAction())) {
            stopSelf();
            if (locationEngine != null) {
                locationEngine.removeLocationUpdates(locationCallback);
            }
        } else {
            activateLocationEngine();
            displaySawTreasures();
            updateTreasures();
            updateValues(intent);
        }
        startForegroundService();
        Timber.i("onStartCommand Started!");
        return START_STICKY;
    }

    private void updateValues(Intent intent) {
        if (intent != null){
            coins = intent.getIntExtra(COIN_MAP_FOREGROUND , 0);
            bagCapacity = intent.getFloatExtra(BAG_CAPACITY_MAP_FOREGROUND , 0f);
            Cursor cursor = getContentResolver().query(MyContentProvider.CONTENT_URI ,
                    null , null , null , null);
            if (cursor != null){
                if (cursor.moveToFirst()){
                    while (!cursor.isAfterLast()){
                        dailySteps = cursor.getInt(cursor.getColumnIndex(MyContentProvider.STEPS));
                    }
                }
                cursor.close();
            }
            Timber.i("foreground_userUpdated \n coins: %s \n bagCapacity: %s \n dailySteps: %s" ,
                    coins , bagCapacity , dailySteps);
        }
    }

    private void startForegroundService() {
        /*
         * Notification for foreground Service
         * */
        int notification_id = (int) System.currentTimeMillis();
        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_custom);

        Intent button_intent = new Intent(this, ForegroundService.class);
        button_intent.setAction(ACTION_STOP_SERVICE);
        PendingIntent button_pending = PendingIntent.getService(
                this,
                0,
                button_intent,
                PendingIntent.FLAG_CANCEL_CURRENT);
        remoteViews.setTextViewText(R.id.notif_txt, String.valueOf(dailySteps));
        remoteViews.setOnClickPendingIntent(R.id.notif_btn, button_pending);

        //action intent
        Intent actionIntent = new Intent(this, MapBoxActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                this,
                0,
                actionIntent,
                PendingIntent.FLAG_UPDATE_CURRENT
        );

        NotificationCompat.Builder builder =
                new NotificationCompat.Builder(this, CHANNEL_ID)
                        .setSmallIcon(R.drawable.ic_stat_notification_small)
                        .setContentTitle(getResources().getString(R.string.notification_title))
                        .setCustomBigContentView(remoteViews)
                        .setPriority(NotificationCompat.PRIORITY_LOW)
                        .addAction(R.id.notif_btn, "Stop", pendingIntent)
                        .setAutoCancel(false);
        if (dailySteps < 2000) {
            builder.setContentText("ماجراجویی بیشتر، گنج بیشتر!!");
        } else if (dailySteps > 2000 && dailySteps < 4000) {
            builder.setContentText("خوبه! امروز خوب فعالیت داشتی!");
        } else if (dailySteps >= 4000 && dailySteps < 6000) {
            builder.setContentText("ایول! امروز خوب تلاش کردی!");
        } else if (dailySteps >= 6000 && dailySteps < 8000) {
            builder.setContentText("رفیق امروز میخوای بترکونی؟!");
        } else if (dailySteps >= 8000 && dailySteps < 10000) {
            builder.setContentText("میبینم کههه خیلی عالی پیش رفتی امروز!");
        } else if (dailySteps >= 10000) {
            builder.setContentText("رفیق ترکوندی! تو فوق العاده ای!");
        }
        builder.setContentIntent(pendingIntent);

        Notification notification = builder.build();

        startForeground(notification_id, notification);

        Timber.i("foreground Started!");

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        locationEngine.removeLocationUpdates(locationCallback);
        unregisterReceiver(receiver);
        if (originLocation != null) originLocation = null;
        if (JSON_locations != null) JSON_locations = null;
        if (JSON_locations_tmp != null) JSON_locations_tmp = null;
        if (geocodeAddress != null) geocodeAddress = null;
        if (address != null) address = null;
        if (dbAdapter != null) dbAdapter = null;
        wakeLock.release();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        locationEngine.removeLocationUpdates(locationCallback);
        stopSelf();
    }

    private void sendTreasureNotification(MarkerItem markerItem, SparseArray<MarkerItem> updatedList) {

        NotificationCompat.Builder builder =
                new NotificationCompat.Builder(this, CHANNEL_ID)
                        .setSmallIcon(R.drawable.ic_stat_notification_small)
                        .setContentTitle(getResources().getString(R.string.notification_text))
                        .setPriority(NotificationCompat.PRIORITY_HIGH)
                        .setVibrate(new long[]{0, 250, 250, 250, 250})
                        .setLights(Color.BLUE, 1000, 2000)
                        .setAutoCancel(true);
        if (!sessionManager.isLoggedIn())
            builder.setContentText("برای بدست آوردنش وارد حسابت شو!");

        //creating an action Intent and passing the values to the GoogleMapActivity from Service
        Intent actionIntent = new Intent(this, MapBoxActivity.class);
        actionIntent.setAction("newTreasureList");
        actionIntent.putExtra("list", (Parcelable) updatedList);

        PendingIntent actionPendingIntent = PendingIntent.getActivity(this,
                0,
                actionIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(actionPendingIntent);
        //issue the notification
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (notificationManager != null && sawTreasuresList.get(markerItem.getId()) == null) {
            //Log.d("markerIds",markerItem.getOwnerId()+"-"+(Integer)user.get(SessionManager.getKeyId()));
            if (markerItem.getOwnerId() != (int) user.get(SessionManager.getKeyId())) {
                notificationManager.notify(1, builder.build());
            }
            sawTreasuresList.put(markerItem.getId(), markerItem);
            Timber.tag("notification_sent").d(updatedList.toString());
        }
    }

    private void displaySawTreasures() {
        final Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                if (originLocation != null) {
                    for (int i = 0; i < treasuresList.size(); i++) {
                        MarkerItem markerItem = treasuresList.valueAt(i);
                        sendTreasureNotification(markerItem, sawTreasuresList);
                        treasuresList.delete(markerItem.getId());
                    }
                }
                handler.postDelayed(this, 12 * 60 * 1000);
            }
        });

    }

    private ArrayList<JSONObject> getJsonTreasures(String json) {

        ArrayList<JSONObject> jsonObjectArrayList = new ArrayList<>();
        if (json != null) {
            try {
jsonObject.get("server_response");
                JSONArray jsonArray = new JSONArray(json);

                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject object = (JSONObject) jsonArray.get(i);
                    jsonObjectArrayList.add(object);

                    MarkerItem markerItem = new MarkerItem(object.getInt("locationId"),
                            object.getInt("ownerId"), object.getString("owner"),
                            object.getDouble("latitude"), object.getDouble("longitude"),
                            object.getInt("value"), object.getInt("shovelId"), object.getInt("shovel"),
                            object.getString("charmLink"),
                            object.getInt("depth"));
                    treasuresList.put(markerItem.getId(), markerItem);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return jsonObjectArrayList;
    }

    private void locationAdder() {
        final Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
//                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                if (NetworkUtil.hasNetworkAccess())
                    if (JSON_locations != null)
                        if (!JSON_locations.equals(JSON_locations_tmp)) {
//                            Log.d("LocationsStatus",JSON_locations.equals(JSON_locations_tmp)+"");
                            JSON_locations_tmp = JSON_locations;
                            //adding json information to the array list of JSONObject
                            ArrayList<JSONObject> jsonObjectArrayList = getJsonTreasures(JSON_locations);
                            treasuresList.clear();
                            if (jsonObjectArrayList != null) {
                                for (JSONObject jsonObject : jsonObjectArrayList) {
                                    try {
                                        String latitude = jsonObject.getString("latitude");
                                        String longitude = jsonObject.getString("longitude");
                                        if (!latitude.equals("") && !longitude.equals("")) {
                                            MarkerItem markerItem = new MarkerItem(jsonObject.getInt("locationId"),
                                                    jsonObject.getInt("ownerId"), jsonObject.getString("owner"),
                                                    jsonObject.getDouble("latitude"), jsonObject.getDouble("longitude"),
                                                    jsonObject.getInt("value"), jsonObject.getInt("shovelId"), jsonObject.getInt("shovel"),
                                                    jsonObject.getString("charmLink"),
                                                    jsonObject.getInt("depth"));
                                            treasuresList.put(markerItem.getId(), markerItem);
                                        }
                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                    }
                                }
                                SparseArray<MarkerItem> tmp = new SparseArray<>();
                                for (int i = 0; i < treasuresList.size(); i++) {
                                    MarkerItem m = treasuresList.valueAt(i);
                                    if (sawTreasuresList.get(m.getId()) != null) {
                                        tmp.put(m.getId(), m);
                                    }
                                }
                                sawTreasuresList = tmp;
                            }
                        }
                handler.postDelayed(this, 11 * 60 * 1000);
            }
        });
    }

    private void updateServer() {
        Handler handler = new Handler();
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (NetworkUtil.hasNetworkAccess()){
                    if (originLocation != null){
                        try {
                            address = new GetAddress(originLocation).execute().get();
                        } catch (InterruptedException | ExecutionException e) {
                            e.printStackTrace();
                        }
                        if (address != null) {
                            new LocationTask(ForegroundService.this).execute("updatePoint",
                                    String.valueOf(coins), String.valueOf(1),
                                    String.valueOf(originLocation.getLatitude()), String.valueOf(originLocation.getLongitude()),
                                    address, address);
                        } else {
                            new LocationTask(ForegroundService.this).execute("updatePoint", String.valueOf(coins), String.valueOf(1),
                                    String.valueOf(originLocation.getLatitude()), String.valueOf(originLocation.getLongitude()),
                                    "not titled", "not titled");
                        }
                        Timber.d("update_server: COINS: %s \n originLocation: %s \n address: %s " ,
                                coins , originLocation.toString(),address);
                    }
                }

                //TODO update server data every 1 hour
                handler.postDelayed(this , 30 * 1000);
            }
        });
    }

    private void updateTreasures() {
        final Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (NetworkUtil.hasNetworkAccess()) {
//                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    try {
                        address = new GetAddress(originLocation).execute().get();
                        if (address != null) {
                            new LocationTask(ForegroundService.this).execute("getLocations", address);
                            JSON_locations = dbAdapter.LocationGetAllData().toString();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                //set up to 17 mins
                handler.postDelayed(this, 17 * 60 * 1000);
            }
        });
    }

    private void locationChecker() {
        final Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                if (originLocation != null && onConnectedFlag && NetworkUtil.hasNetworkAccess()) {
                    try {
                        address = new GetAddress(originLocation).execute().get();

                        if (address != null) {
                            zone = address;
                        }

                        if (zone != null && !zone.equals(currentZone)) {
                            currentZone = zone;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                //set up to 19 mins
                handler.postDelayed(this, 19 * 60 * 1000);
            }
        });
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(CalligraphyContextWrapper.wrap(base));
    }
```

and I simply can't understand why is this happening cause I was working for maybe 4 hours ago! but it doesn't work for now...

Update: for about 9 hours earlier I was using my phone and suddenly I saw the Notification of my Foreground Service started! so I figured it out that the system doesn't start my Foreground process (or kill it immediately) and start it whenever it wants!(according to managing the memories perhaps)
So why is that so? and how can be resolved?

答:
My Stupid Bad!
the reason that my service didn't start and most of the time my app crashed was because of the method updateValues(intent) inside of onStartCommand!
It has a while Loop that the condition wasn't right and it got stuck in an infinite loop! so that was the reason code did't go further to complete the onStartCommand  and start the Service!

Body:
I have a Foreground service which is defined in manifest and in a different process and I used to call it when my activity runs and everything was working good but suddenly when I want to start the foreground Service the onStartCommand doesn't invoke anymore, only the onCreate method! and I cant see my Log in onStartCommand method...

This is My Service declared in Manifest:

<service
            android:name=".services.ForegroundService"
            android:enabled="true"
            android:exported="false"
            android:process=":ForegroundService" />

here is my code, for starting the service :

private void startServices() {
        new Handler().postDelayed(() -> {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                startForegroundService(new Intent(MapBoxActivity.this,ForegroundService.class));
            } else {
                startService(new Intent(MapBoxActivity.this,ForegroundService.class));
                Timber.i("service Started!");
            }
            TaskScheduler.schedule(MapBoxActivity.this);
        }, 10*1000);
    }

and I call startServices() method in my onCreate method of my Activity...

and here is the code of my Foreground service:

public class ForegroundService extends Service implements
        SensorEventListener, StepListener , MapboxActivityLocationCallback.MapboxLocationListener {

    private static final String ACTION_STOP_SERVICE = "stop_service";
    public static final String URL_SAVE_PROFILE = "https://www.mohregroup.com/db-mapapa/saveName.php";

    private int countedSteps = 0;
    private Location originLocation;
    private LocationEngine locationEngine;
    private long DEFAULT_INTERVAL_IN_MILLISECONDS = 10 * 60 * 1000L;
    private long DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS * 3;
    private MapboxActivityLocationCallback locationCallback = new MapboxActivityLocationCallback();

    private final SparseArray<MarkerItem> treasuresList = new SparseArray<>();
    private SparseArray<MarkerItem> sawTreasuresList = new SparseArray<>();

    private String JSON_locations = null, JSON_locations_tmp = null, geocodeAddress = null, address;

    //Session Manager
    private SessionManager sessionManager;
    private HashMap<String, Object> user;

    //locationChecker
    private String zone, currentZone;
    private boolean onConnectedFlag = false;

    private MyDbAdapter dbAdapter;

    private int coins , dailySteps;
    private float bagCapacity;

    private SteepDetector steepDetector;

    private BagBroadcastReceiver receiver;

    private PowerManager.WakeLock wakeLock;

    public ForegroundService() {
    }

    @SuppressLint("MissingPermission")
    @Override
    public void onCreate() {
        super.onCreate();
        activateLocationEngine();

        //###########SEND TO SERVER
        registerReceiver(new NetworkStateChecker(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
        //for updated UI!
        BroadcastReceiver sendToServerReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                //TODO : for updated UI!
            }
        };
        registerReceiver(sendToServerReceiver, new IntentFilter(DATA_SAVED_BROADCAST));

        syncProfile();

        //###########SEND TO SERVER

        //TODO : works even screen is off
        PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,":ForegroundService");
        wakeLock.acquire(5000);

        sessionManager = new SessionManager(getApplicationContext());
        user = sessionManager.getUserDetails();
        coins = (int) user.get(SessionManager.getKeyCoin());
        bagCapacity = (float) user.get(SessionManager.getKEY_BagCapacity());
        dailySteps  = (int) user.get(SessionManager.getKEY_Steps());
        Timber.i("foreground_userDetails \n coins: %s \n bagCapacity: %s \n dailySteps: %s" ,
                coins , bagCapacity , dailySteps);

        dbAdapter = new MyDbAdapter(getApplicationContext());

        steepDetector = new SteepDetector();
        steepDetector.registerListener(this);

        SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        if (sensorManager != null) {
            //TODO : make sensors great again!
//            Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
            Sensor sensor2 = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//            if (sensor != null) {
//                sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_UI);
//            } else
                if (sensor2 != null) {
                //we don't have step counter sensor! so we use accelerometer
                sensorManager.registerListener(this, sensor2, SensorManager.SENSOR_DELAY_NORMAL);
            }
        }

        locationAdder();
        receiver = new BagBroadcastReceiver();
        registerReceiver(receiver, new IntentFilter("bag_state"));

        new Handler().postDelayed(this::getAdd, 10 * 1000);

        locationCallback.registerMapboxLocationListener(this);

        updateServer();
    }

    private void getAdd() {
        if (originLocation != null) {
            try {
                address = new GetAddress(originLocation).execute().get();
//                Timber.tag("geocodeR").d("%s \n", address);
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void syncProfile() {
        Handler handler = new Handler();
        handler.post(() -> {
            StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_SAVE_PROFILE,
                    response -> {
                        try {
                            JSONObject obj = new JSONObject(response);
                            if (!obj.getBoolean("error")) {
                                //if there is a success
                                //storing the name to sqlite with status synced
                                dbAdapter.addProfile(countedSteps, PROFILE_SYNCED_WITH_SERVER);
                                Timber.tag("OnResponse").d("synced successfully!");
                            } else {
                                //if there is some error
                                //saving the name to sqlite with status unsynced
                                Timber.tag("OnResponse").d("not synced ");
                                dbAdapter.addProfile(countedSteps, PROFILE_NOT_SYNCED_WITH_SERVER);
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    },
                    error -> {
                        //on error storing the name to sqlite with status unsynced
                        Timber.tag("OnErrorResponse").d("not synced ");
                        dbAdapter.addProfile(countedSteps, PROFILE_NOT_SYNCED_WITH_SERVER);
                    }) {
                @Override
                protected Map<String, String> getParams() {
                    Map<String, String> params = new HashMap<>();
                    params.put("step", String.valueOf(countedSteps));
                    return params;
                }
            };

            VolleySingleton.getInstance(ForegroundService.this).addToRequestQueue(stringRequest);

        });
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        //Step Counter with StepDetector Sensor
        if (event.sensor.getType() == Sensor.TYPE_STEP_DETECTOR
                && event.values[0] == 1.0) {
            countedSteps++;
            int steps;
            int prev_odometer_steps = (int) user.get(SessionManager.getKEY_Steps());
            if (countedSteps > prev_odometer_steps) {
                steps = countedSteps - prev_odometer_steps;
                if ((int) user.get(SessionManager.getKeyCoin()) < (float) user.get(SessionManager.getKEY_BagCapacity())) {
                    BagBroadcastReceiver.isNotified = false;
                    coins += steps;
                }
            }
            if (coins >= ((float) user.get(SessionManager.getKEY_BagCapacity()))) {
                sendBroadcast(new Intent("bag_state"));
                Timber.tag("bag_coins").d("%s", coins);
            }
        } else {
            steepDetector.updateAccel(
                    event.timestamp, event.values[0], event.values[1], event.values[2]);
        }
    }

    private void updateContentProvider() {
        ContentValues contentValues = new ContentValues();
        contentValues.put(MyContentProvider.COINS , coins);
        contentValues.put(MyContentProvider.STEPS , countedSteps);
        getContentResolver().update(MyContentProvider.CONTENT_URI , contentValues , null , null);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int i) {

    }

    @Override
    public void step(long timeNs) {
        countedSteps++;
        if ((int) user.get(SessionManager.getKeyCoin()) < (float) user.get(SessionManager.getKEY_BagCapacity())) {
            BagBroadcastReceiver.isNotified = false;
            coins += 1;
            Timber.i("foreground_updatedCoin: coins: %s \n countedSteps: %s \n steps: %s \n bagC: %s",
                    coins , countedSteps , 1 , bagCapacity);
        }
        //use content provider
        updateContentProvider();
        if (coins >= ((float) user.get(SessionManager.getKEY_BagCapacity()))) {
            sendBroadcast(new Intent("bag_state"));
            Timber.tag("bag_coins").d("%s", coins);
        }
    }

    @Override
    public void onLocationUpdate(Location lastLocation) {
        if (lastLocation != null) {
            originLocation = lastLocation;
            try {
                if (JSON_locations != null && address != null) {
                    JSON_locations = dbAdapter.LocationGetAllData().toString();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @SuppressLint("MissingPermission")
    private void activateLocationEngine() {
        locationEngine = LocationEngineProvider.getBestLocationEngine(this);
        LocationEngineRequest request = new LocationEngineRequest.Builder(DEFAULT_INTERVAL_IN_MILLISECONDS)
                .setFastestInterval(DEFAULT_INTERVAL_IN_MILLISECONDS / 5)
                .setMaxWaitTime(DEFAULT_MAX_WAIT_TIME)
                .setPriority(LocationEngineRequest.PRIORITY_BALANCED_POWER_ACCURACY)
                .build();

        locationEngine.requestLocationUpdates(request, locationCallback, Looper.getMainLooper());
        locationEngine.getLastLocation(locationCallback);

        if (!onConnectedFlag) {
            locationChecker();
            onConnectedFlag = true;
        }
    }

    @Override
    public IBinder onBind(@NonNull Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (intent != null &&
                ACTION_STOP_SERVICE.equals(intent.getAction())) {
            stopSelf();
            if (locationEngine != null) {
                locationEngine.removeLocationUpdates(locationCallback);
            }
        } else {
            activateLocationEngine();
            displaySawTreasures();
            updateTreasures();
            updateValues(intent);
        }
        startForegroundService();
        Timber.i("onStartCommand Started!");
        return START_STICKY;
    }

    private void updateValues(Intent intent) {
        if (intent != null){
            coins = intent.getIntExtra(COIN_MAP_FOREGROUND , 0);
            bagCapacity = intent.getFloatExtra(BAG_CAPACITY_MAP_FOREGROUND , 0f);
            Cursor cursor = getContentResolver().query(MyContentProvider.CONTENT_URI ,
                    null , null , null , null);
            if (cursor != null){
                if (cursor.moveToFirst()){
                    while (!cursor.isAfterLast()){
                        dailySteps = cursor.getInt(cursor.getColumnIndex(MyContentProvider.STEPS));
                    }
                }
                cursor.close();
            }
            Timber.i("foreground_userUpdated \n coins: %s \n bagCapacity: %s \n dailySteps: %s" ,
                    coins , bagCapacity , dailySteps);
        }
    }

    private void startForegroundService() {
        /*
         * Notification for foreground Service
         * */
        int notification_id = (int) System.currentTimeMillis();
        RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_custom);

        Intent button_intent = new Intent(this, ForegroundService.class);
        button_intent.setAction(ACTION_STOP_SERVICE);
        PendingIntent button_pending = PendingIntent.getService(
                this,
                0,
                button_intent,
                PendingIntent.FLAG_CANCEL_CURRENT);
        remoteViews.setTextViewText(R.id.notif_txt, String.valueOf(dailySteps));
        remoteViews.setOnClickPendingIntent(R.id.notif_btn, button_pending);

        //action intent
        Intent actionIntent = new Intent(this, MapBoxActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                this,
                0,
                actionIntent,
                PendingIntent.FLAG_UPDATE_CURRENT
        );

        NotificationCompat.Builder builder =
                new NotificationCompat.Builder(this, CHANNEL_ID)
                        .setSmallIcon(R.drawable.ic_stat_notification_small)
                        .setContentTitle(getResources().getString(R.string.notification_title))
                        .setCustomBigContentView(remoteViews)
                        .setPriority(NotificationCompat.PRIORITY_LOW)
                        .addAction(R.id.notif_btn, "Stop", pendingIntent)
                        .setAutoCancel(false);
        if (dailySteps < 2000) {
            builder.setContentText("ماجراجویی بیشتر، گنج بیشتر!!");
        } else if (dailySteps > 2000 && dailySteps < 4000) {
            builder.setContentText("خوبه! امروز خوب فعالیت داشتی!");
        } else if (dailySteps >= 4000 && dailySteps < 6000) {
            builder.setContentText("ایول! امروز خوب تلاش کردی!");
        } else if (dailySteps >= 6000 && dailySteps < 8000) {
            builder.setContentText("رفیق امروز میخوای بترکونی؟!");
        } else if (dailySteps >= 8000 && dailySteps < 10000) {
            builder.setContentText("میبینم کههه خیلی عالی پیش رفتی امروز!");
        } else if (dailySteps >= 10000) {
            builder.setContentText("رفیق ترکوندی! تو فوق العاده ای!");
        }
        builder.setContentIntent(pendingIntent);

        Notification notification = builder.build();

        startForeground(notification_id, notification);

        Timber.i("foreground Started!");

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        locationEngine.removeLocationUpdates(locationCallback);
        unregisterReceiver(receiver);
        if (originLocation != null) originLocation = null;
        if (JSON_locations != null) JSON_locations = null;
        if (JSON_locations_tmp != null) JSON_locations_tmp = null;
        if (geocodeAddress != null) geocodeAddress = null;
        if (address != null) address = null;
        if (dbAdapter != null) dbAdapter = null;
        wakeLock.release();
    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        locationEngine.removeLocationUpdates(locationCallback);
        stopSelf();
    }

    private void sendTreasureNotification(MarkerItem markerItem, SparseArray<MarkerItem> updatedList) {

        NotificationCompat.Builder builder =
                new NotificationCompat.Builder(this, CHANNEL_ID)
                        .setSmallIcon(R.drawable.ic_stat_notification_small)
                        .setContentTitle(getResources().getString(R.string.notification_text))
                        .setPriority(NotificationCompat.PRIORITY_HIGH)
                        .setVibrate(new long[]{0, 250, 250, 250, 250})
                        .setLights(Color.BLUE, 1000, 2000)
                        .setAutoCancel(true);
        if (!sessionManager.isLoggedIn())
            builder.setContentText("برای بدست آوردنش وارد حسابت شو!");

        //creating an action Intent and passing the values to the GoogleMapActivity from Service
        Intent actionIntent = new Intent(this, MapBoxActivity.class);
        actionIntent.setAction("newTreasureList");
        actionIntent.putExtra("list", (Parcelable) updatedList);

        PendingIntent actionPendingIntent = PendingIntent.getActivity(this,
                0,
                actionIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(actionPendingIntent);
        //issue the notification
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (notificationManager != null && sawTreasuresList.get(markerItem.getId()) == null) {
            //Log.d("markerIds",markerItem.getOwnerId()+"-"+(Integer)user.get(SessionManager.getKeyId()));
            if (markerItem.getOwnerId() != (int) user.get(SessionManager.getKeyId())) {
                notificationManager.notify(1, builder.build());
            }
            sawTreasuresList.put(markerItem.getId(), markerItem);
            Timber.tag("notification_sent").d(updatedList.toString());
        }
    }

    private void displaySawTreasures() {
        final Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                if (originLocation != null) {
                    for (int i = 0; i < treasuresList.size(); i++) {
                        MarkerItem markerItem = treasuresList.valueAt(i);
                        sendTreasureNotification(markerItem, sawTreasuresList);
                        treasuresList.delete(markerItem.getId());
                    }
                }
                handler.postDelayed(this, 12 * 60 * 1000);
            }
        });

    }

    private ArrayList<JSONObject> getJsonTreasures(String json) {

        ArrayList<JSONObject> jsonObjectArrayList = new ArrayList<>();
        if (json != null) {
            try {
jsonObject.get("server_response");
                JSONArray jsonArray = new JSONArray(json);

                for (int i = 0; i < jsonArray.length(); i++) {
                    JSONObject object = (JSONObject) jsonArray.get(i);
                    jsonObjectArrayList.add(object);

                    MarkerItem markerItem = new MarkerItem(object.getInt("locationId"),
                            object.getInt("ownerId"), object.getString("owner"),
                            object.getDouble("latitude"), object.getDouble("longitude"),
                            object.getInt("value"), object.getInt("shovelId"), object.getInt("shovel"),
                            object.getString("charmLink"),
                            object.getInt("depth"));
                    treasuresList.put(markerItem.getId(), markerItem);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return jsonObjectArrayList;
    }

    private void locationAdder() {
        final Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
//                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                if (NetworkUtil.hasNetworkAccess())
                    if (JSON_locations != null)
                        if (!JSON_locations.equals(JSON_locations_tmp)) {
//                            Log.d("LocationsStatus",JSON_locations.equals(JSON_locations_tmp)+"");
                            JSON_locations_tmp = JSON_locations;
                            //adding json information to the array list of JSONObject
                            ArrayList<JSONObject> jsonObjectArrayList = getJsonTreasures(JSON_locations);
                            treasuresList.clear();
                            if (jsonObjectArrayList != null) {
                                for (JSONObject jsonObject : jsonObjectArrayList) {
                                    try {
                                        String latitude = jsonObject.getString("latitude");
                                        String longitude = jsonObject.getString("longitude");
                                        if (!latitude.equals("") && !longitude.equals("")) {
                                            MarkerItem markerItem = new MarkerItem(jsonObject.getInt("locationId"),
                                                    jsonObject.getInt("ownerId"), jsonObject.getString("owner"),
                                                    jsonObject.getDouble("latitude"), jsonObject.getDouble("longitude"),
                                                    jsonObject.getInt("value"), jsonObject.getInt("shovelId"), jsonObject.getInt("shovel"),
                                                    jsonObject.getString("charmLink"),
                                                    jsonObject.getInt("depth"));
                                            treasuresList.put(markerItem.getId(), markerItem);
                                        }
                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                    }
                                }
                                SparseArray<MarkerItem> tmp = new SparseArray<>();
                                for (int i = 0; i < treasuresList.size(); i++) {
                                    MarkerItem m = treasuresList.valueAt(i);
                                    if (sawTreasuresList.get(m.getId()) != null) {
                                        tmp.put(m.getId(), m);
                                    }
                                }
                                sawTreasuresList = tmp;
                            }
                        }
                handler.postDelayed(this, 11 * 60 * 1000);
            }
        });
    }

    private void updateServer() {
        Handler handler = new Handler();
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (NetworkUtil.hasNetworkAccess()){
                    if (originLocation != null){
                        try {
                            address = new GetAddress(originLocation).execute().get();
                        } catch (InterruptedException | ExecutionException e) {
                            e.printStackTrace();
                        }
                        if (address != null) {
                            new LocationTask(ForegroundService.this).execute("updatePoint",
                                    String.valueOf(coins), String.valueOf(1),
                                    String.valueOf(originLocation.getLatitude()), String.valueOf(originLocation.getLongitude()),
                                    address, address);
                        } else {
                            new LocationTask(ForegroundService.this).execute("updatePoint", String.valueOf(coins), String.valueOf(1),
                                    String.valueOf(originLocation.getLatitude()), String.valueOf(originLocation.getLongitude()),
                                    "not titled", "not titled");
                        }
                        Timber.d("update_server: COINS: %s \n originLocation: %s \n address: %s " ,
                                coins , originLocation.toString(),address);
                    }
                }

                //TODO update server data every 1 hour
                handler.postDelayed(this , 30 * 1000);
            }
        });
    }

    private void updateTreasures() {
        final Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (NetworkUtil.hasNetworkAccess()) {
//                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    try {
                        address = new GetAddress(originLocation).execute().get();
                        if (address != null) {
                            new LocationTask(ForegroundService.this).execute("getLocations", address);
                            JSON_locations = dbAdapter.LocationGetAllData().toString();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                //set up to 17 mins
                handler.postDelayed(this, 17 * 60 * 1000);
            }
        });
    }

    private void locationChecker() {
        final Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                if (originLocation != null && onConnectedFlag && NetworkUtil.hasNetworkAccess()) {
                    try {
                        address = new GetAddress(originLocation).execute().get();

                        if (address != null) {
                            zone = address;
                        }

                        if (zone != null && !zone.equals(currentZone)) {
                            currentZone = zone;
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                //set up to 19 mins
                handler.postDelayed(this, 19 * 60 * 1000);
            }
        });
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(CalligraphyContextWrapper.wrap(base));
    }

and I simply can't understand why is this happening cause I was working for maybe 4 hours ago! but it doesn't work for now...

Update: for about 9 hours earlier I was using my phone and suddenly I saw the Notification of my Foreground Service started! so I figured it out that the system doesn't start my Foreground process (or kill it immediately) and start it whenever it wants!(according to managing the memories perhaps)
So why is that so? and how can be resolved?


问:
How to not continually repeat a background scenario for Cucumber features that depend on that background scenario
I'm writing some end-to-end tests for my application using Cucumber and Selenium. I'm keeping every scenario totally independent of one another, as advised on the Cucumber website. However, my application has session based authentication, so every time a new scenario is run, it will required a login process in order to first access the site. Right now my approach is to put the login scenario as a background scenario for all other scenarios, like so:

```<code>  Background: User is Logged In
    Given I am on the login screen
    When I enter my login details
    And I click submit
    Then I should be logged in
</code>```

However, this feels like a lot of duplicated 'code'. Moreover, having each scenario run independently requires a new WebDriver instance being created and a browser being run for each scenario, which feels a bit inefficient?

Can anyone advise firstly on how I can avoid duplicating the background scenario in every other scenario (if possible)  and secondly if having a separate WebDriver instance for each scenario is the correct approach?

答:
First of all each of your scenarios is going to have to login and create a new session. Thats the price you pay to do end to end testing. The cost of this in runtime should be relatively small with a standard login process as most login screens are simple, and have short rendering times and very little db access. It really is a very bad idea to tray and save runtime here by trying to share sessions between scenarios.

To start tidying your cukes you could follow Daniel's answer, but instead of nesting the steps I would recommend extracting the code to a helper method and calling that instead.

To do this elegantly with power, i.e. deal with different users with roles and extra attributes you need to do a bit more. You can see a detailed example of this here (https://github.com/diabolo/cuke_up).

To use this effectively follow the commit history and focus mostly on the features folder.

This has some framework code that allows you to register/create users and then use them in lots of different configurations. There is some underlying code that is a little complex, which gives you the power to create users who know their own passwords, as well as add other attributes like roles.

The end result is that you can write a step definitions like

```<code>Given I am registered
Given I am an admin
Given I am logged in
Given I am logged in as an admin
</code>```

which are implemented as

```<code>Given 'I am registered' do
  @i = create_user
end

Given 'I am an admin' do
  @i = create_user role: 'admin'
end

Given 'I am logged in' do
  @i = create_user
  login as: @i
end

Given 'I am logged in as an admin' do
  @i = create_user role: 'admin'
  login as: @i
end
</code>```

note: the variable @i is used to pass the user from one step to the next

You don't have to worry about repetition here as all the steps make calls to the same helper methods. You can use the patterns shown here in a much wider context to simplify your features/

Body:
I'm writing some end-to-end tests for my application using Cucumber and Selenium. I'm keeping every scenario totally independent of one another, as advised on the Cucumber website. However, my application has session based authentication, so every time a new scenario is run, it will required a login process in order to first access the site. Right now my approach is to put the login scenario as a background scenario for all other scenarios, like so:

  Background: User is Logged In
    Given I am on the login screen
    When I enter my login details
    And I click submit
    Then I should be logged in

However, this feels like a lot of duplicated 'code'. Moreover, having each scenario run independently requires a new WebDriver instance being created and a browser being run for each scenario, which feels a bit inefficient?

Can anyone advise firstly on how I can avoid duplicating the background scenario in every other scenario (if possible)  and secondly if having a separate WebDriver instance for each scenario is the correct approach?

Body:
First of all each of your scenarios is going to have to login and create a new session. Thats the price you pay to do end to end testing. The cost of this in runtime should be relatively small with a standard login process as most login screens are simple, and have short rendering times and very little db access. It really is a very bad idea to tray and save runtime here by trying to share sessions between scenarios.

To start tidying your cukes you could follow Daniel's answer, but instead of nesting the steps I would recommend extracting the code to a helper method and calling that instead.

To do this elegantly with power, i.e. deal with different users with roles and extra attributes you need to do a bit more. You can see a detailed example of this here (https://github.com/diabolo/cuke_up).

To use this effectively follow the commit history and focus mostly on the features folder.

This has some framework code that allows you to register/create users and then use them in lots of different configurations. There is some underlying code that is a little complex, which gives you the power to create users who know their own passwords, as well as add other attributes like roles.

The end result is that you can write a step definitions like

Given I am registered
Given I am an admin
Given I am logged in
Given I am logged in as an admin

which are implemented as

Given 'I am registered' do
  @i = create_user
end

Given 'I am an admin' do
  @i = create_user role: 'admin'
end

Given 'I am logged in' do
  @i = create_user
  login as: @i
end

Given 'I am logged in as an admin' do
  @i = create_user role: 'admin'
  login as: @i
end

note: the variable @i is used to pass the user from one step to the next

You don't have to worry about repetition here as all the steps make calls to the same helper methods. You can use the patterns shown here in a much wider context to simplify your features/


问:
SELECT with JOIN -> I want to combine these tables with JOIN
I have 4 tables:

```<code>1) tw_Towar: -> tw_Id, tw_Nazwa,tw_SklepInternet
2) tw_Cena: -> tc_Id, tc_CenaNetto1
3) tw_Stan: -> st_TowId, st_Stan
4) tw_ZdjecieTw: -> zd_IdTowar, zd_Glowne
</code>```

I want to combine these tables with JOIN:

First column is part ID , others are properties of part.

I need to get out(SELECT): tw_Nazwa, tc_CenaNetto1, st_Stan, zd_Glowne

Thanks

答:
```<code>SELECT a.tw_Nazwa, c.st_Stan, d.zd_Glowne , d.zd_Zdjecie, a.tw_Id
FROM tw__Towar  a
LEFT JOIN tw_Cena  b ON a.tw_Id = b.tc_IdTowar
LEFT JOIN tw_Stan c ON b.tc_IdTowar=c.st_TowId
LEFT JOIN tw_ZdjecieTw  d ON d.zd_IdTowar=c.st_TowId
WHERE zd_IdTowar = ".$_REQUEST['pid']." ";

</code>```

This is working good ;)

Body:
I have 4 tables:

1) tw_Towar: -> tw_Id, tw_Nazwa,tw_SklepInternet
2) tw_Cena: -> tc_Id, tc_CenaNetto1
3) tw_Stan: -> st_TowId, st_Stan
4) tw_ZdjecieTw: -> zd_IdTowar, zd_Glowne

I want to combine these tables with JOIN:

First column is part ID , others are properties of part.

I need to get out(SELECT): tw_Nazwa, tc_CenaNetto1, st_Stan, zd_Glowne

Thanks

Body:
SELECT a.tw_Nazwa, c.st_Stan, d.zd_Glowne , d.zd_Zdjecie, a.tw_Id
FROM tw__Towar  a
LEFT JOIN tw_Cena  b ON a.tw_Id = b.tc_IdTowar
LEFT JOIN tw_Stan c ON b.tc_IdTowar=c.st_TowId
LEFT JOIN tw_ZdjecieTw  d ON d.zd_IdTowar=c.st_TowId
WHERE zd_IdTowar = ".$_REQUEST['pid']." ";

This is working good ;)


问:
Why only the first value is written to the variable
I want to get the properties of an object and call a function depending on the property. I'm trying to do it like this:

```<code>let page = {};
Object.keys(product.details).forEach((k) => {
  console.log(k)
  switch (k) {
    case 'description':
      page.add(getDescription());
      break;
    case 'comment':
      page.add(getComment());
      break;
    case 'subDescription':
      page.add(getSubDescription());
      break;
  }
});
console.log(page);
</code>```

My object:

```<code>{
  about: 'text',
  description: 'text',
  comment: 'text',
  subDescription: 'text'
}
</code>```

What do I get in the console:

```<code>about
description
...\src\views\partials\product\description.hbs
</code>```

Why is only the first function called, and the rest not? What's my mistake?

答:
page.add is not defined unless you added it to the Object.prototype or declared it within your object, but thats totally unnecessary.

Use something like this, to make it more easy to handle. Why would you use functions to get values from an Object with the same key?

```<code>const page = {}

for (let key in product.details) {
  console.log(key) // returns about, comment, description, ....
  page[key] = product.details[key]
}

console.log(page)

/* console.log(page) returns
{
  about: "text"
  comment: "text"
  description: "text"
  subDescription: "text"
}
*/

</code>```

Body:
I want to get the properties of an object and call a function depending on the property. I'm trying to do it like this:

let page = {};
Object.keys(product.details).forEach((k) => {
  console.log(k)
  switch (k) {
    case 'description':
      page.add(getDescription());
      break;
    case 'comment':
      page.add(getComment());
      break;
    case 'subDescription':
      page.add(getSubDescription());
      break;
  }
});
console.log(page);

My object:

{
  about: 'text',
  description: 'text',
  comment: 'text',
  subDescription: 'text'
}

What do I get in the console:

about
description
...\src\views\partials\product\description.hbs

Why is only the first function called, and the rest not? What's my mistake?

Body:
page.add is not defined unless you added it to the Object.prototype or declared it within your object, but thats totally unnecessary.

Use something like this, to make it more easy to handle. Why would you use functions to get values from an Object with the same key?

const page = {}

for (let key in product.details) {
  console.log(key) // returns about, comment, description, ....
  page[key] = product.details[key]
}

console.log(page)

/* console.log(page) returns
{
  about: "text"
  comment: "text"
  description: "text"
  subDescription: "text"
}
*/


问:
Drools: Evaluation of DMN 1.2 FEEL-functions does not work
I want to evaluate in Drools 7.21 FEEL-funtions that are new in DMN 1.2, like sqrt() or modulo(), but the method

dmnRuntime.evaluateAll(dmnModel,context)

is allways returning the value 'null' (just for the new functions) with status 'SUCCESS'. What do I do wrong or what is missing?

The DMN-File looks like this:

```<code><?xml version="1.0" encoding="UTF-8" standalone="no"?>
<semantic:definitions xmlns:semantic="http://www.omg.org/spec/DMN/20180521/MODEL/" xmlns="http://www.trisotech.com/definitions/_56fd6445-ff6a-4c28-8206-71fce7f80436" xmlns:feel="http://www.omg.org/spec/FEEL/20140401" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exporter="DMN Modeler" exporterVersion="6.0.1" id="_56fd6445-ff6a-4c28-8206-71fce7f80436" name="Sqrt-Function" namespace="http://www.trisotech.com/definitions/_56fd6445-ff6a-4c28-8206-71fce7f80436" >
  <semantic:decision id="_cf6124bd-9907-4ac0-b4fd-59a962dbc502" name="square_root">
    <semantic:variable id="_edaf978e-3634-4e52-8244-5fd4e16fd257" name="square_root" typeRef="feel:number"/>
    <semantic:literalExpression id="_c990c3b2-e322-4ef9-931d-79bcdac99686">
      <semantic:text>sqrt(81)</semantic:text>
    </semantic:literalExpression>
  </semantic:decision>
</semantic:definitions>
</code>```

After importing the file in "dmnModel":

DMNMarshaller marshaller = new org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller();
FileInputStream fis = new FileInputStream( dmnFile );
Definitions unmarshal = marshaller.unmarshal( new InputStreamReader( fis ) );
DMNCompiler compiler = DMNFactory.newCompiler();
DMNModel dmnModel = compiler.compile(unmarshal);
```

<p>I call the Drools-evaluation like this:</p>

<pre class="lang-java prettyprint-override"><code>KieContainer kieContainer = KieHelper.getKieContainer(ks.newReleaseId("org.kie", "dmn-test-"+UUID.randomUUID(), "1.2"));
DMNRuntime dmnRuntime = kieContainer.newKieSession().getKieRuntime(DMNRuntime.class);
((DMNRuntimeImpl) dmnRuntime).setOption(new RuntimeTypeCheckOption(true));
DMNResult result = dmnRuntime.evaluateAll(dmnModel, context);
</code>```

答:
It would be best advised not to (un)marshall and not to having to compile the DMN file manually; instead to use the standard means of standard build of KieContainer from the KJAR; as detailed by the user guide in the documentation.

In other words, this works correctly with your DMN file:

```<code>KieServices kieServices = KieServices.Factory.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
DMNRuntime dmnRuntime = KieRuntimeFactory.of(kieContainer.getKieBase()).get(DMNRuntime.class);
DMNModel dmnModel = dmnRuntime.getModel(namespace, modelName);
DMNContext context = dmnRuntime.newContext();
((DMNRuntimeImpl) dmnRuntime).setOption(new RuntimeTypeCheckOption(true));
DMNResult result = dmnRuntime.evaluateAll(dmnModel, context);
</code>```

producing 9 as a result.

If you really want to use the KieHelper anyway, it is best advised to pass in the DMN file as a KieResource, to the call of KieHelper.getKieContainer(...), for example this:

```<code>KieContainer kieContainer = KieHelper.getKieContainer(ks.newReleaseId("org.kie", "dmn-test-" + UUID.randomUUID(), "1.2"),
                                                      ks.getResources().newFileSystemResource(new File(dmnFile)));
DMNRuntime dmnRuntime = KieRuntimeFactory.of(kieContainer.getKieBase()).get(DMNRuntime.class);
((DMNRuntimeImpl) dmnRuntime).setOption(new RuntimeTypeCheckOption(true));
DMNModel dmnModel = dmnRuntime.getModel(namespace, modelName);
DMNContext context = dmnRuntime.newContext();
DMNResult result = dmnRuntime.evaluateAll(dmnModel, context);
System.out.println(result);
</code>```

you can change the call ks.getResources().newFileSystemResource(...) to a URL, ClassPath, Byte, ... -based resource as needed, based on your use-case. This way the KieHelper will be in charge of unmarshalling

Also this second snippet works for me with your DMN file, producing 9 as a result.

The problem in your code is the initialisation of the DMNCompiler is not really meant to be invoked manually by the user, and in fact nowhere in the documentation there is a requirement to manage this manually; both the above methods would delegate this to the internals of the KieContainer/KieHelper, which would be the standard way.

I would advice to follow the KieContainer build as detailed in the documentation as in the former example, but I hope this answer help you resolve for you either way --locally both working for me.

Hope this helps!

Body:
I want to evaluate in Drools 7.21 FEEL-funtions that are new in DMN 1.2, like sqrt() or modulo(), but the method

dmnRuntime.evaluateAll(dmnModel,context)

is allways returning the value 'null' (just for the new functions) with status 'SUCCESS'. What do I do wrong or what is missing?

The DMN-File looks like this:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<semantic:definitions xmlns:semantic="http://www.omg.org/spec/DMN/20180521/MODEL/" xmlns="http://www.trisotech.com/definitions/_56fd6445-ff6a-4c28-8206-71fce7f80436" xmlns:feel="http://www.omg.org/spec/FEEL/20140401" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" exporter="DMN Modeler" exporterVersion="6.0.1" id="_56fd6445-ff6a-4c28-8206-71fce7f80436" name="Sqrt-Function" namespace="http://www.trisotech.com/definitions/_56fd6445-ff6a-4c28-8206-71fce7f80436" >
  <semantic:decision id="_cf6124bd-9907-4ac0-b4fd-59a962dbc502" name="square_root">
    <semantic:variable id="_edaf978e-3634-4e52-8244-5fd4e16fd257" name="square_root" typeRef="feel:number"/>
    <semantic:literalExpression id="_c990c3b2-e322-4ef9-931d-79bcdac99686">
      <semantic:text>sqrt(81)</semantic:text>
    </semantic:literalExpression>
  </semantic:decision>
</semantic:definitions>

After importing the file in "dmnModel":

DMNMarshaller marshaller = new org.kie.dmn.backend.marshalling.v1x.XStreamMarshaller();
FileInputStream fis = new FileInputStream( dmnFile );
Definitions unmarshal = marshaller.unmarshal( new InputStreamReader( fis ) );
DMNCompiler compiler = DMNFactory.newCompiler();
DMNModel dmnModel = compiler.compile(unmarshal);

I call the Drools-evaluation like this:

KieContainer kieContainer = KieHelper.getKieContainer(ks.newReleaseId("org.kie", "dmn-test-"+UUID.randomUUID(), "1.2"));
DMNRuntime dmnRuntime = kieContainer.newKieSession().getKieRuntime(DMNRuntime.class);
((DMNRuntimeImpl) dmnRuntime).setOption(new RuntimeTypeCheckOption(true));
DMNResult result = dmnRuntime.evaluateAll(dmnModel, context);

Body:
It would be best advised not to (un)marshall and not to having to compile the DMN file manually; instead to use the standard means of standard build of KieContainer from the KJAR; as detailed by the user guide in the documentation.

In other words, this works correctly with your DMN file:

KieServices kieServices = KieServices.Factory.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
DMNRuntime dmnRuntime = KieRuntimeFactory.of(kieContainer.getKieBase()).get(DMNRuntime.class);
DMNModel dmnModel = dmnRuntime.getModel(namespace, modelName);
DMNContext context = dmnRuntime.newContext();
((DMNRuntimeImpl) dmnRuntime).setOption(new RuntimeTypeCheckOption(true));
DMNResult result = dmnRuntime.evaluateAll(dmnModel, context);

producing 9 as a result.

If you really want to use the KieHelper anyway, it is best advised to pass in the DMN file as a KieResource, to the call of KieHelper.getKieContainer(...), for example this:

KieContainer kieContainer = KieHelper.getKieContainer(ks.newReleaseId("org.kie", "dmn-test-" + UUID.randomUUID(), "1.2"),
                                                      ks.getResources().newFileSystemResource(new File(dmnFile)));
DMNRuntime dmnRuntime = KieRuntimeFactory.of(kieContainer.getKieBase()).get(DMNRuntime.class);
((DMNRuntimeImpl) dmnRuntime).setOption(new RuntimeTypeCheckOption(true));
DMNModel dmnModel = dmnRuntime.getModel(namespace, modelName);
DMNContext context = dmnRuntime.newContext();
DMNResult result = dmnRuntime.evaluateAll(dmnModel, context);
System.out.println(result);

you can change the call ks.getResources().newFileSystemResource(...) to a URL, ClassPath, Byte, ... -based resource as needed, based on your use-case. This way the KieHelper will be in charge of unmarshalling

Also this second snippet works for me with your DMN file, producing 9 as a result.

The problem in your code is the initialisation of the DMNCompiler is not really meant to be invoked manually by the user, and in fact nowhere in the documentation there is a requirement to manage this manually; both the above methods would delegate this to the internals of the KieContainer/KieHelper, which would be the standard way.

I would advice to follow the KieContainer build as detailed in the documentation as in the former example, but I hope this answer help you resolve for you either way --locally both working for me.

Hope this helps!


问:
class not found autoloading psr-4
I am learning the Composer autoloading. I have some issues with PSR-4.

I am following this tutorial: https://vegibit.com/composer-autoloading-tutorial/

I have reviewed the code a few hours but I keep having the same issue when I load the script in the browser:

Fatal error: Uncaught Error: Class 'VegibitLibraryGreeting' not found
  in C:\PHPWebPages\aldemo\aldemo4\index.php:5 Stack trace: #0 {main}
  thrown in C:\PHPWebPages\aldemo\aldemo4\index.php on line 5

I have tried several solutions proposed in similar questions but I haven't solved it yet.

I attach some screenshots:

Please could someone help me finding out why is happening this error.
Thank in advance.

Notes:

I am going to show the new code after the solution to allow anyone that will have the same issue can review the solution:

答:
greeting.php:

You can't declare two namespaces in the same file. Namespace declaration should be in the very beginning of PHP file.
You also should declare namespaces as they are presented in composer.json:

```<code>namespace Vegibit\Library;
</code>```

Split this code to separate files.

index.php:

```<code>$vb = new Vegibit\Library\Greeting();
</code>```

Title: class not found autoloading psr-4

Body:
greeting.php:

You can't declare two namespaces in the same file. Namespace declaration should be in the very beginning of PHP file.
You also should declare namespaces as they are presented in composer.json:

namespace Vegibit\Library;

Split this code to separate files.

index.php:

$vb = new Vegibit\Library\Greeting();


问:
Android : Compare two ArrayList of objects and find unmatching ids from the second ArrayList
I want to compare two ArrayList of objects and find the unmatching values from the second ArrayList based on the ids in the object.

For Example:

Person.java

```<code>private int id;
private String name;
private String place;
</code>```

MainActivity.java:

```<code>ArrayList<Person> arrayList1 = new ArrayList<Person>();
arrayList1.add(new Person(1,"name","place"));
arrayList1.add(new Person(2,"name","place"));
arrayList1.add(new Person(3,"name","place"));

ArrayList<Person> arrayList2 = new ArrayList<Person>();
arrayList2.add(new Person(1,"name","place"));
arrayList2.add(new Person(3,"name","place"));
arrayList2.add(new Person(5,"name","place"));
arrayList2.add(new Person(6,"name","place"));
</code>```

I want to compare the arrayList1, arrayList2 and need to find the unmatching values from the arrayList2.
I need the id values 5,6.

How can I do this?

答:
arrayListChars=new ArrayList<>();  //[M,A,R,V,E,L]

arrayListAddChars=new ArrayList<>(); //[M,A,....coming values]

int count = 0;

for(int i=0;i

if(arrayListAddChars.get(i).equals(arrayListChars.get(i))){

```<code>    count++;
   }
    else
    {
     break;
    }
  }
</code>```

Body:
I want to compare two ArrayList of objects and find the unmatching values from the second ArrayList based on the ids in the object.

For Example:

Person.java

private int id;
private String name;
private String place;

MainActivity.java:

ArrayList<Person> arrayList1 = new ArrayList<Person>();
arrayList1.add(new Person(1,"name","place"));
arrayList1.add(new Person(2,"name","place"));
arrayList1.add(new Person(3,"name","place"));

ArrayList<Person> arrayList2 = new ArrayList<Person>();
arrayList2.add(new Person(1,"name","place"));
arrayList2.add(new Person(3,"name","place"));
arrayList2.add(new Person(5,"name","place"));
arrayList2.add(new Person(6,"name","place"));

I want to compare the arrayList1, arrayList2 and need to find the unmatching values from the arrayList2.
I need the id values 5,6.

How can I do this?

Body:
arrayListChars=new ArrayList<>();  //[M,A,R,V,E,L]

arrayListAddChars=new ArrayList<>(); //[M,A,....coming values]

int count = 0;

for(int i=0;i

if(arrayListAddChars.get(i).equals(arrayListChars.get(i))){

    count++;
   }
    else
    {
     break;
    }
  }


问:
Find duplicate for a combination of rows - Oracle SQL
I have a table:

table1

```<code>unique_id       user_id   user_seq      col_name            value_val    position
1               100       1             test1               100          1
1               100       1             test2               123          1
1               100       1             test1               a            2
1               100       1             test2               text         2
1               100       1             test3               1Rw          2
1               100       1             test4               1Tes         2

2               101       1             test1               1            1
2               101       1             test2               1            1
2               101       1             test3               1            1
2               101       1             test4               1            1
2               101       1             test5               1            1

3               100       1             test1               100          1
3               100       1             test2               123          1
3               100       1             test1               a            2
3               100       1             test2               text         2
3               100       1             test3               1Rw          2
3               100       1             test4               1Tes         2

4               101       1             test1               1            1
4               101       1             test2               1            1
4               101       1             test3               1            1
4               101       1             test4               1            1
</code>```

I need to find duplicate based on the following:

user_id, user_seq, col_name, value_val and position should be exactly same for different unique_id.

In the above example, unique_id - 1 and 3 are EXACTLY same, so they should be returned as output.

For unique_id = 2 and 4, there is a difference of test5 not available for unique_id = 4, so it won't be captured.

Output would be:

```<code>unique_id
1
3
</code>```

Also, my dataset is huge, around 50 million records, so need an optimized solution. Any help?

EDIT

My table structure:

```<code>Name        Null? Type
----------- ----- --------------
UNIQUE_ID          NUMBER
USER_SEQ           VARCHAR2(100)
COL_NAME           VARCHAR2(263)
VALUE_VAL          VARCHAR2(4000)
POSITION           NUMBER
USER_ID            NUMBER
</code>```

No indexes available.

答:
Assuming that you can concatenate the values into strings, perhaps the simplest method is:

```<code>select *
from (select unique_id, count(*) over (partition by vals) as cnt
      from (select unique_id,
                   listagg(user_id || ':' || user_seq || ':' || col_name || ':' || value_val || ':' || position, ',') within group (order by user_id, user_seq, col_name, value_val, position) as vals
            from sample_data sd
            group by unique_id
           ) sd
      ) sd
where cnt > 1;
</code>```

Here is a db<>fiddle.

Let me emphasize:  This is not a generic solution, because of internal string length limitations in Oracle.  But it works for you data and may be a convenient solution for your problem.

Body:
I have a table:

table1

unique_id       user_id   user_seq      col_name            value_val    position
1               100       1             test1               100          1
1               100       1             test2               123          1
1               100       1             test1               a            2
1               100       1             test2               text         2
1               100       1             test3               1Rw          2
1               100       1             test4               1Tes         2

2               101       1             test1               1            1
2               101       1             test2               1            1
2               101       1             test3               1            1
2               101       1             test4               1            1
2               101       1             test5               1            1

3               100       1             test1               100          1
3               100       1             test2               123          1
3               100       1             test1               a            2
3               100       1             test2               text         2
3               100       1             test3               1Rw          2
3               100       1             test4               1Tes         2

4               101       1             test1               1            1
4               101       1             test2               1            1
4               101       1             test3               1            1
4               101       1             test4               1            1

I need to find duplicate based on the following:

user_id, user_seq, col_name, value_val and position should be exactly same for different unique_id.

In the above example, unique_id - 1 and 3 are EXACTLY same, so they should be returned as output.

For unique_id = 2 and 4, there is a difference of test5 not available for unique_id = 4, so it won't be captured.

Output would be:

unique_id
1
3

Also, my dataset is huge, around 50 million records, so need an optimized solution. Any help?

EDIT

My table structure:

Name        Null? Type
----------- ----- --------------
UNIQUE_ID          NUMBER
USER_SEQ           VARCHAR2(100)
COL_NAME           VARCHAR2(263)
VALUE_VAL          VARCHAR2(4000)
POSITION           NUMBER
USER_ID            NUMBER

No indexes available.

Body:
Assuming that you can concatenate the values into strings, perhaps the simplest method is:

select *
from (select unique_id, count(*) over (partition by vals) as cnt
      from (select unique_id,
                   listagg(user_id || ':' || user_seq || ':' || col_name || ':' || value_val || ':' || position, ',') within group (order by user_id, user_seq, col_name, value_val, position) as vals
            from sample_data sd
            group by unique_id
           ) sd
      ) sd
where cnt > 1;

Here is a db<>fiddle.

Let me emphasize:  This is not a generic solution, because of internal string length limitations in Oracle.  But it works for you data and may be a convenient solution for your problem.