使用改进版在Android中使用PHP和MySQL开发的RESTful API
我正在开发一个android应用程序,通过改造访问RESTAPI API使用PHP和MySQL PHP文件如下所示: index.php使用改进版在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); //
<?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();
?>
同时关闭防火墙。
祝你们今天愉快,伙计们