使用改进版在Android中使用PHP和MySQL开发的RESTful API

使用改进版在Android中使用PHP和MySQL开发的RESTful API,php,android,mysql,rest,retrofit,Php,Android,Mysql,Rest,Retrofit,我正在开发一个android应用程序,通过改造访问RESTAPI API使用PHP和MySQL PHP文件如下所示: index.php <?php $servername = "localhost"; $username = "root"; $password = ""; $dbname = "bookdb"; // Create connection $conn = new mysqli($servername, $username, $password, $dbname); //

我正在开发一个android应用程序,通过改造访问RESTAPI

API使用PHP和MySQL

PHP文件如下所示:

index.php

<?php 
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "bookdb";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT * FROM books";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    echo '{"books":[';

        $first = true; 
        while($row=$result->fetch_assoc()){
        //  cast results to specific data types

            if($first) {
                $first = false;
            } else {
                echo ',';
            }
            echo json_encode($row);
        }
        echo ']}'; 
} else {
    echo "0 results";
}
$conn->close();
?>
<?php 
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "bookdb";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT * FROM books";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    echo '[';

        $first = true; 
        while($row=$result->fetch_assoc()){
        //  cast results to specific data types

            if($first) {
                $first = false;
            } else {
                echo ',';
            }
            echo json_encode($row);
        }
        echo ']'; 
} else {
    echo "0 results";
}
$conn->close();
?>
这是预期的输出

现在我尝试在Android中使用改型:

BookListActivity.java

package com.example.android.taskapp;

import android.content.Context;
import android.database.Cursor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;

import com.example.android.taskapp.api.ApiInterface;
import com.example.android.taskapp.model.Book;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import retrofit.Callback;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.client.Response;

public class BookListActivity extends AppCompatActivity {

static final String API_URL = "http://192.168.0.104:8080/books";
ListView books_listview;
RestAdapter restAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_book_list);
    books_listview = (ListView) findViewById(R.id.books_listview);

    restAdapter = new RestAdapter.Builder().setEndpoint(API_URL).build();
    ApiInterface methods = restAdapter.create(ApiInterface.class);

    Callback cb = new Callback() {
        @Override
        public void success(Object o, Response response) {
            List<Book> books = (List<Book>) o;
            //Log.v("BookListActivity", booksString);
            //TypeToken<List<Book>> token = new TypeToken<List<Book>>() {};
            //List<Book> books = new Gson().fromJson(booksString, token.getType());

            List<HashMap<String,Object>> bookMapList = new ArrayList<>();
            for(Book b: books){
                HashMap<String, Object> bookmap = new HashMap<>();

                try {
                    bookmap.put(b.getClass().getField("author").getName(),b.getAuthor());
                    bookmap.put(b.getClass().getField("categories").getName(),b.getCategories());
                    bookmap.put(b.getClass().getField("lastCheckedOut").getName(),b.getLastCheckedOut());
                    bookmap.put(b.getClass().getField("lastCheckedOutBy").getName(),b.getLastCheckedOutBy());
                    bookmap.put(b.getClass().getField("publisher").getName(),b.getPublisher());
                    bookmap.put(b.getClass().getField("title").getName(),b.getTitle());
                    bookmap.put(b.getClass().getField("url").getName(),b.getUrl());
                    bookMapList.add(bookmap);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
            }
            SimpleAdapter adapter = new SimpleAdapter(getApplication(), bookMapList, R.layout.list_item_book,
                    new String [] {"title", "author"},new int [] {R.id.book_title, R.id.book_author});

            books_listview.setAdapter(adapter);
        }

        @Override
        public void failure(RetrofitError error) {
            Log.e("BookListActivity", error.getMessage() +"\n"+ error.getStackTrace());
            error.printStackTrace();
        }
    };
    methods.getBooks(cb);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_book_list, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}
