martes, 20 de agosto de 2013

Adding location to MapFragment

I am using Reverse Geocoding to get the location, after that, I am placing a marker in the location.

This code adds a location to the MapFragment:

public class AddressMapFragment extends MapFragment {
 
 LatLng location;
 
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
 }
 
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {
  View v =  super.onCreateView(inflater, container, savedInstanceState);
  
  Bundle args = getArguments();
  
  if(args!=null){
   String fulladdress = args.getString("fulladdress");
   new ReverseGeocoding().execute(fulladdress);
  }
  
  
  
  return v;
 }
 
 private void initMap(){
     UiSettings settings = getMap().getUiSettings();
     settings.setAllGesturesEnabled(false);
     settings.setMyLocationButtonEnabled(false);
     
     if(location!=null){

      getMap().moveCamera(CameraUpdateFactory.newLatLngZoom(location,16));
      getMap().addMarker(new MarkerOptions().position(location));
     }
 }
 
 public class ReverseGeocoding extends AsyncTask<String, Void, Void>{

  @Override
  protected Void doInBackground(String... params) {
   reverse_geocoding(params[0]);
   return null;
  }
  
  @Override
  protected void onPostExecute(Void result) {
   super.onPostExecute(result);
   
   initMap();
   
  }
  
 }
 
 public void reverse_geocoding(String fulladdress){
  
  Geocoder geo = new Geocoder(getActivity());
  try {
   List<Address> addresses = geo.getFromLocationName(fulladdress, 1);
   if(addresses.size()>0){
    Address address = addresses.get(0); 
    location = new LatLng(address.getLatitude(),address.getLongitude());
   }
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

}

Back to previous fragment with back button

To be able to go back to the previous fragment pressing the back hardware button we have to add the fragment adding null to the backstack.

This is the resultant code:
Fragment fragment = new Fragment();
  
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().add(R.id.content_frame, fragment).addToBackStack(null).commit();
 

jueves, 18 de julio de 2013

How to get view dimensions at onCreate

Hi, Trying to get the dimensions of my RelativeLayout at the onCreate of my Activity without no success, at the begining teh code seemed very easy :
RelativeLayout dashboard = (RelativeLayout)findViewById(R.id.dashboard);
int width = dashboard.getWidth()
no luck!, in this case getWidth() is always 0. Then I tryed to figure out why this happens and I realize that dashboard is not rendered yet, so, I have to find a callback after rendering to get the dashboard width... no luck! onResume didn't work neither, so I was researching through internet and I've found this blog where my problem is perfect solved. I've just going to put the code but you can read the entire article at http://code2thought.blogspot.com.es/2011/01/getting-layout-dimensions-in-android.html
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.dashboard);
  
  RelativeLayout dashboard = (GridLayout)findViewById(R.id.dashboard);
  
  
  dashboard.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
   
   @Override
   public void onGlobalLayout() {
    
    int width = dashboard.getWidth()
    
   }
  });
  
 }
happy coding!

martes, 16 de julio de 2013

GridLayout views out of the screen

Sometimes your views inside a gridlayout are outside the screen, to fix that you can give to your views android:width="0", that way it fits inside the Gridlayout.
<GridLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:columnCount="2">

    <Button
        android:layout_column="0"
        android:layout_columnSpan="1"
        android:layout_gravity="start|end"
        android:layout_row="0"
        android:text="ASDFASDF"
         />

    <Button
        android:layout_column="1"
        android:layout_gravity="start|end"
        android:layout_row="0"
        android:text="SDAVDFBDFB" />

    <Button
        android:layout_column="0"
        android:layout_columnSpan="2"
        android:layout_gravity="fill|center"
        android:layout_row="1"
        android:text="ASDVADFBFDAFEW" />

    <Button
        android:layout_column="0"
        android:layout_columnSpan="1"
        android:layout_gravity="fill|center"
        android:layout_row="2"
        android:text="FWEA AWFWEA" />

    <Button
        android:layout_column="1"
        android:layout_columnSpan="1"
        android:layout_gravity="fill"
        android:layout_row="2"
        android:text="BERWEfasf" />

    <Button
        android:layout_width="94dp"
        android:layout_column="0"
        android:layout_columnSpan="1"
        android:layout_gravity="fill|center"
        android:layout_row="3"
        android:text="SDFVBFAEVSAD" />

    <Button
        android:layout_column="0"
        android:layout_columnSpan="1"
        android:layout_gravity="fill|center"
        android:layout_row="4"
        android:layout_rowSpan="2"
        android:text="GVBAERWEFSD" />

    <Button
        android:width="0dp"
        android:layout_column="1"
        android:layout_columnSpan="1"
        android:layout_gravity="fill|center"
        android:layout_row="3"
        android:layout_rowSpan="2"
        android:text="VSDFAVE SDFASDWA SDFASD" />

    <Button
        android:width="0dp"
        android:layout_column="1"
        android:layout_columnSpan="1"
        android:layout_gravity="fill|center"
        android:layout_row="5"
        android:text="FWEWEGAWEFWAE"/>

