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+"\n");

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。

 

你可能感兴趣的:(json)