public class BookListActivity extends AppCompatActivity {

static final String API_URL = "http://192.168.0.104/books";
ListView books_listview;
RestAdapter restAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_book_list);
    books_listview = (ListView) findViewById(R.id.books_listview);

    OkHttpClient mOkHttpClient = new OkHttpClient();
    mOkHttpClient.setConnectTimeout(15000,TimeUnit.MILLISECONDS);
    mOkHttpClient.setReadTimeout(15000,TimeUnit.MILLISECONDS);

    restAdapter = new RestAdapter.Builder()
            .setEndpoint(API_URL)
            .setClient(new OkClient(mOkHttpClient))
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .build();
    ApiInterface methods = restAdapter.create(ApiInterface.class);

    Callback<List<Book>> cb = new Callback<List<Book>>() {
        @Override
        public void success(List<Book> books, Response response) {
            //Log.v("BookListActivity", booksString);
            //TypeToken<List<Book>> token = new TypeToken<List<Book>>() {};
            //List<Book> books = new Gson().fromJson(booksString, token.getType());

            List<HashMap<String,Object>> bookMapList = new ArrayList<>();
            for(Book b: books){
                HashMap<String, Object> bookmap = new HashMap<>();

                try {

                    bookmap.put(b.getClass().getField("book_id").getName(),b.getBook_id());
                    bookmap.put(b.getClass().getField("author").getName(),b.getAuthor());
                    bookmap.put(b.getClass().getField("categories").getName(),b.getCategories());
                    bookmap.put(b.getClass().getField("lastCheckedOut").getName(),b.getLastCheckedOut());
                    bookmap.put(b.getClass().getField("lastCheckedOutBy").getName(),b.getLastCheckedOutBy());
                    bookmap.put(b.getClass().getField("publisher").getName(),b.getPublisher());
                    bookmap.put(b.getClass().getField("title").getName(),b.getTitle());
                    bookmap.put(b.getClass().getField("url").getName(),b.getUrl());
                    bookMapList.add(bookmap);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
            }
            SimpleAdapter adapter = new SimpleAdapter(getApplication(), bookMapList, R.layout.list_item_book,
                    new String [] {"title", "author"},new int [] {R.id.book_title, R.id.book_author});

            books_listview.setAdapter(adapter);
        }

        @Override
        public void failure(RetrofitError error) {
            Log.e("BookListActivity", error.getMessage() +"\n"+ error.getStackTrace());
            error.printStackTrace();
        }
    };
    methods.getBooks(cb);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_book_list, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}
at methods.getbooksb;这条线

谁能告诉我我错过了什么

我已经尝试过寻找类似的答案,但没有任何帮助

我还在应用程序节点上方的清单中包含了所有必要的权限


非常感谢您的帮助。

在到处挖掘之后,我终于找到了解决问题的方法:

我错过的最大一件事是:

<uses-permission android:name="ANDROID.PERMISSION.INTERNET" />
应该是

<uses-permission android:name="android.permission.INTERNET" />
其他文件中有一些小更改:

BookListActivity.java

package com.example.android.taskapp;

import android.content.Context;
import android.database.Cursor;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;

import com.example.android.taskapp.api.ApiInterface;
import com.example.android.taskapp.model.Book;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import retrofit.Callback;
import retrofit.RestAdapter;
import retrofit.RetrofitError;
import retrofit.client.Response;

public class BookListActivity extends AppCompatActivity {

static final String API_URL = "http://192.168.0.104:8080/books";
ListView books_listview;
RestAdapter restAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_book_list);
    books_listview = (ListView) findViewById(R.id.books_listview);

    restAdapter = new RestAdapter.Builder().setEndpoint(API_URL).build();
    ApiInterface methods = restAdapter.create(ApiInterface.class);

    Callback cb = new Callback() {
        @Override
        public void success(Object o, Response response) {
            List<Book> books = (List<Book>) o;
            //Log.v("BookListActivity", booksString);
            //TypeToken<List<Book>> token = new TypeToken<List<Book>>() {};
            //List<Book> books = new Gson().fromJson(booksString, token.getType());

            List<HashMap<String,Object>> bookMapList = new ArrayList<>();
            for(Book b: books){
                HashMap<String, Object> bookmap = new HashMap<>();

                try {
                    bookmap.put(b.getClass().getField("author").getName(),b.getAuthor());
                    bookmap.put(b.getClass().getField("categories").getName(),b.getCategories());
                    bookmap.put(b.getClass().getField("lastCheckedOut").getName(),b.getLastCheckedOut());
                    bookmap.put(b.getClass().getField("lastCheckedOutBy").getName(),b.getLastCheckedOutBy());
                    bookmap.put(b.getClass().getField("publisher").getName(),b.getPublisher());
                    bookmap.put(b.getClass().getField("title").getName(),b.getTitle());
                    bookmap.put(b.getClass().getField("url").getName(),b.getUrl());
                    bookMapList.add(bookmap);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
            }
            SimpleAdapter adapter = new SimpleAdapter(getApplication(), bookMapList, R.layout.list_item_book,
                    new String [] {"title", "author"},new int [] {R.id.book_title, R.id.book_author});

            books_listview.setAdapter(adapter);
        }

        @Override
        public void failure(RetrofitError error) {
            Log.e("BookListActivity", error.getMessage() +"\n"+ error.getStackTrace());
            error.printStackTrace();
        }
    };
    methods.getBooks(cb);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_book_list, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}
