What's the detailed error message in the payload?
In Android Studio, only "APIService.ServiceException: Bad Request"
This is the code (Traccar Manager example in git hub), I did tests pointing to https://demo4.traccar.org/ and got the same error.
public class SendCommandFragment extends Fragment {
class CommandTypeDataHolder {
private String type;
private String name;
public CommandTypeDataHolder(String type, String name) {
this.type = type;
this.name = name;
}
@Override
public String toString() {
return name;
}
}
class CommandTypeAdapter extends ArrayAdapter<CommandTypeDataHolder> {
CommandTypeAdapter(List<CommandTypeDataHolder> items) {
super(getActivity(), R.layout.list_item, android.R.id.text1, items);
}
@Override
public View getView(int position, View convertView, ViewGroup container) {
View view = super.getView(position, convertView, container);
CommandTypeDataHolder commandTypeDataHolder = getItem(position);
TextView popupText = (TextView) view.findViewById(android.R.id.text1);
popupText.setText(commandTypeDataHolder.name);
view.setTag(commandTypeDataHolder.type);
return view;
}
}
private static Map<String, Integer> i10nMapping = new HashMap<>();
static {
i10nMapping.put(Command.TYPE_ALARM_ARM, R.string.command_alarm_arm);
i10nMapping.put(Command.TYPE_ALARM_DISARM, R.string.command_alarm_disarm);
i10nMapping.put(Command.TYPE_ENGINE_STOP, R.string.command_engine_stop);
i10nMapping.put(Command.TYPE_ENGINE_RESUME, R.string.command_engine_resume);
i10nMapping.put(Command.TYPE_POSITION_PERIODIC, R.string.command_position_periodic);
}
public static final String EXTRA_DEVICE_ID = "deviceId";
private Spinner commandsSpinner;
private LinearLayout frequencyGroup;
private EditText frequencyEditText;
private LinearLayout unitGroup;
private Spinner unitSpinner;
private View sendButton;
@Nullable
@Override
public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_send_command, container, false);
commandsSpinner = (Spinner) view.findViewById(R.id.commands);
frequencyGroup = (LinearLayout) view.findViewById(R.id.frequencyGroup);
frequencyEditText = (EditText) view.findViewById(R.id.frequency);
unitGroup = (LinearLayout) view.findViewById(R.id.unitGroup);
unitSpinner = (Spinner) view.findViewById(R.id.unit);
sendButton = (Button) view.findViewById(R.id.button_send);
frequencyGroup.setVisibility(View.GONE);
unitGroup.setVisibility(View.GONE);
commandsSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if(view.getTag().toString().equals(Command.TYPE_POSITION_PERIODIC)) {
frequencyGroup.setVisibility(View.VISIBLE);
unitGroup.setVisibility(View.VISIBLE);
} else {
frequencyGroup.setVisibility(View.GONE);
unitGroup.setVisibility(View.GONE);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
frequencyGroup.setVisibility(View.GONE);
unitGroup.setVisibility(View.GONE);
}
});
final long deviceId = getActivity().getIntent().getExtras().getLong(EXTRA_DEVICE_ID);
final MainApplication application = (MainApplication) getActivity().getApplication();
final WebService service = application.getService();
service.putCommands(deviceId).enqueue(new WebServiceCallback<List<CommandType>>(getContext()) {
@Override
public void onSuccess(Response<List<CommandType>> response) {
List<CommandTypeDataHolder> commandTypeDataHolders = new ArrayList<>();
for (CommandType commandType: response.body()) {
String name = getI10nString(commandType.getType());
commandTypeDataHolders.add(new CommandTypeDataHolder(commandType.getType(), name));
}
commandsSpinner.setAdapter(new CommandTypeAdapter(commandTypeDataHolders));
}
});
sendButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Command command = new Command();
command.setDeviceId(deviceId);
command.setType((String) commandsSpinner.getSelectedView().getTag());
if (command.getType().equals(Command.TYPE_POSITION_PERIODIC)) {
int value = 0;
try {
value = Integer.parseInt(frequencyEditText.getText().toString());
} catch (NumberFormatException e) {
Toast.makeText(getContext(), R.string.error_invalid_frequency, Toast.LENGTH_LONG).show();
return;
}
int multiplier = getResources().getIntArray(R.array.unit_values)[unitSpinner.getSelectedItemPosition()];
command.set(Command.KEY_FREQUENCY, value * multiplier);
}
final MainApplication application = (MainApplication) getActivity().getApplication();
final WebService service = application.getService();
service.sendCommand(command).enqueue(new WebServiceCallback<Command>(getContext()) {
@Override
public void onSuccess(Response<Command> response) {
Toast.makeText(getContext(), R.string.command_sent, Toast.LENGTH_LONG).show();
}
@Override
public void onFailure(Call<Command> call, Throwable t) {
super.onFailure(call, t);
Toast.makeText(getContext(), (new Gson().toJson(command) + "\n" + t.toString()),Toast.LENGTH_LONG).show();
}
});
getActivity().finish();
}
});
return view;
}
private String getI10nString(String key) {
String result = key;
Integer resId = i10nMapping.get(key);
if(resId != null) {
try {
CharSequence nameCharSequence = getContext().getResources().getText(resId);
result = nameCharSequence.toString();
} catch (Resources.NotFoundException e) {
Log.w(SendCommandFragment.class.getSimpleName(), e);
}
}
return result;
}
}
You have to check the payload.
Hello, I don't understand, my payload is:
{"attributes":{"frequency":5},"description":"5 sec","deviceId":143,"type":"positionPeriodic"}
I get this same bad request error in the traccar-manager-android-native app. I am not able to find the error in the tracer log for more information and in the debug mode of Android Studio neither. Is there a way to activate the more complete log to identify the error, or can you give me some more guidance? Thanks
I'm asking for response payload, not the request. I'm not asking for logs either.
I didn't get the payload of the response, I just get this in onFailure(Call<Command> call, Throwable t):
.APIService.ServiceException: Bad Request
There is always a payload if there's a "Bad Request" error. If you don't know how to see the payload, you should read the documentation on the tool you're using to send API requests and figure out how to do it. Once you know the payload, we can continue this conversation.
Hello, thanks to you I just learned a little more about Android Studio. What are you asking for this?
Account has limit sending commands - SecurityException (PermissionsManager:290 < CommandResource: 69 < ...)
It means what it says. Commands are restricted for the account or the server.
One more piece of information, with the same user logged in via the browser, the command is sent normally.
please, be clearer, I did not find this information that you posted, much less understood what you meant, especially when the same user manages to send the commands through the browser, but logged in through the app it does not send them. When you say restricted to the server, I understood even less and searching the traccar forum and the documentation, I didn't find anything about it. Thank you very much for your time.
There must be some difference.
Hello!
Bad request means that the server does not recognize the command because it is missing necessary data, or it is not in the correct format or data is missing.
try this way:
{id: 0, attributes: {"frequency":5}, deviceId: 143, type: "positionPeriodic", textChannel: false, description: "5 sec"}
Problem solved.
When sending the command requesting the saved commands for the desired device, as a response I get:
{
"id": 7,
"attributes": {
"frequency": 5
},
"deviceId": 128,
"type": "positionPeriodic",
"textChannel": false,
"description": "5 sec"
}
[
{
"id": 7,
"attributes": {
"frequency": 5
},
"deviceId": 0,
"type": "positionPeriodic",
"textChannel": false,
"description": "5 sec"
},
{
"id": 8,
"attributes": {
"frequency": 10
},
"deviceId": 0,
"type": "positionPeriodic",
"textChannel": false,
"description": "10 sec"
},
{
"id": 9,
"attributes": {
"frequency": 15
},
"deviceId": 0,
"type": "positionPeriodic",
"textChannel": false,
"description": "15 sec"
}
]
The id field needs to be saved to be sent correctly later.
The code had to be changed to store the id and when sending the command to be executed, send it with the same id, getting my request like this:
{
"id": 7,
"attributes": {
"frequency": 5
},
"deviceId": 130,
"type": "positionPeriodic",
"textChannel": false,
"description": "5 sec"
}
If you wish, I can send you the Traccar Manager Native code corrected with this implementation and working in the new version of android studio. Just let me know how to send it to you.
Hi, I'm trying to send commands saved by api, but I always get BAD Request as a response. I already downloaded the sample app and managed to run it, but it has the same error.
This is the function:
@POST("/api/commands/send") Call<Command> sendCommand(@Body Command command);
This is the json I send via post:
{"attributes":{"frequency":5},"description":"5 sec","deviceId":143,"type":"positionPeriodic"}
This is the error I get:
I'm asking for help, because I've already done all the tests and comparisons, but I haven't found the error.