http://developer.android.youdaxue.com/training/basics/network-ops/connecting.html#security
In order to perform network operations in your application, your manifest must include the following permissions:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
public class MainActivity extends FragmentActivity implements DownloadCallback {
...
// Keep a reference to the NetworkFragment, which owns the AsyncTask object
// that is used to execute network ops.
private NetworkFragment mNetworkFragment;
// Boolean telling us whether a download is in progress, so we don't trigger overlapping
// downloads with consecutive button clicks.
private boolean mDownloading = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
...
mNetworkFragment = NetworkFragment.getInstance(getSupportFragmentManager(), "https://www.google.com");
}
private void startDownload() {
if (!mDownloading && mNetworkFragment != null) {
// Execute the async download.
mNetworkFragment.startDownload();
mDownloading = true;
}
}
}
/**
* Implementation of headless Fragment that runs an AsyncTask to fetch data from the network.
*/
public class NetworkFragment extends Fragment {
public static final String TAG = "NetworkFragment";
private static final String URL_KEY = "UrlKey";
private DownloadCallback mCallback;
private DownloadTask mDownloadTask;
private String mUrlString;
/**
* Static initializer for NetworkFragment that sets the URL of the host it will be downloading
* from.
*/
public static NetworkFragment getInstance(FragmentManager fragmentManager, String url) {
NetworkFragment networkFragment = new NetworkFragment();
Bundle args = new Bundle();
args.putString(URL_KEY, url);
networkFragment.setArguments(args);
fragmentManager.beginTransaction().add(networkFragment, TAG).commit();
return networkFragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mUrlString = getArguments().getString(URL_KEY);
...
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
// Host Activity will handle callbacks from task.
mCallback = (DownloadCallback) context;
}
@Override
public void onDetach() {
super.onDetach();
// Clear reference to host Activity to avoid memory leak.
mCallback = null;
}
@Override
public void onDestroy() {
// Cancel task when Fragment is destroyed.
cancelDownload();
super.onDestroy();
}
/**
* Start non-blocking execution of DownloadTask.
*/
public void startDownload() {
cancelDownload();
mDownloadTask = new DownloadTask();
mDownloadTask.execute(mUrlString);
}
/**
* Cancel (and interrupt if necessary) any ongoing DownloadTask execution.
*/
public void cancelDownload() {
if (mDownloadTask != null) {
mDownloadTask.cancel(true);
}
}
...
/**
* Implementation of AsyncTask designed to fetch data from the network.
*/
private class DownloadTask extends AsyncTask<String, Integer, DownloadTask.Result> {
private DownloadCallback<String> mCallback;
DownloadTask(DownloadCallback<String> callback) {
setCallback(callback);
}
void setCallback(DownloadCallback<String> callback) {
mCallback = callback;
}
/**
* Wrapper class that serves as a union of a result value and an exception. When the download
* task has completed, either the result value or exception can be a non-null value.
* This allows you to pass exceptions to the UI thread that were thrown during doInBackground().
*/
static class Result {
public String mResultValue;
public Exception mException;
public Result(String resultValue) {
mResultValue = resultValue;
}
public Result(Exception exception) {
mException = exception;
}
}
/**
* Cancel background network operation if we do not have network connectivity.
*/
@Override
protected void onPreExecute() {
if (mCallback != null) {
NetworkInfo networkInfo = mCallback.getActiveNetworkInfo();
if (networkInfo == null || !networkInfo.isConnected() ||
(networkInfo.getType() != ConnectivityManager.TYPE_WIFI
&& networkInfo.getType() != ConnectivityManager.TYPE_MOBILE)) {
// If no connectivity, cancel task and update Callback with null data.
mCallback.updateFromDownload(null);
cancel(true);
}
}
}
/**
* Defines work to perform on the background thread.
*/
@Override
protected DownloadTask.Result doInBackground(String... urls) {
Result result = null;
if (!isCancelled() && urls != null && urls.length > 0) {
String urlString = urls[0];
try {
URL url = new URL(urlString);
String resultString = downloadUrl(url);
if (resultString != null) {
result = new Result(resultString);
} else {
throw new IOException("No response received.");
}
} catch(Exception e) {
result = new Result(e);
}
}
return result;
}
/**
* Updates the DownloadCallback with the result.
*/
@Override
protected void onPostExecute(Result result) {
if (result != null && mCallback != null) {
if (result.mException != null) {
mCallback.updateFromDownload(result.mException.getMessage());
} else if (result.mResultValue != null) {
mCallback.updateFromDownload(result.mResultValue);
}
mCallback.finishDownloading();
}
}
/**
* Override to add special behavior for cancelled AsyncTask.
*/
@Override
protected void onCancelled(Result result) {
}
}
public interface DownloadCallback<T> {
interface Progress {
int ERROR = -1;
int CONNECT_SUCCESS = 0;
int GET_INPUT_STREAM_SUCCESS = 1;
int PROCESS_INPUT_STREAM_IN_PROGRESS = 2;
int PROCESS_INPUT_STREAM_SUCCESS = 3;
}
/**
* Indicates that the callback handler needs to update its appearance or information based on
* the result of the task. Expected to be called from the main thread.
*/
void updateFromDownload(T result);
/**
* Get the device's active network status in the form of a NetworkInfo object.
*/
NetworkInfo getActiveNetworkInfo();
/**
* Indicate to callback handler any progress update.
* @param progressCode must be one of the constants defined in DownloadCallback.Progress.
* @param percentComplete must be 0-100.
*/
void onProgressUpdate(int progressCode, int percentComplete);
/**
* Indicates that the download operation has finished. This method is called even if the
* download hasn't completed successfully.
*/
void finishDownloading();
}