当我从index.php中删除HTML代码并且只保留php行之间时,我的代码工作正常。但是当我使用HTML行显示的时候 - 我需要应用程序的其他部分 - 它会给出错误:
“使用JsonReader.setLenient(true)接受第1行第1行路径上格式错误的JSON $”
我尝试过使用
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
但它给了我另一个错误:
“java.lang.IllegalStateException:预期BEGIN_OBJECT但在第1行第1行路径为STRING”
这是我的Logcat output
如何解决这个问题?!!!
FirstPOIPreference.java:
public class FirstPOIPreference extends DialogPreference {
private EditText et_alias, et_keyword, et_address;
private Spinner sp_city;
private ArrayAdapter<String> adapter;
private boolean deleted;
private Context context;
private SharedPreferences pref;
private POI poiDialog = new POI();
public FirstPOIPreference(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init();
}
private void init() {
setPersistent(false);
setDialogLayoutResource(R.layout.pref_poi_dialog);
setPositiveButtonText(android.R.string.ok);
setNegativeButtonText(android.R.string.cancel);
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
pref = PreferenceManager.getDefaultSharedPreferences(this.context);
load(getSharedPreferences());
initViews(view);
fillViews();
}
private void load(SharedPreferences prefs) {
poiDialog.setAlias(prefs.getString(Constants.FIRST_POI_ALIAS, ""));
poiDialog.setKeyword(prefs.getString(Constants.FIRST_POI_KEYWORD, ""));
poiDialog.setAddress(prefs.getString(Constants.FIRST_POI_ADDRESS, ""));
poiDialog.setCity((prefs.getString(Constants.FIRST_POI_CITY, "")));
}
private void initViews(View view) {
deleted = false;
TextView tv_delete = (TextView) view.findViewById(R.id.tv_poi_delete);
et_alias = (EditText) view.findViewById(R.id.et_poi_alias);
et_keyword = (EditText) view.findViewById(R.id.et_poi_keyword);
et_address = (EditText) view.findViewById(R.id.et_poi_address);
sp_city = (Spinner) view.findViewById(R.id.spinner_poi_city);
sp_city.setPrompt("City");
String[] arrayCity = new String[]{"Erie", "Pittsburgh", "Cleveland", "Buffalo", "Niagara Falls", "Jamestown"};
adapter = new ArrayAdapter <> (this.getContext(),
android.R.layout.simple_spinner_dropdown_item, arrayCity);
sp_city.setAdapter(adapter);
et_alias.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
poiDialog.setAlias(et_alias.getText().toString());
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
et_keyword.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
poiDialog.setKeyword(et_keyword.getText().toString());
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
et_address.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
poiDialog.setAddress(et_address.getText().toString());
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
sp_city.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView <?> parentView, View selectedItemView,
int position, long id) {
poiDialog.setCity(sp_city.getSelectedItem().toString());
}
@Override
public void onNothingSelected(AdapterView <?> parentView) {
}
});
tv_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder delete_builder = new AlertDialog.Builder(context);
delete_builder.setMessage("Are you sure you want to delete this point of interest?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(context, "Deleting POI !", Toast.LENGTH_LONG).show();
deletePOI();
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
AlertDialog alertDelete = delete_builder.create();
alertDelete.setTitle("Delete POI!");
alertDelete.show();
}
});
}
private void fillViews() {
et_alias.setText(poiDialog.getAlias());
et_keyword.setText(poiDialog.getKeyword());
et_address.setText(poiDialog.getAddress());
sp_city.setSelection(adapter.getPosition(poiDialog.getCity()));
}
@Override
protected void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
String alias, keyword, address, city;
if(deleted) {
et_alias.setText("");
et_keyword.setText("");
et_address.setText("");
sp_city.setPrompt("City");
} else {
alias = et_alias.getText().toString();
keyword = et_keyword.getText().toString();
address = et_address.getText().toString();
city = sp_city.getSelectedItem().toString();
if (!keyword.isEmpty() && !address.isEmpty() && !city.isEmpty()) {
Toast.makeText(context, "Saving POI !", Toast.LENGTH_LONG).show();
addPOI(alias, keyword, address, city);
} else {
Toast.makeText(context, "Required Fields are empty !", Toast.LENGTH_LONG).show();
}
}
}
}
private void addPOI(String alias, String keyword, String address, String city) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.retryOnConnectionFailure(true)
.connectTimeout(15, TimeUnit.SECONDS)
.build();
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
RequestInterface requestInterface = retrofit.create(RequestInterface.class);
User user = new User();
user.setEmail(pref.getString(Constants.USER_EMAIL, ""));
POI poi = new POI();
poi.setAlias(alias);
poi.setKeyword(keyword);
poi.setAddress(address);
poi.setCity(city);
ServerRequest request = new ServerRequest();
request.setOperation(Constants.ADD_POI);
request.setUser(user);
request.setPoi(poi);
Call <ServerResponse> response = requestInterface.operation(request);
response.enqueue(new Callback <ServerResponse>() {
@Override
public void onResponse(Call <ServerResponse> call,
retrofit2.Response <ServerResponse> response) {
ServerResponse resp = response.body();
if(resp.getResult().equals(Constants.SUCCESS)) {
Toast.makeText(context, resp.getMessage(), Toast.LENGTH_LONG).show();
SharedPreferences.Editor editor = getEditor();
save(editor);
} else {
Toast.makeText(context, resp.getMessage(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call <ServerResponse> call, Throwable t) {
Log.d(Constants.TAG, "failed");
Toast.makeText(context, t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
}
private void save(SharedPreferences.Editor editor) {
editor.putString(Constants.FIRST_POI_ALIAS, poiDialog.getAlias());
editor.putString(Constants.FIRST_POI_KEYWORD, poiDialog.getKeyword());
editor.putString(Constants.FIRST_POI_ADDRESS, poiDialog.getAddress());
editor.putString(Constants.FIRST_POI_CITY, poiDialog.getCity());
editor.apply();
}
private void deletePOI() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RequestInterface requestInterface = retrofit.create(RequestInterface.class);
User user = new User();
user.setEmail(pref.getString(Constants.USER_EMAIL, ""));
POI poi = new POI();
poi.setKeyword(pref.getString(Constants.FIRST_POI_KEYWORD, ""));
poi.setCity(pref.getString(Constants.FIRST_POI_CITY, ""));
ServerRequest request = new ServerRequest();
request.setOperation(Constants.DELETE_POI);
request.setUser(user);
request.setPoi(poi);
Call <ServerResponse> response = requestInterface.operation(request);
response.enqueue(new Callback <ServerResponse>() {
@Override
public void onResponse(Call <ServerResponse> call,
retrofit2.Response <ServerResponse> response) {
ServerResponse resp = response.body();
if(resp.getResult().equals(Constants.SUCCESS)) {
Toast.makeText(context, resp.getMessage(), Toast.LENGTH_LONG).show();
SharedPreferences.Editor editor = getEditor();
saveDelete(editor);
deleted = true;
} else {
Toast.makeText(context, resp.getMessage(), Toast.LENGTH_LONG).show();
}
}
@Override
public void onFailure(Call <ServerResponse> call, Throwable t) {
Log.d(Constants.TAG, "failed");
Toast.makeText(context, t.getLocalizedMessage(), Toast.LENGTH_LONG).show();
}
});
}
private void saveDelete(SharedPreferences.Editor editor) {
editor.putString(Constants.FIRST_POI_ALIAS, "");
editor.putString(Constants.FIRST_POI_KEYWORD, "");
editor.putString(Constants.FIRST_POI_ADDRESS, "");
editor.putString(Constants.FIRST_POI_CITY, "");
editor.apply();
}
}
的index.php:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<pre>
<?php
// dispaly all errors except Warnings
ini_set('display_errors',1);
error_reporting(E_ALL & ~E_WARNING);
include 'fetch_data.php';
require_once 'users/login.php';
require_once 'preferences/preferences.php';
require_once 'include/functions_validation.php';
$login = new Login();
$pref = new Preferences();
$fun = new FunctionsValidation();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$data = json_decode(file_get_contents("php://input"));
if(isset($data -> operation)) {
$operation = $data -> operation;
if(!empty($operation)) {
/*
* User registration and login operations
*/
if($operation == 'register') {
echo $login -> register($data);
}
else if ($operation == 'regVerify') {
echo $login -> registerVerify($data);
}
else if ($operation == 'login') {
echo $login -> login($data);
}
else if ($operation == 'chgPass') {
echo $login -> changePassword($data);
}
else if ($operation == 'resPassReq') {
echo $login -> resetPasswordReq($data);
}
else if ($operation == 'resPass') {
echo $login -> resetPassword($data);
}
/*
* Point of Interest operations
*/
else if($operation == 'addPOI') {
echo $pref -> addPOI($data);
}
else if($operation == 'deletePOI') {
echo $pref -> deletePOI($data);
}
/**
* Mileage Distance operations
*/
else if($operation == 'addMileage') {
echo $pref -> addMileage($data);
}
else if($operation == 'deleteMileage') {
echo $pref -> deleteMileage($data);
}
} else { // if operation is empty
echo $fun -> getMsgParamNotEmpty();
}
} else { // if operation is not set
echo $fun -> getMsgInvalidParam();
}
} else if ($_SERVER['REQUEST_METHOD'] == 'GET') {
echo "GeolocationNews API";
}
?>
</pre>
</body>
</html>
答案 0 :(得分:0)
Constants.BASE_URL
是否指向您的index.php
页面?
如果是这样,您正在尝试将HTML页面解析为JSON,这是无效的。我建议您从Android应用程序发送某种查询参数,您可以从PHP检查,以便HTML部分不包含在输出中。
假设您的Android应用程序将请求提交给index.php?output=json
,例如。然后在index.php中,您可以检查:
<?php
$jsonOnly = (isset($_GET['output']) && $_GET['output'] == 'json');
if (!$jsonOnly):
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<pre>
<?php
endif;
// your existing PHP code here
if (!$jsonOnly):
?>
</pre>
</body>
</html>
<?php
endif;
?>
编辑但是,我认为将逻辑与演示文稿分开会更好。如果您将所有PHP代码放在单独的文件中,例如handle_request.php
?然后在index.php中,您可以拥有所有HTML代码,然后包含该文件:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<pre>
<?php include('handle_request.php'); ?>
</pre>
</body>
</html>
对于您的应用,您可以创建一个用作Constants.BASE_URL
的其他文件,例如app.php
,它只会设置正确的JSON内容类型标头并包含相同的文件:< / p>
<?php
header('Content-Type: application/json');
include('handle_request.php');
?>