首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Android中使用Google Books API

在Android中使用Google Books API
EN

Stack Overflow用户
提问于 2013-01-29 05:22:31
回答 2查看 11.8K关注 0票数 6

大家好,我是Android新手,也是使用web API的新手。我目前正在编写一个应用程序,可以扫描一本书中的条形码,然后在Google Books中搜索它。

到目前为止,我在我的应用程序中实现了Scandit,并从Google API控制台为Books API注册并获得了API密钥。从那时起,我不知道如何继续并开始编码。从我的理解来看,它需要我通过uri请求数据,但我被困在如何实际编码的问题上。我想知道是否有人可以给我指出正确的方向,或者提供一个示例代码来说明如何使用URI获取数据。

我还下载了zipped Book API Jar libraries,我需要使用这个吗?我之所以这样问,是因为这个网站上Google Places API上的一个问题,其中一个答案说,你所需要的就是使用Google API作为构建目标,它不需要任何Jar文件,但这也适用于Books API吗?

另外,我正在使用Eclipse,我应该将构建目标设置为Google APIs 16吗?我猜这是正确的,因为我计划在未来使用谷歌地图与这个应用程序。

谢谢,这是我第一次在这里提问。

EN

回答 2

Stack Overflow用户

发布于 2013-05-10 06:19:28

