Home > Android, Java > What I’m I Working With

What I’m I Working With

Supporting a variety of Android devices can be challenging. To begin with there are currently 17 versions of Android. Then there’s the wide variety of screen sizes and densities. When developing an Android application it would be nice to quickly and easily understand the device’s properties.  I decided to created a simple library which displayed the following property sets:

  •  Display – General information about a display, such as its size, density, and font scaling.
  • OS – Information about the current build, extracted from system properties.
  • System – System related information.

With this library in place my application can invoke it from a menu option that is available while I develop it.

I created an Fragment sub-class to be used within the various Activities. The fragment contains a ListView and requires a ListAdapter and List from its sub-classes.

SimpleListViewFragment.java

public abstract class SimpleListViewFragment extends Fragment {
    abstract protected ListAdapter getAdapter(Context context);

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_simplelistview, container, false);

        ListView screenPropertiesView = (ListView) view.findViewById(R.id.listView);
        screenPropertiesView.setAdapter(getAdapter(container.getContext()));

        return view;
    }
}

fragment_simplelistview.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </ListView>

</LinearLayout>

Next is an other abstract class SimpleTwoLineListViewFragment which provides the adapter and requires the list from the sub-class.

SimpleTwoLineListViewFragment.java

public abstract class SimpleTwoLineListViewFragment extends SimpleListViewFragment {
	abstract protected List getList();

	protected ArrayAdapter getAdapter(Context context) {
		return new ArrayAdapter(context, android.R.layout.simple_list_item_2, getList()){
	        @Override
	        public View getView(int position, View convertView, ViewGroup parent){
	            TwoLineListItem view;
	            if(convertView == null){
	                LayoutInflater inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	                view = (TwoLineListItem)inflater.inflate(android.R.layout.simple_list_item_2, null);
	            }else{
	                view = (TwoLineListItem)convertView;
	            }
	            T data = getItem(position);
	            view.getText1().setText(data.getName());
	            view.getText2().setText(data.getValue());

	            return view;
	        }
	    };
	}
}

Finally, there are the three classes DisplayPropertiesFragmentOSPropertiesFragment, and SystemPropertiesFragment which provide the properties in a List the properties.

DisplayPropertiesFragment.java

public class DisplayPropertiesFragment extends SimpleTwoLineListViewFragment {
	private String getDensityString(int density) {
		String string;

		if (density <= DisplayMetrics.DENSITY_LOW) {
			string = "low";
		}
		else if (density <= DisplayMetrics.DENSITY_MEDIUM) {
			string = "medium";
		}
		else if (density <= DisplayMetrics.DENSITY_TV) {
			string = "tv";
		}
		else if (density <= DisplayMetrics.DENSITY_HIGH) {
			string = "high";
		}
		else {
			string = "xhigh";
		}

		return string;
	}

	@Override
	protected List getList() {
		List list = new ArrayList();

		DisplayMetrics metrics = getResources().getDisplayMetrics();

		list.add(new TwoLineData("Width (pixels)", Integer.toString(metrics.widthPixels)));
		list.add(new TwoLineData("Height (pixels)", Integer.toString(metrics.heightPixels)));
		list.add(new TwoLineData("Density", Double.toString(metrics.density)));
		list.add(new TwoLineData("Density DPI", String.format("%d (%s)", metrics.densityDpi, getDensityString(metrics.densityDpi))));
		list.add(new TwoLineData("Scaled Density", Double.toString(metrics.scaledDensity)));
		list.add(new TwoLineData("xdpi", Double.toString(metrics.xdpi)));
		list.add(new TwoLineData("ydpi", Double.toString(metrics.ydpi)));

		return list;
	}

Android introduced fragments in Android 3.0 (API level 11) . I’ve got a level 10 device and what my application to support that.  Fortunately Android provides a Support Library which will add API’s not available for older platform versions.

To use these fragments I created DeveloperFragmentActivity. This class is designed to be called by an Intent with an extra string defining the name of the fragment class to instantiate and embedded (via Fragment.replace()).

DeveloperFragmentActivity.java

public class DeveloperFragmentActivity extends FragmentActivity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_developer);

        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    	String fragmentClass = this.getIntent().getStringExtra("fragment");

        try {
			Fragment fragment = (Fragment) Class.forName(fragmentClass).newInstance();

	        fragmentTransaction.replace(R.id.mainFragement, fragment);
	        fragmentTransaction.commit();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
    }
}

DeveloperActivity and DeveloperPropertiesFragment bring it all together.

DeveloperActivity.java

public class DeveloperActivity extends FragmentActivity {

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_developer);

    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();

    Fragment fragment = new DeveloperPropertiesFragment();
    fragmentTransaction.replace(R.id.mainFragement, fragment);
    fragmentTransaction.commit();
    }
}

DeveloperPropertiesFragment.java

class ListData {
private String title;
private String description;
private String fragment;

public ListData(String title, String description, String fragment) {
this.setTitle(title);
this.setDescription(description);
this.setFragment(fragment);
}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public String getFragment() {
		return fragment;
	}

	public void setFragment(String fragment) {
		this.fragment = fragment;
	}
}

public class DeveloperPropertiesFragment extends SimpleListViewFragment<ListData> {
	private List<ListData> list;

	private List<ListData> getList() {
		return list;
	}

	@Override
public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		list = new ArrayList<ListData>();
		list.add(new ListData(getString(R.string.display_item_title), getString(R.string.display_item_description), DisplayPropertiesFragment.class.getName()));
		list.add(new ListData(getString(R.string.os_item_title), getString(R.string.os_item_description), OSPropertiesFragment.class.getName()));
		list.add(new ListData(getString(R.string.system_item_title), getString(R.string.system_item_description), SystemPropertiesFragment.class.getName()));
	}

	@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
		View view = super.onCreateView(inflater, container, savedInstanceState);

		ListView listView = (ListView) view.findViewById(R.id.listView);
		listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);

		listView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			    Intent intent = new Intent(view.getContext(), DeveloperFragmentActivity.class);
			    intent.putExtra("fragment", getList().get(position).getFragment());
			    startActivity(intent);
			}
		});

		return view;
	}

	protected ArrayAdapter<ListData> getAdapter(Context context) {
		return new ArrayAdapter<ListData>(context, android.R.layout.simple_list_item_2, getList()){
	        @Override
	        public View getView(int position, View convertView, ViewGroup parent){
	        	TwoLineListItem view;

	            if(convertView == null){
	                LayoutInflater inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	                view = (TwoLineListItem)inflater.inflate(android.R.layout.simple_list_item_2, null);
	            }else{
	                view = (TwoLineListItem)convertView;
	            }

	            ListData data = getItem(position);
	            view.getText1().setText(data.getTitle());
	            view.getText2().setText(data.getDescription());

	            return view;
	        }
	    };
	}
}

The result is a set of ListView’s that display a variety of device properties.

developer sample

The code is available at GitHub.

Advertisements
Categories: Android, Java
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: