码迷,mamicode.com
首页 > 移动开发 > 详细

android:如何从照片中获取拍摄地址信息

时间:2015-08-29 21:43:58      阅读:331      评论:0      收藏:0      [点我收藏+]

标签:android   开发   gps   image   

在开发中遇到一个需求,需要解析拿到照片拍摄时的地址信息,在网上有很多网站提供照片上传后解析出照片的具体信息,很详细。android也很给力,提供ExifInterface ,可以获取到拍摄照片时的很多信息。

TAG_DATETIME 时间日期
TAG_FLASH 闪光灯
TAG_GPS_LATITUDE 纬度
TAG_GPS_LATITUDE_REF 纬度参考 
TAG_GPS_LONGITUDE 经度
TAG_GPS_LONGITUDE_REF 经度参考 
TAG_IMAGE_LENGTH 图片长
TAG_IMAGE_WIDTH 图片宽
TAG_MAKE 设备制造商
TAG_MODEL 设备型号
TAG_ORIENTATION 方向
TAG_WHITE_BALANCE 白平衡

下面是从照片中获取经纬度,以及通过范围百度地图接口获取详细的拍摄地信息。

现在可以获取到经纬度信息,由于Google使用的经纬度格式为DMS格式,也就是度分秒格式,如果需要使用其他格式就需要转化,代码中将其转化为DD格式。
/**
 * 从照片中获取经纬度
 */
public class GetLatandLng{
       public GetLatandLng() {
            super();
        }
    /**
       path 为照片的路径
    */
    public  double[] getlocation(String path){
            float output1 = 0;
            float output2 = 0;
            @SuppressWarnings("unused")
            String context ;
            Location location;
           try {
             ExifInterface exifInterface=new ExifInterface(path);
             String latValue = exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
             String latRef   = exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
             String lngValue = exifInterface.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
             String lngRef   = exifInterface.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF);
             if (latValue != null && latRef != null && lngValue != null && lngRef != null) {
                 try {
                     output1 = convertRationalLatLonToFloat(latValue, latRef);
                     output2= convertRationalLatLonToFloat(lngValue, lngRef);
                 } catch (IllegalArgumentException e) {
                   e.printStackTrace();
                 }
             }
         } catch (Exception e) {
             e.printStackTrace();
         } 
        context = Context.LOCATION_SERVICE;
        location=new Location(LocationManager.GPS_PROVIDER);
        location.setLatitude(output1);
        location.setLongitude(output2);
        double lat = location.getLatitude();  
        double lng = location.getLongitude();
        double[] f={lat,lng};
        return f;
       }

       private static float convertRationalLatLonToFloat(
               String rationalString, String ref) {
           try {
               String [] parts = rationalString.split(",");

               String [] pair;
               pair = parts[0].split("/");
               double degrees = Double.parseDouble(pair[0].trim())
                       / Double.parseDouble(pair[1].trim());

               pair = parts[1].split("/");
               double minutes = Double.parseDouble(pair[0].trim())
                       / Double.parseDouble(pair[1].trim());

               pair = parts[2].split("/");
               double seconds = Double.parseDouble(pair[0].trim())
                       / Double.parseDouble(pair[1].trim());

               double result = degrees + (minutes / 60.0) + (seconds / 3600.0);
               if ((ref.equals("S") || ref.equals("W"))) {
                   return (float) -result;
               }
               return (float) result;
           } catch (NumberFormatException e) {
               throw new IllegalArgumentException();
           } catch (ArrayIndexOutOfBoundsException e) {
               throw new IllegalArgumentException();
           }
       }
}

convertRationalLatLonToFloat方法是源码中自带的方法。

下面就需要把照片中的经纬度传给百度地图接口,但是遇到了经纬度纠偏的问题,给大家推荐一个不错的纠偏网站:
http://api.zdoz.net/Default.aspx

public class DDtoAddress {