我刚做完这件事。这就是我如何使用HttpURLConnectionAsyncTask实现它的(我只是调用“https://www.googleapis.com/books/v1/volumes?q=isbn:”+您的JSON并解析JSON):

代码语言:javascript
复制
// Received ISBN from Barcode Scanner. Send to GoogleBooks to obtain book information.
class GoogleApiRequest extends AsyncTask<String, Object, JSONObject>{

    @Override
    protected void onPreExecute() {
        // Check network connection.
        if(isNetworkConnected() == false){
            // Cancel request.
            Log.i(getClass().getName(), "Not connected to the internet");
            cancel(true);
            return;
        }
    }
    @Override
    protected JSONObject doInBackground(String... isbns) {
        // Stop if cancelled
        if(isCancelled()){
            return null;
        }

        String apiUrlString = "https://www.googleapis.com/books/v1/volumes?q=isbn:" + isbns[0];
        try{
            HttpURLConnection connection = null;
            // Build Connection.
            try{
                URL url = new URL(apiUrlString);
                connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("GET");
                connection.setReadTimeout(5000); // 5 seconds
                connection.setConnectTimeout(5000); // 5 seconds
            } catch (MalformedURLException e) {
                // Impossible: The only two URLs used in the app are taken from string resources.
                e.printStackTrace();
            } catch (ProtocolException e) {
                // Impossible: "GET" is a perfectly valid request method.
                e.printStackTrace();
            }
            int responseCode = connection.getResponseCode();
            if(responseCode != 200){
                Log.w(getClass().getName(), "GoogleBooksAPI request failed. Response Code: " + responseCode);
                connection.disconnect();
                return null;
            }

            // Read data from response.
            StringBuilder builder = new StringBuilder();
            BufferedReader responseReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line = responseReader.readLine();
            while (line != null){
                builder.append(line);
                line = responseReader.readLine();
            }
            String responseString = builder.toString();
            Log.d(getClass().getName(), "Response String: " + responseString);
            JSONObject responseJson = new JSONObject(responseString);
            // Close connection and return response code.
            connection.disconnect();
            return responseJson;
        } catch (SocketTimeoutException e) {
            Log.w(getClass().getName(), "Connection timed out. Returning null");
            return null;
        } catch(IOException e){
            Log.d(getClass().getName(), "IOException when connecting to Google Books API.");
            e.printStackTrace();
            return null;
        } catch (JSONException e) {
            Log.d(getClass().getName(), "JSONException when connecting to Google Books API.");
            e.printStackTrace();
            return null;
        }
    }
    @Override
    protected void onPostExecute(JSONObject responseJson) {
        if(isCancelled()){
            // Request was cancelled due to no network connection.
            showNetworkDialog();
        } else if(responseJson == null){
            showSimpleDialog(getResources().getString(R.string.dialog_null_response));
        }
        else{
            // All went well. Do something with your new JSONObject.
        }
    }
}

protected boolean isNetworkConnected(){

    // Instantiate mConnectivityManager if necessary
    if(mConnectivityManager == null){
        mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    }
    // Is device connected to the Internet?
    NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
    if(networkInfo != null && networkInfo.isConnected()){
        return true;
    } else {
        return false;
    }
}

我省略了对话框方法的代码,因为它们不相关。希望这能有所帮助。

票数 7
EN

Stack Overflow用户

发布于 2017-07-10 03:40:04

要在HTTP级别直接访问Google Books API或任何其他REST,如果您愿意编写异步代码,则可以使用Volley;对于更简单的同步请求,可以使用OkHttp。还有Android Asynchronous Http Client

但更好的是,您可以使用FeignRetrofit抽象出HTTP级别的实现细节,并在自动生成的实现之上提供流畅的类型安全API。Retrofit是the most used network library in Android,但在更广泛的Java生态系统中更多地使用Feign。

这是一个使用Feign for Google Books API的例子,Retrofit非常相似。

接口,实现由Feign自动生成:

代码语言:javascript
复制
public interface GoogleBooksApi {

    @RequestLine("GET /books/v1/volumes")
    Results findBookByISBN(@QueryMap Map<String, Object> queryParameters);

}

应用编程接口客户端代码

代码语言:javascript
复制
public class BookLookupService {

    public Book fetchBookByISBN(String isbn) throws BookLookupException {
        final GoogleBooksApi googleBooksApi = connect();
        final Map<String, Object> queryParameters = new HashMap<>();
        queryParameters.put("q", "isbn:" + isbn);
        final Results apiResponse = googleBooksApi.findBookByISBN(queryParameters);
        if (apiResponse == null || apiResponse.getTotalItems() < 1) {
            throw new BookLookupException("No books found for ISBN " + isbn);
        }
        final List<Result> results = apiResponse.getItems();
        if (results == null || results.size() < 1) {
            throw new BookLookupException("Invalid items list for ISBN " + isbn);
        }
        final Book book = results.get(0).getBook();
        return book;
    }

    private static GoogleBooksApi connect() {
        return Feign.builder()
            .decoder(new GsonDecoder())
            .logger(new Logger.ErrorLogger())
            .logLevel(Logger.Level.BASIC)
            .target(GoogleBooksApi.class, "https://www.googleapis.com");
    }
}

响应结构建模的API实体

代码语言:javascript
复制
public class Results {
    int totalItems;
    List<Result> items;

    public int getTotalItems() {
        return totalItems;
    }

    public List<Result> getItems() {
        return items;
    }
}

public class Result {
    // the JSON field is named volumeInfo
    Book volumeInfo;

    public Book getBook() {
        return volumeInfo;
    }
}

public class Book {
    private String title;
    private List<String> authors;

    public String getTitle() {
        return title;
    }

    public List<String> getAuthors() {
        return authors;
    }
}

最后同样重要的是,测试

代码语言:javascript
复制
@RunWith(AndroidJUnit4.class)
public class BookLookupServiceAndroidTest {
    private BookLookupService bookLookupService = new BookLookupService();

    @Test
    public void whenMultipleLookupResultsThenReturnsFirst() throws Exception {
        assertThat(bookLookupService.fetchBookByISBN("9780321356680").getTitle(),
                   is(equalTo("Effective Java, 2nd Edition")));
    }
}

请注意,您需要将代码包装在AsyncTask中以使其成为异步的,因为主线程上不允许网络请求。AsyncTask应该会更新onPostExecute()中的UI。

下面是一个例子:

代码语言:javascript
复制
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        final Button fetchBookButton = (Button) findViewById(R.id.FetchBookButton);
        fetchBookButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) { new FetchBookTask().execute(getISBN()); }
        });
    }

    private String getISBN() {
        final EditText isbnField = (EditText) findViewById(R.id.BookIsbnField);
        return isbnField.getText().toString();
    }

    private void showMessage(String message) {
        Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
    }

    class FetchBookTask extends AsyncTask<String, Void, Book> {

        @Override
        protected Book doInBackground(String... params) {
            final String isbn = params[0];
            try {
                return new BookLookupService().fetchBookByISBN(isbn);
            } catch (Exception e) {
                Log.e("fetchBookByISBN", e.toString());
                return null;
            }
        }

        @Override
        protected void onPostExecute(Book book) {
            if (book != null) {
                showMessage("Got book: " + book.getTitle());
            } else {
                showMessage("Failed to fetch book");
            }
        }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14571478

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档