• 12.3.3 使用JSON和位置提取Flickr图像


        可以对Flickr JSON示例进行更新以结合位置信息,方法是请求LocationManager的位置变化的通知时执行请求。当然,必须将位置添加到请求中,其中Flickr支持将它作为请求中查询字符串的一部分。

     1 package com.nthm.androidtestActivity;
     2 
     3 import java.io.BufferedReader;
     4 import java.io.IOException;
     5 import java.io.InputStream;
     6 import java.io.InputStreamReader;
     7 import java.net.HttpURLConnection;
     8 import java.net.MalformedURLException;
     9 import java.net.URL;
    10 import org.apache.http.HttpEntity;
    11 import org.apache.http.HttpResponse;
    12 import org.apache.http.client.HttpClient;
    13 import org.apache.http.client.methods.HttpGet;
    14 import org.apache.http.impl.client.DefaultHttpClient;
    15 import org.json.JSONArray;
    16 import org.json.JSONObject;
    17 import com.nthm.androidtest.R;
    18 import android.app.Activity;
    19 import android.content.Context;
    20 import android.graphics.Bitmap;
    21 import android.graphics.BitmapFactory;
    22 import android.location.Location;
    23 import android.location.LocationListener;
    24 import android.location.LocationManager;
    25 import android.os.Bundle;
    26 import android.view.LayoutInflater;
    27 import android.view.View;
    28 import android.view.ViewGroup;
    29 import android.widget.BaseAdapter;
    30 import android.widget.ImageView;
    31 import android.widget.ListView;
    32 import android.widget.TextView;

        在FilchrJSONLocation活动中实现LocationListener,从而可以在位置更改时获得通知。

     1 public class FilchrJSONLocation extends Activity implements LocationListener{
     2     public static final String API_KEY="YOU_API_AKY";
     3     private  FilckrPhoto[] photos;
     4     private TextView tv;
     5     private LocationManager lm;
     6     @Override
     7     protected void onCreate(Bundle savedInstanceState) {
     8         super.onCreate(savedInstanceState);
     9         setContentView(R.layout.filchrjsonlocation);
    10         tv=(TextView) findViewById(R.id.TextView);
    11         tv.setText("Looking Up Location");

         与直接请求Flickr不同,首先将指定想要的位置,方法是创建一个LocationManager实例并调用requestLocationUpdates方法,将活动注册为LocationListener。其中,指定至多每60秒以及至少移动500米之后更新。

    1         lm=(LocationManager) getSystemService(LocationManager.NETWORK_PROVIDER);
    2         lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 60000, 500.0f, this);
    3     }
    4     
    5     @Override
    6     protected void onPause() {
    7         super.onPause();
    8         lm.removeUpdates(this);
    9     }

        现在,当调用onLocationChanged方法时会向Flickr发出请求,同时考虑以Location对象形式传入的位置。

    1     @Override
    2     public void onLocationChanged(Location location) {
    3         tv.setText(location.getLatitude()+" "+location.getLongitude());
    4         HttpClient httpcilent=new DefaultHttpClient();

        需要构造URL来处理几个额外的参数:表示纬度的lat、表示经度的lon以及精确率(accuracy),精确率数字代表了返回结果中纬度和经度的范围。根据Flickr API文档,值1表示整个世界,6表示一个“区域”,11大约是一座城市,而16大约是一条街道。另外需要指定两个标记,“Halloween(万圣节)”和“dog(狗)”,根据Flickr API文档以逗号分隔他们。

     1         HttpGet httpget=new HttpGet("http://api.filckr.com/services/rest/?method=flickr.photos.search&tags=waterfront&format=json&api_key="+API_KEY+"&per_page=5" +
     2                 "&nojsoncallback=1&accuracy=6&lat="+location.getLatitude()+"&lon="+location.getLongitude());
     3         HttpResponse response;
     4         try{
     5             response=httpcilent.execute(httpget);
     6             HttpEntity entity=response.getEntity();
     7             if(entity!=null){
     8                 InputStream inputstream=entity.getContent();
     9                 BufferedReader bufferedreader=new BufferedReader(new InputStreamReader(inputstream));
    10                 StringBuilder stringbuilder=new StringBuilder();
    11                 String currentline=null;
    12                 try{
    13                     while((currentline=bufferedreader.readLine())!=null){
    14                         stringbuilder.append(currentline+"
    ");
    15                     }
    16                 }catch(IOException e){
    17                     e.printStackTrace();
    18                 }
    19                 String result=stringbuilder.toString();
    20                 JSONObject thedata=new JSONObject(result);
    21                 JSONObject thephotosdata=thedata.getJSONObject("photos");
    22                 JSONArray thephotodata=thephotosdata.getJSONArray("photo");
    23                 photos=new FilckrPhoto[thephotodata.length()];
    24                 for(int i=0;i<thephotodata.length();i++){
    25                     JSONObject photodata=thephotodata.getJSONObject(i);
    26                     photos[i]=new FilckrPhoto(photodata.getString("id"),
    27                             photodata.getString("owner"), 
    28                             photodata.getString("secret"), 
    29                             photodata.getString("server"), 
    30                             photodata.getString("title"),
    31                             photodata.getString("farm"));
    32                 }
    33                 inputstream.close();
    34             }
    35         }catch(Exception e){
    36             e.printStackTrace();
    37         }
    38         ListView listView=(ListView) this.findViewById(R.id.ListView);
    39         listView.setAdapter(new FlickrGalleryAdapter(this, photos));
    40     }

        当然,由于实现了LocationListener,因此需要提供onProviderEnabled和onProviderDisabled方法。此处方法是空方法。在你的应用程序中,你可能希望通知用户这些事件的发生,以解释为什么位置更新已停止或开始工作。

     1     @Override
     2     public void onStatusChanged(String provider, int status, Bundle extras) {
     3         
     4     }
     5     @Override
     6     public void onProviderEnabled(String provider) {
     7         
     8     }
     9     @Override
    10     public void onProviderDisabled(String provider) {
    11         
    12     }

        这个示例的其余代码与之前给出的一样。需要一个FlickrGalleryAdapter类,使用来自Flickr的结果处理ListView的所有元素。

     1     class FlickrGalleryAdapter extends BaseAdapter{
     2         private Context context;
     3         private FilckrPhoto [] photos;
     4         private LayoutInflater inflater;
     5         public FlickrGalleryAdapter(Context _context,FilckrPhoto [] _items){
     6             context=_context;
     7             photos=_items;
     8             inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
     9         }
    10         @Override
    11         public int getCount() {
    12             return photos.length;
    13         }
    14 
    15         @Override
    16         public Object getItem(int position) {
    17             return photos[position];
    18         }
    19 
    20         @Override
    21         public long getItemId(int position) {
    22             return position;
    23         }
    24 
    25         @Override
    26         public View getView(int position, View convertView, ViewGroup parent) {
    27             View photoRow=inflater.inflate(R.layout.filchrjsonlocation_list_item, null);
    28             ImageView image=(ImageView) photoRow.findViewById(R.id.ImageView);
    29             image.setImageBitmap(imageFromUrl(photos[position].makeURL()));
    30             TextView imageTitle=(TextView) photoRow.findViewById(R.id.TextView);
    31             imageTitle.setText(photos[position].title);
    32             return photoRow;
    33         }
    34         public Bitmap imageFromUrl(String url){
    35             Bitmap bitmapImage;
    36             URL imageUrl=null;
    37             try {
    38                 imageUrl=new URL(url);
    39             } catch (MalformedURLException e) {
    40                 e.printStackTrace();
    41             }
    42             try {
    43                 HttpURLConnection httpConnection=(HttpURLConnection) imageUrl.openConnection();
    44                 httpConnection.setDoInput(true);
    45                 httpConnection.connect();
    46                 InputStream is=httpConnection.getInputStream();
    47                 bitmapImage=BitmapFactory.decodeStream(is);
    48             } catch (IOException e) {
    49                 e.printStackTrace();
    50                 bitmapImage=Bitmap.createBitmap(10,10,Bitmap.Config.ARGB_8888);
    51             }
    52             
    53             return bitmapImage;
    54         }
    55     }

        最后,与之前示例中一样,有一个FilckrPhoto类,用来保存通过JSON从Flickr发送的每张照片的数据。

     1     class FilckrPhoto{
     2         private String id;
     3         private String owner;
     4         private String secret;
     5         private String server;
     6         private String title;
     7         private String farm;
     8         
     9         public FilckrPhoto(String _id,String _owner,String _secret,String _server,String _title,String _farm){
    10             id=_id;
    11             owner=_owner;
    12             secret=_secret;
    13             server=_server;
    14             title=_title;
    15             farm=_farm;
    16         }
    17         public String makeURL(){
    18             return "http://farm"+farm+".static.flickr.com/"+server+"/"+id+"_"+secret+"_m.jpg";
    19         }
    20     }
    21 }

        下面是示例中使用的filchrjsonlocation.xml布局。

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="match_parent"
     3     android:layout_height="match_parent"
     4     android:orientation="vertical"
     5     >
     6     <TextView 
     7         android:layout_width="wrap_content"
     8         android:layout_height="wrap_content"
     9         android:id="@+id/TextView"/>
    10  <ListView 
    11      android:layout_width="wrap_content"
    12      android:layout_height="wrap_content"
    13      android:id="@+id/ListView"
    14   />
    15 </LinearLayout>

        下面是示例中使用的ListView布局的filchrjsonlocation_list_item.xml文件。

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     android:layout_width="match_parent"
     3     android:layout_height="match_parent"
     4     android:orientation="horizontal"
     5     >
     6     <ImageView 
     7         android:id="@+id/ImageView"
     8         android:layout_width="wrap_content"
     9         android:layout_height="wrap_content"
    10         />
    11  <TextView 
    12      android:id="@+id/TextView"
    13      android:text="TextView"
    14      android:layout_width="fill_parent"
    15      android:layout_height="wrap_content"
    16      android:textSize="35dip"></TextView>
    17 </LinearLayout>

        当然还需要指定此示例具有访问Internet和使用位置的权限。

        正如我们所见,只须在应用程序中考虑位置,就可以创建及其动态的体验。在当前的情况下,随着用户的移动,将会为他或她展示一套全新的由Flickr提供的“dog,halloween”照片。

        现在让我们将注意力转回到Web服务协议并开始讨论REST。

  • 相关阅读:
    Day10
    Day9
    Day8
    Day7
    Day 6
    Day5
    第一周计划
    事件总线模式辨析
    解释器模式辨析
    解释器模式深度探究
  • 原文地址:https://www.cnblogs.com/ZSS-Android/p/3966169.html
Copyright © 2020-2023  润新知