Professional Documents
Culture Documents
coursera-android-locationlab/Skeleton/src/course/labs/locationlab/MockLocationProvider.java
kjorg50 on 20 Apr 2014
initial commit
1 contributor
RawBlameHistory
android.content.Context;
android.location.Location;
android.location.LocationManager;
android.os.SystemClock;
coursera-android-locationlab/Skeleton/src/course/labs/locationlab/PlaceDownloaderTask.java
kjorg50 on 20 Apr 2014
updaed geoname ID
1 contributor
RawBlameHistory
java.io.BufferedReader;
java.io.IOException;
java.io.InputStream;
java.io.InputStreamReader;
java.io.StringReader;
java.lang.ref.WeakReference;
java.net.HttpURLConnection;
java.net.MalformedURLException;
java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import
import
import
import
import
import
org.w3c.dom.DOMException;
org.w3c.dom.Document;
org.w3c.dom.Node;
org.w3c.dom.NodeList;
org.xml.sax.InputSource;
org.xml.sax.SAXException;
import
import
import
import
import
import
android.graphics.Bitmap;
android.graphics.BitmapFactory;
android.location.Location;
android.location.LocationManager;
android.os.AsyncTask;
android.util.Log;
private
private
private
private
WeakReference<PlaceViewActivity> mParent;
static Bitmap mStubBitmap;
static Location mockLoc1 = new Location(LocationManager.NETWORK_PROVIDER);
static Location mockLoc2 = new Location(LocationManager.NETWORK_PROVIDER);
BufferedReader in = null;
try {
URL url = new URL(params[0]);
mHttpUrl = (HttpURLConnection) url.openConnection();
in = new BufferedReader(new InputStreamReader(
mHttpUrl.getInputStream()));
StringBuffer sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
} catch (MalformedURLException e) {
} catch (IOException e) {
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
mHttpUrl.disconnect();
}
return placeDataFromXml(result);
}
private Bitmap getFlagFromURL(String flagUrl) {
InputStream in = null;
Log.i("temp", flagUrl);
try {
URL url = new URL(flagUrl);
mHttpUrl = (HttpURLConnection) url.openConnection();
in = mHttpUrl.getInputStream();
return BitmapFactory.decodeStream(in);
} catch (MalformedURLException e) {
Log.e("DEBUG", e.toString());
} catch (IOException e) {
Log.e("DEBUG", e.toString());
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
mHttpUrl.disconnect();
}
return BitmapFactory.decodeResource(mParent.get().getResources(),
R.drawable.stub);
}
private static PlaceRecord placeDataFromXml(String xmlString) {
DocumentBuilder builder;
String countryName = "";
String countryCode = "";
String placeName = "";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(
xmlString)));
NodeList list = document.getDocumentElement().getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node curr = list.item(i);
NodeList list2 = curr.getChildNodes();
for (int j = 0; j < list2.getLength(); j++) {
Node curr2 = list2.item(j);
if (curr2.getNodeName() != null) {
if (curr2.getNodeName().equals("countryName")) {
countryName = curr2.getTextContent();
} else if (curr2.getNodeName().equals("countryCode")) {
countryCode = curr2.getTextContent();
} else if (curr2.getNodeName().equals("name")) {
placeName = curr2.getTextContent();
}
}
}
}
} catch (DOMException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return new PlaceRecord(generateFlagURL(countryCode.toLowerCase()),
countryName, placeName);
}
private static String generateURL(String username, Location location) {
return "http://www.geonames.org/findNearbyPlaceName?username="
+ username + "&style=full&lat=" + location.getLatitude()
+ "&lng=" + location.getLongitude();
}
private static String generateFlagURL(String countryCode) {
return "http://www.geonames.org/flags/x/" + countryCode + ".gif";
}
}
coursera-android-locationlab/Skeleton/src/course/labs/locationlab/PlaceViewActivity.java
kjorg50 on 20 Apr 2014
remove TODOs
1 contributor
RawBlameHistory
android.app.ListActivity;
android.content.Context;
android.location.Location;
android.location.LocationListener;
android.location.LocationManager;
android.os.Bundle;
android.util.Log;
android.view.Menu;
android.view.MenuInflater;
android.view.MenuItem;
android.view.View;
android.view.View.OnClickListener;
android.widget.ListView;
android.widget.TextView;
android.widget.Toast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// DONE - Set up the app's user interface
// This class is a ListActivity, so it has its own ListView
// ListView's adapter should be a PlaceViewAdapter
mAdapter = new PlaceViewAdapter(getApplicationContext());
// from UI lab...
// Put divider between ToDoItems and FooterView
getListView().setFooterDividersEnabled(true);
// DONE - add a footerView to the ListView
// You can use footer_view.xml to define the footer
// 1. get a layout inflater
// 2. call the inflate method, with the id of the footer view resource
// 3. cast it as a TextView
mFooterView = (TextView) this.getLayoutInflater().inflate(R.layout.footer_view, null);
// adds it to the ListView
getListView().addFooterView(mFooterView);
// enable it only if there is a location
mFooterView.setEnabled(mLastLocationReading != null);
// DONE - When the footerView's onClick() method is called, it must issue the
// following log call
// log("Entered footerView.OnClickListener.onClick()");
mFooterView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
log("Entered footerView.OnClickListener.onClick()");
// footerView must respond to user clicks.
// Must handle 3 cases:
// 3) There is no current location - response is up to you. The best
// solution is to disable the footerView until you have a location.
if (mLastLocationReading == null)
{
log("Location data is not available");
mFooterView.setEnabled(false);
}
// 1) The current location is new - download new Place Badge. Issue the
// following log call:
// log("Starting Place Download");
if(! mAdapter.intersects(mLastLocationReading))
{
log("Starting Place Download");
PlaceDownloaderTask pdt = new PlaceDownloaderTask(PlaceViewActivity.this);
pdt.execute(mLastLocationReading);
} else {
// 2) The current location has been seen before - issue Toast message.
// Issue the following log call:
log("You already have this location badge");
Toast.makeText(getApplicationContext(), "You already have this location badge",
Toast.LENGTH_LONG).show();
}
}
});
// Attach the adapter to this ListActivity's ListView
getListView().setAdapter(mAdapter);
}
@Override
protected void onResume() {
super.onResume();
Location tempLoc;
mMockLocationProvider = new MockLocationProvider(
LocationManager.NETWORK_PROVIDER, this);
// DONE - Check NETWORK_PROVIDER for an existing location reading.
// Acquire reference to the LocationManager
if (null == (mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE)))
finish();
tempLoc = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
// Only keep this last reading if it is fresh - less than 5 minutes old.
if(tempLoc != null && age(tempLoc)<FIVE_MINS)
{
mLastLocationReading = tempLoc;
}
// DONE - register to receive location updates from NETWORK_PROVIDER
// can use "this" since this class implements LocationListener
mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, mMinTime,
mMinDistance, this);
}
@Override
protected void onPause() {
mMockLocationProvider.shutdown();
// DONE - unregister for location updates
mLocationManager.removeUpdates(this);
super.onPause();
}
// Callback method used by PlaceDownloaderTask
public void addNewPlace(PlaceRecord place) {
log("Entered addNewPlace()");
mAdapter.add(place);
}
@Override
public void onLocationChanged(Location currentLocation) {
//
//
//
//
//
//
// current location.
if(mLastLocationReading == null || age(currentLocation) < age(mLastLocationReading))
{
mLastLocationReading = currentLocation;
// enable the footer view again since we have an updated location
mFooterView.setEnabled(true);
}
}
@Override
public void onProviderDisabled(String provider) {
// not implemented
}
@Override
public void onProviderEnabled(String provider) {
// not implemented
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// not implemented
}
private long age(Location location) {
return System.currentTimeMillis() - location.getTime();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.print_badges:
ArrayList<PlaceRecord> currData = mAdapter.getList();
for (int i = 0; i < currData.size(); i++) {
log(currData.get(i).toString());
}
return true;
case R.id.delete_badges:
mAdapter.removeAllViews();
return true;
case R.id.place_one:
mMockLocationProvider.pushLocation(37.422, -122.084);
return true;
case R.id.place_invalid:
mMockLocationProvider.pushLocation(0, 0);
return true;
case R.id.place_two:
mMockLocationProvider.pushLocation(38.996667, -76.9275);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private static void log(String msg) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, msg);
}
}
coursera-android-contentproviders-lab
branch: master
coursera-android-contentproviderslab/Skeleton/ContentProviderLabUser/src/course/labs/contentproviderlab/PlaceDownloaderTask.java
kjorg50 on 26 Apr 2014
clean up TODOs
1 contributor
RawBlameHistory
java.io.BufferedReader;
java.io.IOException;
java.io.InputStream;
java.io.InputStreamReader;
java.io.StringReader;
java.lang.ref.WeakReference;
java.net.HttpURLConnection;
java.net.MalformedURLException;
java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import
import
import
import
import
import
org.w3c.dom.DOMException;
org.w3c.dom.Document;
org.w3c.dom.Node;
org.w3c.dom.NodeList;
org.xml.sax.InputSource;
org.xml.sax.SAXException;
import
import
import
import
import
import
android.graphics.Bitmap;
android.graphics.BitmapFactory;
android.location.Location;
android.location.LocationManager;
android.os.AsyncTask;
android.util.Log;
coursera-android-contentproviderslab/Skeleton/ContentProviderLabUser/src/course/labs/contentproviderlab/Place
ViewActivity.java
kjorg50 on 26 Apr 2014
clean up TODOs
1 contributor
RawBlameHistory
android.app.ListActivity;
android.app.LoaderManager;
android.app.LoaderManager.LoaderCallbacks;
android.content.Context;
android.content.CursorLoader;
android.content.Loader;
android.database.Cursor;
android.location.Location;
android.location.LocationListener;
android.location.LocationManager;
android.os.Bundle;
android.util.Log;
android.view.Menu;
android.view.MenuInflater;
android.view.MenuItem;
android.view.View;
android.view.View.OnClickListener;
android.widget.ListView;
android.widget.TextView;
android.widget.Toast;
course.labs.contentproviderlab.provider.PlaceBadgesContract;
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, msg);
}
}
coursera-android-contentproviderslab/Skeleton/ContentProviderLabUser/src/course/labs/contentproviderlab/Place
ViewAdapter.java
kjorg50 on 26 Apr 2014
clean up TODOs
1 contributor
RawBlameHistory
java.io.BufferedOutputStream;
java.io.File;
java.io.FileNotFoundException;
java.io.FileOutputStream;
java.io.IOException;
java.util.ArrayList;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android.content.ContentValues;
android.content.Context;
android.database.Cursor;
android.graphics.Bitmap;
android.graphics.Bitmap.CompressFormat;
android.graphics.BitmapFactory;
android.location.Location;
android.net.Uri;
android.os.Environment;
android.view.LayoutInflater;
android.view.View;
android.view.ViewGroup;
android.widget.CursorAdapter;
android.widget.ImageView;
android.widget.TextView;
course.labs.contentproviderlab.provider.PlaceBadgesContract;
list.clear();
// Check if the database is empty!
if(newCursor.moveToFirst())
{
do
{ // combine the getting of the record with adding it to the list
list.add(getPlaceRecordFromCursor(newCursor));
} while(newCursor.moveToNext());
// moveToNext() returns false when the cursor is already past the last entry in the result set
}
// Set the NotificationURI for the new cursor
newCursor.setNotificationUri(mContext.getContentResolver(),
PlaceBadgesContract.CONTENT_URI);
}
return newCursor;
}
// returns a new PlaceRecord for the data at the cursor's
// current position
private PlaceRecord getPlaceRecordFromCursor(Cursor cursor) {
String flagBitmapPath = cursor.getString(cursor
.getColumnIndex(PlaceBadgesContract.FLAG_BITMAP_PATH));
String countryName = cursor.getString(cursor
.getColumnIndex(PlaceBadgesContract.COUNTRY_NAME));
String placeName = cursor.getString(cursor
.getColumnIndex(PlaceBadgesContract.PLACE_NAME));
double lat = cursor.getDouble(cursor
.getColumnIndex(PlaceBadgesContract.LAT));
double lon = cursor.getDouble(cursor
.getColumnIndex(PlaceBadgesContract.LON));
return new PlaceRecord(null, flagBitmapPath, countryName, placeName,
lat, lon);
}
public int getCount() {
return list.size();
}
public Object getItem(int position) {
return list.get(position);
}
public long getItemId(int position) {
return position;
}
static class ViewHolder {
ImageView flag;
TextView country;
TextView place;
}
public boolean intersects(Location location) {
for (PlaceRecord item : list) {
if (item.intersects(location)) {
return true;
}
}
return false;
}
public void add(PlaceRecord listItem) {
String lastPathSegment = Uri.parse(listItem.getFlagUrl())
.getLastPathSegment();
String filePath = mBitmapStoragePath + "/" + lastPathSegment;
if (storeBitmapToFile(listItem.getFlagBitmap(), filePath)) {
listItem.setFlagBitmapPath(filePath);
list.add(listItem);
// DONE - Insert new record into the ContentProvider
}
private Bitmap getBitmapFromFile(String filePath) {
return BitmapFactory.decodeFile(filePath);
}
private boolean storeBitmapToFile(Bitmap bitmap, String filePath) {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
try {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(filePath));
bitmap.compress(CompressFormat.PNG, 100, bos);
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {
return false;
}
return true;
}
return false;
}
}
android2-week8/W8-A7-ThreadedDownloadsBoundServices/src/edu/vuum/mocca/DownloadActivity.java
LFenske on 11 Jul 2014
Change "DONE" back to "TODO" for grading.
1 contributor
RawBlameHistory
import
import
import
import
import
import
import
android.content.ServiceConnection;
android.net.Uri;
android.os.IBinder;
android.os.RemoteException;
android.util.Log;
android.view.View;
android.os.AsyncTask;
/**
* This is the main Activity that the program uses to start the
* ThreadedDownloads application. It allows the user to input the URL
* of an image and download that image using one of two different
* Android Bound Service implementations: synchronous and
* asynchronous. The Activity starts the Service using bindService().
* After the Service is started, its onBind() hook method returns an
* implementation of an AIDL interface to the Activity by
* asynchronously calling the onServiceConnected() hook method in the
* Activity. The AIDL interface object that's returned can then be
* used to interact with the Service either synchronously or
* asynchronously, depending on the type of AIDL interface requested.
*
* Starting Bound Services to run synchronously in background Threads
* from the asynchronous UI Thread is an example of the
* Half-Sync/Half-Async Pattern. Starting Bound Services using
* Intents is an example of the Activator and Command Processor
* patterns. The DownloadActivity plays the role of the Creator and
* creates a Command in the form of an Intent. The Intent is received
* by the Service process, which plays the role of the Executor.
*
* The use of AIDL interfaces to pass information between two
* different processes is an example of the Broker Pattern, in which
* all communication-related functionality is encapsulated in the AIDL
* interface and the underlying Android Binder framework, shielding
* applications from tedious and error-prone aspects of inter-process
* communication.
*/
public class DownloadActivity extends DownloadBase {
/**
* Used for debugging.
*/
private final String TAG = this.getClass().getSimpleName();
/**
* The AIDL Interface that's used to make twoway calls to the
* DownloadServiceSync Service. This object plays the role of
* Requestor in the Broker Pattern. If it's null then there's no
* connection to the Service.
*/
DownloadCall mDownloadCall;
/**
* The AIDL Interface that we will use to make oneway calls to the
* DownloadServiceAsync Service. This plays the role of Requestor
* in the Broker Pattern. If it's null then there's no connection
* to the Service.
*/
DownloadRequest mDownloadRequest;
/**
* This ServiceConnection is used to receive results after binding
* to the DownloadServiceSync Service using bindService().
*/
ServiceConnection mServiceConnectionSync = new ServiceConnection() {
/**
* Cast the returned IBinder object to the DownloadCall
* AIDL Interface and store it for later use in
* mDownloadCall.
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.d(TAG, "ComponentName: " + name);
// TODO You fill in here to replace null with a call
// to a generated stub method that converts the
// service parameter into an interface that can be
// used to make RPC calls to the Service.
mDownloadCall = DownloadCall.Stub.asInterface(service);
}
/**
* Called if the remote service crashes and is no longer
* available. The ServiceConnection will remain bound,
* but the service will not respond to any requests.
*/
@Override
public void onServiceDisconnected(ComponentName name) {
mDownloadCall = null;
}
};
/**
* This ServiceConnection is used to receive results after binding
* to the DownloadServiceAsync Service using bindService().
*/
ServiceConnection mServiceConnectionAsync = new ServiceConnection() {
/**
* Cast the returned IBinder object to the DownloadRequest
* AIDL Interface and store it for later use in
* mDownloadRequest.
*/
@Override
public void onServiceConnected(ComponentName name,
IBinder service) {
// TODO You fill in here to replace null with a call
// to a generated stub method that converts the
// service parameter into an interface that can be
// used to make RPC calls to the Service.
mDownloadRequest = DownloadRequest.Stub.asInterface(service);
}
/**
* Called if the remote service crashes and is no longer
* available. The ServiceConnection will remain bound,
try {
return mDownloadCall.downloadImage(uris[0]);
} catch (RemoteException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String filePath) {
// This is executed in the UI thread.
displayBitmap(filePath);
}
}.execute(uri);
}
break;
case R.id.bound_async_button:
// TODO - You fill in here to call downloadImage() on
// mDownloadRequest, passing in the appropriate Uri and
// callback.
if (mDownloadRequest != null) {
try {
mDownloadRequest.downloadImage(uri, mDownloadCallback);
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
}
}
/**
* Hook method called when the DownloadActivity becomes visible to
* bind the Activity to the Services.
*/
@Override
public void onStart () {
super.onStart();
// Bind this activity to the DownloadBoundService* Services if
// they aren't already bound Use mBoundSync/mBoundAsync
if (mDownloadCall == null)
bindService(DownloadBoundServiceSync.makeIntent(this),
mServiceConnectionSync,
BIND_AUTO_CREATE);
if (mDownloadRequest == null)
bindService(DownloadBoundServiceAsync.makeIntent(this),
mServiceConnectionAsync,
BIND_AUTO_CREATE);
}
/**
* Hook method called when the DownloadActivity becomes completely
* hidden to unbind the Activity from the Services.
*/
@Override
public void onStop () {
super.onStop();
android2-week8/W8-A7-ThreadedDownloadsBoundServices/src/edu/vuum/mocca/DownloadBase.java
LFenske on 11 Jul 2014
Use AsyncTask so the UI thread doesn't block.
1 contributor
RawBlameHistory
import
import
import
import
import
import
import
import
import
import
import
import
android.app.Activity;
android.content.Context;
android.graphics.Bitmap;
android.graphics.BitmapFactory;
android.graphics.drawable.BitmapDrawable;
android.os.Bundle;
android.os.StrictMode;
android.util.Log;
android.view.View;
android.view.inputmethod.InputMethodManager;
android.widget.EditText;
android.widget.ImageView;
/**
* This class is used the base class for the DownloadActivity. It
* instantiates the UI and handles displaying images and getting text
* from the EditText object by making displayBitmap() and
* getUrlString() available to subclasses. This design separates
* concerns by having DownloadBase handle UI functionality while
* subclasses (such as DownloadActivity) handle any Service-related
* communication with the GeoNames Web service.
*
* GeoNamesBase is an example of the Template Method pattern since it
* extends Activity and overrides its onCreate() hook method. More
* generally, any object that extends Activity and overrides its hook
* methods, such as onStart() or onPause(), is also an example of the
* Template Method pattern.
*/
public class DownloadBase extends Activity {
/**
* Used for debugging.
*/
private final String TAG = this.getClass().getSimpleName();
/**
* This is the reference to the text box that allows the user to
* input a URL to an image for downloading.
*/
private EditText mUrlEditText;
/**
* This is a reference to the container of an image in the UI.
* When we finish downloading, we update this to display the image
* we just stored on the file system.
*/
private ImageView mImageView;
/**
* The original bitmap (used for reseting the image).
*/
private Bitmap mDefaultBitmap;
/**
* Store the current bitmap for testing purposes.
*/
public Bitmap mCurrentBitmap;
/**
* Hide the keyboard after a user has finished typing the url.
*/
protected void hideKeyboard() {
InputMethodManager mgr =
(InputMethodManager) getSystemService
(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(mUrlEditText.getWindowToken(),
0);
}
/**
* Display the given file in the ImageView. Use
* BitmapFactory.decodeFile(). Store the bitmap used to update
* the file to make testing easier.
*/
void displayBitmap (String pathname) {
mCurrentBitmap = BitmapFactory.decodeFile(pathname);
mImageView.setImageBitmap(mCurrentBitmap);
}
/**
* Gets the URL from the EditText
*/
String getUrlString () {
return mUrlEditText.getText().toString();
}
/**
* Resets image to the default image stored with the program.
*/
public void resetImage(View view) {
mImageView.setImageBitmap(mDefaultBitmap);
mCurrentBitmap = mDefaultBitmap;
Log.d(TAG, "reset Image");
}
/**
* This is called when the Activity is initially created. This is
* where we setup the UI for the activity and initialize any
* objects that need to exist while the activity exists.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(getClass().getSimpleName(), "onCreate");
super.onCreate(savedInstanceState);
// Use the Android framework to create a User Interface for
// this activity. The interface that should be created is
// defined in activity_download.xml in the res/layout folder.
setContentView(R.layout.activity_download);
// Once the UI is created, get a reference to the instantiated
// EditText and ImageView objects by providing their ids to
// the Android framework.
mUrlEditText = (EditText) findViewById(R.id.url);
mImageView = (ImageView) findViewById(R.id.imageView1);
// Store whatever image is originally displayed in the
android2-week8/W8-A7-ThreadedDownloadsBoundServices/src/edu/vuum/mocca/DownloadBoundServiceAsync.java
LFenske on 11 Jul 2014
Change "DONE" back to "TODO" for grading.
1 contributor
RawBlameHistory
import
import
import
import
android.content.Intent;
android.net.Uri;
android.os.IBinder;
android.os.RemoteException;
/**
* @class DownloadBoundServiceAsync
* @brief This class handles downloads using asynchronous AIDL
* interactions. The component that binds to this service
* should receive an IBinder. This IBinder should be an
* instance of DownloadRequest, which extends IBinder. The
* component can then interact with this service by making
* normal calls on the DownloadRequest object. Specifically,
* the component can ask this service to download an image,
* passing in a DownloadCallback object. Once the download is
* finished, this service should send the pathname of the
* downloaded file back to the calling component by calling
* sendPath() on the DownloadCallback object.
*
* AIDL is an example of the Broker Pattern, in which all
* interprocess communication details are hidden behind the
* AIDL interfaces.
*/
public class DownloadBoundServiceAsync extends Service{
/**
* The concrete implementation of the AIDL Interface
* DownloadRequest. We extend the Stub class, which implements
* DownloadRequest, so that Android can properly handle calls
* across process boundaries.
*
* This implementation plays the role of Invoker in the Broker
* Pattern.
*/
DownloadRequest.Stub mDownloadRequestImpl = new DownloadRequest.Stub() {
/**
* Download the image at the given Uri and return a
* pathname to the file on the Android file system by
* calling the sendPath() method on the provided callback
*
* Use the methods defined in DownloadUtils for code brevity.
*/
@Override
public void downloadImage(Uri uri,
DownloadCallback callback)
throws RemoteException {
// TODO You fill in here to download the file using
// the appropriate helper method in DownloadUtils and
// then send the pathname back to the client via the
// callback object.
String filePath = DownloadUtils.downloadFile(DownloadBoundServiceAsync.this, uri);
callback.sendPath(filePath);
}
};
/**
android2-week8/W8-A7-ThreadedDownloadsBoundServices/src/edu/vuum/mocca/DownloadBoundServiceSync.java
LFenske on 11 Jul 2014
Change "DONE" back to "TODO" for grading.
1 contributor
RawBlameHistory
android.app.Service;
android.content.Context;
android.content.Intent;
android.net.Uri;
android.os.IBinder;
android.os.RemoteException;
/**
* @class DownloadBoundServiceSync
*
* bindService().
*
* @param context The context of the calling component.
*/
public static Intent makeIntent(Context context) {
// TODO - replace the null to create the appropriate Intent
// and return it to the caller.
return new Intent(context, DownloadBoundServiceSync.class);
}
}
android2-week8/W8-A7-ThreadedDownloadsBoundServices/src/edu/vuum/mocca/DownloadUtils.java
LFenske on 11 Jul 2014
Use AsyncTask so the UI thread doesn't block.
1 contributor
RawBlameHistory
java.io.File;
java.io.FileOutputStream;
java.io.IOException;
java.io.InputStream;
java.io.OutputStream;
java.net.URL;
import edu.vuum.mocca.R;
import
import
import
import
android.content.Context;
android.net.Uri;
android.util.Base64;
android.util.Log;
/**
* @class DownloadUtils
*
* @brief This class encapsulates several static methods so that all
* Services can access them without redefining them in each
* Service.
*/
public class DownloadUtils {
/**
* Used for debugging.
*/
static final String TAG = "DownloadActivity";
/**
* If you have access to a stable Internet connection for testing
* purposes, feel free to change this variable to false so it
* actually downloads the image from a remote server.
*/
// TODO - You can change this to the appropriate setting for your
// environment.
static final boolean DOWNLOAD_OFFLINE = false;
/**
* The resource that we write to the file system in offline
* mode. Note that this must be the same image that the testing
* project expects. (found in res/drawable-nodpi and Options.java)
*/
static final int OFFLINE_TEST_IMAGE = R.raw.dougs;
/**
* The file name that we should use to store the image in offline mode
*/
static final String OFFLINE_FILENAME = "dougs.jpg";
/**
* Download the file located at the provided internet url using
* the URL class, store it on the android file system using
* openFileOutput(), and return the path to the file on disk.
*
* @param context the context in which to write the file
* @param uri the web url
*
* @return the path to the downloaded file on the file system
*/
public static String downloadFile (Context context,
Uri uri) {
try {
// If we're offline, write the image in our resources to
// disk, then return that pathname.
if (DOWNLOAD_OFFLINE) {
// Store the image on the file system. We can store it
// as private since the test project runs in the same
// process as the target project
FileOutputStream out =
context.openFileOutput(OFFLINE_FILENAME, 0);
// Get a stream from the image resource
InputStream in =
context.getResources().openRawResource(OFFLINE_TEST_IMAGE);
// Write the resource to disk.
copy(in, out);
in.close();
out.close();
return context.getFileStreamPath(Base64.encodeToString(url.getBytes(),
Base64.NO_WRAP));
}
/**
* Copy the contents of an InputStream into an OutputStream.
*
* @param in
* @param out
* @return
* @throws IOException
*/
static public int copy(final InputStream in,
final OutputStream out) throws IOException {
final int BUFFER_LENGTH = 1024;
final byte[] buffer = new byte[BUFFER_LENGTH];
int totalRead = 0;
int read = 0;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
totalRead += read;
}
return totalRead;
}
}
Coursera_Android_Week8/SourceFiles/Skeleton/
Completed Assignment
latest commit 0d385d1fa4
ShankOffice authored on 20 Mar 2014
..
ContentProviderLabContentProvider First commit
a year ago
ContentProviderLabUser
Completed Assignment
Coursera_Android_Week8/SourceFiles/Skeleton/ContentProviderLabUser/src/
course/labs/contentproviderlab/PlaceDownloaderTask.java
ShankOffice on 20 Mar 2014
Completed Assignment
0 contributors
RawBlameHistory
java.io.BufferedReader;
java.io.IOException;
java.io.InputStream;
java.io.InputStreamReader;
java.io.StringReader;
java.lang.ref.WeakReference;
java.net.HttpURLConnection;
java.net.MalformedURLException;
java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import
import
import
import
import
org.w3c.dom.DOMException;
org.w3c.dom.Document;
org.w3c.dom.Node;
org.w3c.dom.NodeList;
org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import
import
import
import
import
import
android.graphics.Bitmap;
android.graphics.BitmapFactory;
android.location.Location;
android.location.LocationManager;
android.os.AsyncTask;
android.util.Log;
place.setCountryName("United States");
place.setPlace("Berwyn");
place.setFlagBitmap(mStubBitmap);
place.setFlagUrl("stub.jpg");
}
}
return place;
}
@Override
protected void onPostExecute(PlaceRecord result) {
if (null != result && null != mParent.get()) {
mParent.get().addNewPlace(result);
}
}
private PlaceRecord getPlaceFromURL(String... params) {
String result = null;
BufferedReader in = null;
try {
URL url = new URL(params[0]);
mHttpUrl = (HttpURLConnection) url.openConnection();
in = new BufferedReader(new InputStreamReader(
mHttpUrl.getInputStream()));
StringBuffer sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
} catch (MalformedURLException e) {
} catch (IOException e) {
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
mHttpUrl.disconnect();
}
return placeDataFromXml(result);
}
private Bitmap getFlagFromURL(String flagUrl) {
InputStream in = null;
try {
URL url = new URL(flagUrl);
mHttpUrl = (HttpURLConnection) url.openConnection();
in = mHttpUrl.getInputStream();
return BitmapFactory.decodeStream(in);
} catch (MalformedURLException e) {
Log.e("DEBUG", e.toString());
} catch (IOException e) {
Log.e("DEBUG", e.toString());
} finally {
try {
if (null != in) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
mHttpUrl.disconnect();
}
return BitmapFactory.decodeResource(mParent.get().getResources(),
R.drawable.stub);
}
private static PlaceRecord placeDataFromXml(String xmlString) {
DocumentBuilder builder;
String countryName = "";
String countryCode = "";
String placeName = "";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(
xmlString)));
NodeList list = document.getDocumentElement().getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node curr = list.item(i);
NodeList list2 = curr.getChildNodes();
for (int j = 0; j < list2.getLength(); j++) {
Node curr2 = list2.item(j);
if (curr2.getNodeName() != null) {
if (curr2.getNodeName().equals("countryName")) {
countryName = curr2.getTextContent();
} else if (curr2.getNodeName().equals("countryCode")) {
countryCode = curr2.getTextContent();
} else if (curr2.getNodeName().equals("name")) {
placeName = curr2.getTextContent();
}
}
}
}
} catch (DOMException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return new PlaceRecord(generateFlagURL(countryCode.toLowerCase()),
null, countryName, placeName, -1, -1);
}
private static String generateURL(String username, Location location) {
return "http://www.geonames.org/findNearbyPlaceName?username="
+ username + "&style=full&lat=" + location.getLatitude()
+ "&lng=" + location.getLongitude();
}
private static String generateFlagURL(String countryCode) {
return "http://www.geonames.org/flags/x/" + countryCode + ".gif";
}
}
Coursera_Android_Week8/SourceFiles/Skeleton/ContentProviderLabUser/src/
course/labs/contentproviderlab/PlaceViewActivity.java
ShankOffice on 20 Mar 2014
Completed Assignment
0 contributors
RawBlameHistory
android.app.ListActivity;
android.app.LoaderManager.LoaderCallbacks;
android.content.Context;
android.content.CursorLoader;
android.content.Loader;
android.database.Cursor;
android.location.Location;
android.location.LocationListener;
android.location.LocationManager;
android.os.Bundle;
android.util.Log;
android.view.Menu;
import
import
import
import
import
import
import
android.view.MenuInflater;
android.view.MenuItem;
android.view.View;
android.view.View.OnClickListener;
android.widget.TextView;
android.widget.Toast;
course.labs.contentproviderlab.provider.PlaceBadgesContract;
// 2) The current location has been seen before - issue Toast message.
// Issue the following log call:
// log("You already have this location badge");
// 3) There is no current location - response is up to you. The best
// solution is to disable the footerView until you have a location.
// Issue the following log call:
}
@Override
public void onProviderDisabled(String provider) {
// not implemented
}
@Override
public void onProviderEnabled(String provider) {
// not implemented
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// not implemented
}
@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
log("Entered onCreateLoader()");
// TODO - Create a new CursorLoader and return it
return new CursorLoader(getApplicationContext(),PlaceBadgesContract.CONTENT_URI,null,null,null,null);
}
@Override
public void onLoadFinished(Loader<Cursor> newLoader, Cursor newCursor) {
// TODO - Swap in the newCursor
mCursorAdapter.swapCursor(newCursor);
}
@Override
public void onLoaderReset(Loader<Cursor> newLoader) {
// TODO - Swap in a null Cursor
mCursorAdapter.swapCursor(null);
}
private long age(Location location) {
return System.currentTimeMillis() - location.getTime();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.print_badges:
ArrayList<PlaceRecord> currData = mCursorAdapter.getList();
for (int i = 0; i < currData.size(); i++) {
log(currData.get(i).toString());
}
return true;
case R.id.delete_badges:
mCursorAdapter.removeAllViews();
return true;
case R.id.place_one:
mMockLocationProvider.pushLocation(37.422, -122.084);
return true;
case R.id.place_invalid:
mMockLocationProvider.pushLocation(0, 0);
return true;
case R.id.place_two:
mMockLocationProvider.pushLocation(38.996667, -76.9275);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private static void log(String msg) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, msg);
}
}
Coursera_Android_Week8/SourceFiles/Skeleton/ContentProviderLabUser/src/
course/labs/contentproviderlab/PlaceViewAdapter.java
ShankOffice on 20 Mar 2014
Completed Assignment
0 contributors
RawBlameHistory
java.io.BufferedOutputStream;
java.io.File;
java.io.FileNotFoundException;
java.io.FileOutputStream;
java.io.IOException;
java.util.ArrayList;
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
import
android.content.ContentValues;
android.content.Context;
android.database.Cursor;
android.graphics.Bitmap;
android.graphics.Bitmap.CompressFormat;
android.graphics.BitmapFactory;
android.location.Location;
android.net.Uri;
android.os.Environment;
android.util.Log;
android.view.LayoutInflater;
android.view.View;
android.view.ViewGroup;
android.widget.CursorAdapter;
android.widget.ImageView;
android.widget.TextView;
course.labs.contentproviderlab.provider.PlaceBadgesContract;
return list;
}
public void removeAllViews() {
list.clear();
// TODO - delete all records in the ContentProvider
mContext.getContentResolver().delete(PlaceBadgesContract.CONTENT_URI, null, null);
mContext.getContentResolver().notifyChange(PlaceBadgesContract.CONTENT_URI, null);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) view.getTag();
holder.flag.setImageBitmap(getBitmapFromFile(cursor.getString(cursor
.getColumnIndex(PlaceBadgesContract.FLAG_BITMAP_PATH))));
holder.country.setText("Country: "
+ cursor.getString(cursor
.getColumnIndex(PlaceBadgesContract.COUNTRY_NAME)));
holder.place.setText("Place: "
+ cursor.getString(cursor
.getColumnIndex(PlaceBadgesContract.PLACE_NAME)));
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View newView;
ViewHolder holder = new ViewHolder();
newView = inflater.inflate(R.layout.place_badge_view, null);
holder.flag = (ImageView) newView.findViewById(R.id.flag);
holder.country = (TextView) newView.findViewById(R.id.country_name);
holder.place = (TextView) newView.findViewById(R.id.place_name);
newView.setTag(holder);
return newView;
}
private Bitmap getBitmapFromFile(String filePath) {
return BitmapFactory.decodeFile(filePath);
}
private boolean storeBitmapToFile(Bitmap bitmap, String filePath) {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
try {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(filePath));
bitmap.compress(CompressFormat.PNG, 100, bos);
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
return false;
} catch (IOException e) {
return false;
}
return true;
}
return false;
}
private static void log(String msg) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(TAG, msg);
}
}
Coursera_Android_Week8/SourceFiles/Skeleton/ContentProviderLabUser/And
roidManifest.xml
ShankOffice on 20 Mar 2014
Completed Assignment
0 contributors
RawBlameHistory
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".PlaceViewActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>