</GridLayout>

miércoles, 19 de junio de 2013

Fit map zoom to markers

Exists an easy way in Google Map API v2 to get the correct zoom for all the markers we have in the map:

 public void setZoom(List<LatLng> coords){
                GoogleMap map = getMap();
  LatLngBounds bounds = helper.getBounds(coords);

                int zoom_padding = 20;
  map.animateCamera(CameraUpdateFactory.newLatLngBounds(bounds, zoom_padding));
 }

        public LatLngBounds getBounds(List<LatLng> coords){
  
  LatLngBounds.Builder builder = new LatLngBounds.Builder();

  for(LatLng coord:coords){
   
    
                 builder.include(coord);
    
  }
  
  return builder.build();
 }

        
easy!

miércoles, 12 de junio de 2013

XML Parser (XmlPullParser)

I feel more confortable parsing JSON, but sometimes I get some services in XML. After reading some articles about parsing and reading the google advices I finally decided to use the class XMLPullParser, not bad, here an example.


First we get the xml
public InputStream getResponseInputStream(String url){
  
  Log.i("URL REQUEST",url);
  URL request;
  try {
   
   request = new URL(url); 
   HttpURLConnection  conn = (HttpURLConnection)request.openConnection(); 
   conn.setConnectTimeout(30000);
   conn.setReadTimeout(30000);
   
   InputStream is = conn.getInputStream();
   return is;

  } catch (MalformedURLException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  
  return null;
 }

Create the parser
public List<Member> getMemberData(String url){
  
  InputStream is=null;
  try{
   is = getResponseInputStream(url);

   XmlPullParser parser = Xml.newPullParser();
            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
         parser.setInput(is, null);
        
         parser.nextTag();
         List<Member> members = readMembers(parser);
   is.close();
   
   return members;
  
  } catch (Exception e) {
   e.printStackTrace();
   
  }
  
  return null;
 }
Parsing:
private List<Member> readMembers(XmlPullParser parser) throws XmlPullParserException, IOException {
     List<Member> entries = new ArrayList<Member>();

     parser.require(XmlPullParser.START_TAG, null, "root");
     while (parser.next() != XmlPullParser.END_TAG) {
         if (parser.getEventType() != XmlPullParser.START_TAG) {
             continue;
         }
         String name = parser.getName();
         // Starts by looking for the entry tag
         if (name.equals("item")) {
             entries.add(readMemberDetail(parser));
         } else {
             skip(parser);
         }
     }  
     return entries;
 }
 
 private Member readMemberDetail(XmlPullParser parser) throws XmlPullParserException, IOException {
     parser.require(XmlPullParser.START_TAG, null, "item");
     Member member = new Member();

     while (parser.next() != XmlPullParser.END_TAG) {
         if (parser.getEventType() != XmlPullParser.START_TAG) {
             continue;
         }
         
         String localName = parser.getName();
         
         if(localName.equals("id")) member.id = readText(parser,"id");
else if(localName.equals("name")) member.name = readText(parser,"name");
else if(localName.equals("address")) member.address = readText(parser,"address");
else skip(parser);

        
     }
     return member;
 }
And some utils like readText to get the content and skip if we get some tag we don't want to parse
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
     if (parser.getEventType() != XmlPullParser.START_TAG) {
         throw new IllegalStateException();
     }
     int depth = 1;
     while (depth != 0) {
         switch (parser.next()) {
         case XmlPullParser.END_TAG:
             depth--;
             break;
         case XmlPullParser.START_TAG:
             depth++;
             break;
         }
     }
  }
 
 public String readText(XmlPullParser parser, String tag){
  try{
   parser.require(XmlPullParser.START_TAG, null, tag);
      String text = readText(parser);
      parser.require(XmlPullParser.END_TAG, null, tag);
      return text;
  } catch (XmlPullParserException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
  
  return null;
 }
More info