public class BookListActivity extends AppCompatActivity {

static final String API_URL = "http://192.168.0.104/books";
ListView books_listview;
RestAdapter restAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_book_list);
    books_listview = (ListView) findViewById(R.id.books_listview);

    OkHttpClient mOkHttpClient = new OkHttpClient();
    mOkHttpClient.setConnectTimeout(15000,TimeUnit.MILLISECONDS);
    mOkHttpClient.setReadTimeout(15000,TimeUnit.MILLISECONDS);

    restAdapter = new RestAdapter.Builder()
            .setEndpoint(API_URL)
            .setClient(new OkClient(mOkHttpClient))
            .setLogLevel(RestAdapter.LogLevel.FULL)
            .build();
    ApiInterface methods = restAdapter.create(ApiInterface.class);

    Callback<List<Book>> cb = new Callback<List<Book>>() {
        @Override
        public void success(List<Book> books, Response response) {
            //Log.v("BookListActivity", booksString);
            //TypeToken<List<Book>> token = new TypeToken<List<Book>>() {};
            //List<Book> books = new Gson().fromJson(booksString, token.getType());

            List<HashMap<String,Object>> bookMapList = new ArrayList<>();
            for(Book b: books){
                HashMap<String, Object> bookmap = new HashMap<>();

                try {

                    bookmap.put(b.getClass().getField("book_id").getName(),b.getBook_id());
                    bookmap.put(b.getClass().getField("author").getName(),b.getAuthor());
                    bookmap.put(b.getClass().getField("categories").getName(),b.getCategories());
                    bookmap.put(b.getClass().getField("lastCheckedOut").getName(),b.getLastCheckedOut());
                    bookmap.put(b.getClass().getField("lastCheckedOutBy").getName(),b.getLastCheckedOutBy());
                    bookmap.put(b.getClass().getField("publisher").getName(),b.getPublisher());
                    bookmap.put(b.getClass().getField("title").getName(),b.getTitle());
                    bookmap.put(b.getClass().getField("url").getName(),b.getUrl());
                    bookMapList.add(bookmap);
                } catch (NoSuchFieldException e) {
                    e.printStackTrace();
                }
            }
            SimpleAdapter adapter = new SimpleAdapter(getApplication(), bookMapList, R.layout.list_item_book,
                    new String [] {"title", "author"},new int [] {R.id.book_title, R.id.book_author});

            books_listview.setAdapter(adapter);
        }

        @Override
        public void failure(RetrofitError error) {
            Log.e("BookListActivity", error.getMessage() +"\n"+ error.getStackTrace());
            error.printStackTrace();
        }
    };
    methods.getBooks(cb);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_book_list, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}
}
和index.php

<?php 
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "bookdb";
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);

// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
$sql = "SELECT * FROM books";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    echo '[';

        $first = true; 
        while($row=$result->fetch_assoc()){
        //  cast results to specific data types

            if($first) {
                $first = false;
            } else {
                echo ',';
            }
            echo json_encode($row);
        }
        echo ']'; 
} else {
    echo "0 results";
}
$conn->close();
?>
同时关闭防火墙。 祝你们今天愉快,伙计们