我正在制作一个用于生成OTP的应用程序,所以我使用了php和我的sql。WAMP 作为本地主机提供商。我的日志猫文件包含
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: org.json.JSONException: Value <br of type java.lang.String cannot be converted to JSONObject
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at org.json.JSON.typeMismatch(JSON.java:111)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at org.json.JSONObject.<init>(JSONObject.java:160)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at org.json.JSONObject.<init>(JSONObject.java:173)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at com.techrefic.app1611.MainActivity$2.onResponse(MainActivity.java:178)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at com.techrefic.app1611.MainActivity$2.onResponse(MainActivity.java:172)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:67)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at android.os.Handler.handleCallback(Handler.java:739)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at android.os.Handler.dispatchMessage(Handler.java:95)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at android.os.Looper.loop(Looper.java:148)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5417)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at java.lang.reflect.Method.invoke(Native Method)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
11-18 13:27:23.766 30362-30362/com.techrefic.app1611 W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
11-18 13:27:23.776 1620-1943/system_process W/InputMethodManagerService: Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@7b87dab attribute=null, token = android.os.BinderProxy@ba60539
11-18 13:27:26.741 1317-1603/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 5574322 , only wrote 5436064
11-18 13:28:00.085 1212-1272/? D/hwcomposer: hw_composer sent 84 syncs in 60s
11-18 13:29:00.061 1212-1272/? D/hwcomposer: hw_composer sent 4 syncs in 60s
XML 文件activity_main.xml包含:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.techrefic.app1611.MainActivity"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingLeft="24dp"
android:paddingRight="24dp"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<EditText
android:id="@+id/editTextEmail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:hint="Email"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editTextPassword"
android:inputType="textPassword"
android:hint="Password"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editTextPhone"
android:inputType="textEmailAddress"
android:hint="Mobile Number"/>
</android.support.design.widget.TextInputLayout>
<android.support.v7.widget.AppCompatButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/buttonRegister"
android:background="@color/colorPrimary"
android:textColor="#fff"
android:layout_marginTop="24dp"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:text="Register"
android:textSize="24sp"/>
<TextView android:id="@+id/linkLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:padding="12dp"
android:gravity="center"
android:text="Already have an account? Login here"
android:textSize="16sp"/>
</LinearLayout>
</ScrollView>
dialog_confirm.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="48dp"
android:paddingRight="24dp"
android:paddingBottom="24dp"
android:paddingLeft="24dp"
android:layout_marginTop="80dp"
android:layout_marginBottom="80dp"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:background="@color/colorAccent">
<TextView
android:layout_width="wrap_content"
android:text="Enter OTP"
android:layout_height="wrap_content" />
<EditText
android:id="@+id/editTextOtp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"/>
<android.support.v7.widget.AppCompatButton
android:id="@+id/buttonConfirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="24dp"
android:layout_marginTop="24dp"
android:background="@color/colorPrimary"
android:padding="12dp"
android:text="Confirm Otp"
android:textColor="#fff"
android:textSize="24sp"/>
</LinearLayout>
我的 Java 文件是 1。主要活动.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
// Creating views
private EditText editTextEmail;
private EditText editTextPassword;
private EditText editTextPhone;
private EditText editTextConfirmOtp;
private AppCompatButton buttonRegister;
private AppCompatButton buttonConfirm;
//Volley RequestQueue
private RequestQueue requestQueue;
//String variables to hold email, password and phone number
private String username;
private String password;
private String phone;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Initializing Views
editTextEmail = (EditText) findViewById(R.id.editTextEmail);
editTextPassword = (EditText) findViewById(R.id.editTextPassword);
editTextPhone = (EditText) findViewById(R.id.editTextPhone);
buttonRegister = (AppCompatButton) findViewById(R.id.buttonRegister);
//Initializing the RequestQueue
requestQueue = Volley.newRequestQueue(this);
//Adding a listener to button
buttonRegister.setOnClickListener((View.OnClickListener) this);
}
// This method would confirm the OTP
private void confirmOtp() throws JSONException {
//Creating a Layout Inflater object for the dialog box
LayoutInflater li = LayoutInflater.from(this);
//Creating a view to get the dialog box
View confirmDialog = li.inflate(R.layout.dialog_confirm, null);
// Initialing confirm button for dialog box and edittext of dialog box
buttonConfirm = (AppCompatButton) confirmDialog.findViewById(R.id.buttonConfirm);
editTextConfirmOtp = (EditText) confirmDialog.findViewById(R.id.editTextOtp);
//Creating an alert dialog builder
AlertDialog.Builder alert = new AlertDialog.Builder(this);
//Adding our dialog box to the view of alert dialog
alert.setView(confirmDialog);
//Creating an alert dialog
final AlertDialog alertDialog = alert.create();
//Displaying the alert dialog
alertDialog.show();
// Onclick of the confirm button from alert dialog
buttonConfirm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//Hiding the alert dialog
alertDialog.dismiss();
//Displaying a progressbar
final ProgressDialog loading = ProgressDialog.show(MainActivity.this, "Authenticating ", "Please wait while we check the entered code", false, false);
//Getting the user entered otp from edittext
final String otp = editTextConfirmOtp.getText().toString().trim();
//Creating an string request
StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.CONFIRM_URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
if (response.equalsIgnoreCase("success")) {
loading.dismiss();
//Start a new activity
startActivity(new Intent(MainActivity.this, Success.class));
} else {
//Displaying a toast if the otp entered is wrong
Toast.makeText(MainActivity.this, "Wrong OTP Please try Again", Toast.LENGTH_LONG).show();
try {
//Asking user to enter otp again
confirmOtp();
} catch (JSONException e) {
e.printStackTrace();
}
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
alertDialog.dismiss();
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
//Adding the parameters otp and email
params.put(Config.KEY_OTP, otp);
params.put(Config.KEY_USERNAME, username);
return params;
}
};
//Adding the request to the queue
requestQueue.add(stringRequest);
}
});
}
//this method will get register the user
private void register() {
//Displaying a progress dialog
final ProgressDialog loading = ProgressDialog.show(this, "Registering", "Please wait...", false, false);
//Getting user data
username = editTextEmail.getText().toString().trim();
password = editTextPassword.getText().toString().trim();
phone = editTextPhone.getText().toString().trim();
//Again creating the request
StringRequest stringRequest = new StringRequest(Request.Method.POST, Config.REGISTER_URL,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
loading.dismiss();
try {
//Creating the json object from the response
JSONObject jsonResponse = new JSONObject(response);
//IF it is success
if (jsonResponse.getString(Config.TAG_RESPONSE).equalsIgnoreCase("success")) {
//Asking user to confirm otp
confirmOtp();
} else {
//If not successful user may already have registerd
Toast.makeText(MainActivity.this, "Username or Phone Number already registered", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
loading.dismiss();
Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_LONG).show();
}
}) {
@Override
protected Map<String, String> getParams()throws AuthFailureError {
Map<String, String> params = new HashMap<>();
//Adding the params to the request
params.put(Config.KEY_USERNAME, username);
params.put(Config.KEY_PASSWORD, password);
params.put(Config.KEY_PHONE, phone);
return params;
}
};
//Adding request to the queue
requestQueue.add(stringRequest);
}
@Override
public void onClick(View v){
//calling refgister method on register button click
register();
}
}
和配置.java
public class Config {
public static final String REGISTER_URL = "http://192.168.0.4/famous/register.php";
public static final String CONFIRM_URL = "http://192.168.0.4/famous/confirm.php";
//Keys to send username, password, phone and otp
public static final String KEY_USERNAME = "username";
public static final String KEY_PASSWORD = "password";
public static final String KEY_PHONE = "phone";
public static final String KEY_OTP = "otp";
//JSON Tag from response from server
public static final String TAG_RESPONSE= "ErrorMessage";
}
我的 gradle 文件包含的依赖项是:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
compile 'com.android.support:design:26.1.0'
compile 'com.mcxiaoke.volley:library:1.0.19'
}
和我使用的PHP文件注册.php
<?php
// Constants for our API
// this is applicable only when you are using SMS API
define('SMSUSER', $_POST[username]);
define('PASSWORD', $_POST[password]);
define('PHONE', $_POST[phone]);
// define('SENDERID', 'EDCRTZ');
// This function will send the otp
$otp = int rand(100000, 999999);
// This is the sms text that will be sent via sms
$sms_content = "Welcome ".SMSUSER.", to DEMO Tp RTA app: Your verification code is".$otp ;
// This is the Actual API URL concatnated with required values
$api_url ="http://mymessageapi".$sms_content."&senderId=EDCRTZ&routeId=1&mobileNos=".PHONE."&smsContentType=english";
//Envoking the API url and getting the response
$response = file_get_contents($api_url);
//Returning the response
return $response;
//If a past request comes to this script
if ($_SERVER['REQUEST_METHOD']=='POST') {
// getting username password and phone number
$username = $_POST['username'];
$password = $_POST['password'];
$phone = $_POST['phone'];
//Generating a 6 digits OTP or verification code
$otp = rand(100000, 999999);
//Importing the db connection script
require_once('dbConnect.php');
//Creating an SQL Query
$sql = "INSERT INTO famous (username, password, phone, otp) values('$username','$password','$phone','$otp')";
//If the query executed on the db successfully
if (mysql_query($con,$sql)) {
// printing the failure message in json
echo '{"ErrorMessage":"Failure"}';
}
//Closing the databse connection
mysqli_close($con);
}
?>
确认.php
<?php
//If a post request is detected
if ($_SERVER['REQUEST_METHOD']=='POST') {
//gETTING THE username and otp
$username = $_POST['username'];
$otp = $_POST['otp'];
// Importing the dbConnect script
require_once('dbConnect.php');
//Creating an SQL to fetch the otp from the table
$sql = "SELECT otp FROM test-table WHERE username = '$username'";
//Getting the result array from databse
$result = mysqli_fetch_array(mysqli_query($con,$sql));
//Getting the otp from the array
$realotp = $result['otp'];
//Getting the otp given is equal to otp fetched from database
if ($otp == $realotp) {
// Creating an sql query to update the column verified to 1 for the specified user
$sql = "UPDATE test-table SET verified= '1' WHERE username ='$username'";
//If the table is updated
if (mysqli_query($con,$sql)) {
//displaying failure
echo 'success';
}else{
//displaying failure
echo "failure";
}
}else{
//displaying failure if otp is not equal to the otp fetched from databse
echo 'failure';
}
//Closing the database
mysql_close($con);
}
?>
dbConnect.php 文件
<?php
define('HOST', 'localhost');
define('USER', 'root');
define('PASS', '');
define('DB', 'famous');
//connecting to database
$con = mysqli_connect(HOST, USER, PASS, DB) or die('Unable to Connect');
?>
我使用我的 WAMP for localhost 服务器在本地运行我的应用程序,我的应用程序在同一个 IP 地址上,任何可以解决这个问题的人
在JSONObject jsonResponse = new JSONObject(response)
中,您正在从响应创建 JSON 对象,该对象不是有效的 JSON。
尝试在调试模式下查看response
值,以确定其中的内容,以及如何获取所需的实际 JSON。
您正在 php 中打印字符串,而不是回显 json 对象
更改您的确认.php代码
//If the table is updated
if (mysqli_query($con,$sql)) {
//displaying failure
echo 'success';
}else{
//displaying failure
echo "failure";
}
}else{
//displaying failure if otp is not equal to the otp fetched from databse
echo 'failure';
}
自
//If the table is updated
if (mysqli_query($con,$sql)) {
//displaying failure
echo json_encode(array('ErrorMessage'=>'success'));
}else{
//displaying failure
echo json_encode(array('ErrorMessage'=>'failure'));
}
}else{
//displaying failure if otp is not equal to the otp fetched from databse
echo json_encode(array('ErrorMessage'=>'failure'));
}
java.lang.String 无法转换为 JSONObject
问题来自
//Creating the json object from the response
JSONObject jsonResponse = new JSONObject(response); // print response.
- 首先确保您的
response
有效JSON
或不。 - 应
DEBUG
应用。 添加断点JSONObject jsonResponse
对于valid JSON
情况,您可以按照 MByD's Answer
.
public boolean isJSONValid(String test) {
try {
new JSONObject(test);
} catch (JSONException ex) {
try {
new JSONArray(test);
} catch (JSONException ex1) {
return false;
}
}
return true;
}