    public DDtoAddress() {
        super();
    }
    //d数组  经纬度信息
    public String GetAddress(double[] d){
        //經度
        String Lng=null;
        //維度
        String Lat=null;
        BufferedReader d1;
        String searchServiceURL;
        URL url ;
        HttpURLConnection httpConnection = null;
        InputStream inputStream = null;
        BufferedReader bufferedReader = null;
        Address  address;
        //接受从网页换回的xml文件
        String str1="";
        double lat1 =d[0];  
        double lng1 =d[1];

        //用未纠偏的经纬度访问纠偏网站
            searchServiceURL = "http://api.zdoz.net/transgpsbd.aspx?lat="+lat1+"&lng="+lng1+"";

            try {
                url = new URL(searchServiceURL);
                httpConnection = (HttpURLConnection) url.openConnection();
                httpConnection.setRequestProperty("Content-Type", "text/plain");
                httpConnection.setRequestMethod("GET");
                httpConnection.setDoOutput(false);
                int status = httpConnection.getResponseCode();
                if (status == 200){
                    inputStream = httpConnection.getInputStream();
                    bufferedReader = new BufferedReader(new InputStreamReader(inputStream));

                    //得到偏移后的经纬度
                    String str=bufferedReader.readLine();
                    String[] s = str.split(",");
                    String temp[]=s[0].split(":");
                    Lng=temp[1];
                    String temp1[]=s[1].split(":");
                    Lat=temp1[1].substring(0, temp1[1].length()-1);
                }
             } catch (Exception e) {
                e.printStackTrace();
             } finally{
                try {
                    //关闭资源
                    httpConnection.disconnect();
                    bufferedReader.close();
                    inputStream.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
             }
            //用纠偏后经纬度重新访问百度API
      searchServiceURL = "http://api.map.baidu.com/geocoder/v2/?ak=XXXXXXXXXXXXXXXXXXX&callback=renderReverse&location="+Lat+","+Lng+"&output=xml&pois=1";
      Log.i("TEST", searchServiceURL);  
      try {
                url = new URL(searchServiceURL);
                httpConnection = (HttpURLConnection) url.openConnection();
                httpConnection.setRequestProperty("Content-Type", "text/plain");
                httpConnection.setRequestMethod("GET");
                httpConnection.setDoOutput(false);
                int status = httpConnection.getResponseCode();
                if (status == 200){
                    InputStream in = httpConnection.getInputStream();
                    d1 = new BufferedReader(new InputStreamReader(in));
                    String  str;
                    while((str=d1.readLine()) != null){
                        str1 = str1+str;
                    }
                }

                //解析读取到的字符串
                SAXReader sax = new SAXReader();
                Document document = (Document) sax.read(new ByteArrayInputStream(str1.getBytes("UTF-8")));
                //获得根元素
                Element root = document.getRootElement();
                Element root1 = root.element("status");
                /** status
                 *  0   正常
                    1   服务器内部错误
                    2   请求参数非法
                    3   权限校验失败
                    4   配额校验失败
                    5   ak不存在或者非法
                    101 服务禁用
                    102 不通过白名单或者安全码不对
                    2xx 无权限
                    3xx 配额错误
                 */
                //当status=0时,做处理,并将返回的结果写入数据库中
                if(root1.getText().equals("0")){
                    address=new Address();
                    Element root2 = root.element("result");

                    Element root3 = root2.element("formatted_address");
                    address.setFormatted_address(root3.getText());
                    Element root4 = root2.element("addressComponent");

                    Element root5 = root4.element("streetNumber");
                    address.setStreetnumber(root5.getText());

                    root5 = root4.element("street");
                    address.setStreet(root5.getText());

                    root5 = root4.element("district");
                    address.setDistrict(root5.getText());

                    root5 = root4.element("city");
                    address.setCity(root5.getText());

                    root5 = root4.element("province");
                    address.setProvince(root5.getText());

                    root5 = root4.element("country");
                    address.setCountry(root5.getText());

                    root5 = root4.element("countryCode");
                    address.setCountrycode(root5.getText());
                    Log.i("TEST", address.toString()+"gergergreg");
                    return address.toString();

                }else{
                    //当status!=0时,做处理
                }
            }
            catch (Exception e) {
                e.printStackTrace();
            }finally{
                try {
                    httpConnection.disconnect();
                    bufferedReader.close();
                    inputStream.close();
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return null;
   }
}
上面代码中:
ak=XXXXXXXXXXXXXXXXXXX
这个为访问百度接口的密钥,就需要自己申请了

定义一个类,接受从网页返回的数据

public class Address {

    String   formatted_address;
    String             country;
    String            province;
    String                city;
    String            district;
    String              street;
    String        streetnumber;
    String         countrycode;
    public Address() {
    }

    public Address(String formatted_address, String country, String province,
            String city, String district, String street, String streetnumber,
            String countrycode) {
        super();
        this.formatted_address = formatted_address;
        this.country = country;
        this.province = province;
        this.city = city;
        this.district = district;
        this.street = street;
        this.streetnumber = streetnumber;
        this.countrycode = countrycode;
    }
    public String getFormatted_address() {
        return formatted_address;
    }
    public void setFormatted_address(String formatted_address) {
        this.formatted_address = formatted_address;
    }
    public String getCountry() {
        return country;
    }
    public void setCountry(String country) {
        this.country = country;
    }
    public String getProvince() {
        return province;
    }
    public void setProvince(String province) {
        this.province = province;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getDistrict() {
        return district;
    }
    public void setDistrict(String district) {
        this.district = district;
    }
    public String getStreet() {
        return street;
    }
    public void setStreet(String street) {
        this.street = street;
    }
    public String getStreetnumber() {
        return streetnumber;
    }
    public void setStreetnumber(String streetnumber) {
        this.streetnumber = streetnumber;
    }
    public String Countrycode() {
        return countrycode;
    }
    public void setCountrycode(String countrycode) {
        this.countrycode = countrycode;
    }

    @Override
    public String toString() {
        return country  + province + city + district + street + streetnumber ;
    }
}

MainActivity .java

public class MainActivity extends Activity {
    //照片路径
    String path="/sdcard/images/test.jpg";
    @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

       /**
        * 必须加入下面两句,否则报错
        * android.os.NetworkOnMainThreadException
        */
       StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
       StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());


       GetLatandLng  getlatandlng=new GetLatandLng();
       double[] d=getlatandlng.getlocation(path);
       DDtoAddress getAddress=new DDtoAddress();
       String address=getAddress.GetAddress(d);
       if(address!=null){
       Toast.makeText(MainActivity.this,address, Toast.LENGTH_LONG).show();
       }
    }

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

提示:访问SDcard和访问网络都需要在清单文件夹中加入相应的权限

版权声明:本文为博主原创文章,未经博主允许不得转载。

android:如何从照片中获取拍摄地址信息

标签:android   开发   gps   image   

原文地址:http://blog.csdn.net/qq_17326933/article/details/48091697

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!