1 package com.android.pmc;
2 
3 import android.app.AlarmManager;
4 import android.app.PendingIntent;
5 import android.content.BroadcastReceiver;
6 import android.content.Context;
7 import android.content.Intent;
8 import android.os.AsyncTask;
9 import android.os.PowerManager;
10 import android.os.SystemClock;
11 import android.util.Log;
12 
13 import java.io.InputStream;
14 import java.net.HttpURLConnection;
15 import java.net.URL;
16 /**
17  * Call wifi Download data whenever an alarm is received.
18  */
19 public class WifiDownloadReceiver extends BroadcastReceiver {
20     private static final int DOWNLOAD_BUFFER_SIZE = 1024 * 4;
21 
22     DownloadTask mDownloadTask;
23     PMCMainActivity mPMCMainActivity;
24     int mFileCount;
25     int mBytesCount;
26     long mDownloadStartTime;
27     String mDownloadURL;
28     private Context mContext;
29     private PowerManager.WakeLock mWakeLock;
30     private int mAlarmInterval;
31     private AlarmManager mAlarmManager;
32     private PendingIntent mAlarmIntent;
33 
WifiDownloadReceiver(PMCMainActivity activity, String url, int interval, AlarmManager alarmManager, PendingIntent alarmIntent)34     public WifiDownloadReceiver(PMCMainActivity activity, String url, int interval,
35                                 AlarmManager alarmManager, PendingIntent alarmIntent) {
36         mPMCMainActivity = activity;
37         mDownloadURL = url;
38         mFileCount = 0;
39         mBytesCount = 0;
40         mDownloadStartTime = -1;
41         mAlarmInterval = interval;
42         mAlarmManager = alarmManager;
43         mAlarmIntent = alarmIntent;
44     }
45 
46     @Override
onReceive(Context context, Intent intent)47     public void onReceive(Context context, Intent intent) {
48         if (mDownloadTask != null && mDownloadTask.getStatus() != AsyncTask.Status.FINISHED) {
49             Log.e(PMCMainActivity.TAG, "Previous download still running.");
50             try {
51                 mDownloadTask.get();
52             } catch (Exception e) {
53                 Log.e(PMCMainActivity.TAG, "Download cancelled.");
54             }
55         } else {
56             mContext = context;
57             PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
58             mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "WIFITEST");
59             // Acquire the lock
60             mWakeLock.acquire();
61             Log.i(PMCMainActivity.TAG, "Starting Download Task");
62             mDownloadTask = new DownloadTask();
63             mDownloadTask.execute(mDownloadURL);
64         }
65         scheduleDownload();
66     }
67 
68     /**
69      * Schedule the next download.
70      */
scheduleDownload()71     public void scheduleDownload() {
72         if (mDownloadStartTime == -1) {
73             // Note down the start of all download activity
74             mDownloadStartTime = System.currentTimeMillis();
75         }
76         Log.i(PMCMainActivity.TAG, "Scheduling the next download after " + mAlarmInterval);
77         mAlarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
78                 SystemClock.elapsedRealtime() + mAlarmInterval, mAlarmIntent);
79     }
80 
81     /**
82      * Cancel the downloads.
83      */
cancelDownload()84     public void cancelDownload() {
85         mAlarmManager.cancel(mAlarmIntent);
86         if (mDownloadTask != null) mDownloadTask.cancel(true);
87     }
88 
89     /**
90      * Returns an approximate data rate at which we're downloading the files.
91      * @return
92      */
getDownloadRate()93     public int getDownloadRate() {
94         long durationInMilliSeconds = (System.currentTimeMillis() - mDownloadStartTime);
95         int durationInSeconds = (int) (durationInMilliSeconds / 1000);
96         return (mBytesCount / durationInSeconds);
97     }
98 
99     class DownloadTask extends AsyncTask<String, Integer, String> {
100         @Override
doInBackground(String... sUrl)101         protected String doInBackground(String... sUrl) {
102             //android.os.Debug.waitForDebugger();
103             Log.d(PMCMainActivity.TAG, "Starting background task for downloading file");
104             HttpURLConnection connection = null;
105             try {
106                 URL url = new URL(sUrl[0]);
107                 connection = (HttpURLConnection) url.openConnection();
108                 connection.connect();
109                 // expect HTTP 200 OK, so we don't mistakenly save error report
110                 // instead of the file
111                 if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
112                     return "Server returned HTTP " + connection.getResponseCode()
113                             + " " + connection.getResponseMessage();
114                 }
115                 // this will be useful to display download percentage
116                 // might be -1: server did not report the length
117                 int fileLength = connection.getContentLength();
118                 int bytesRead = downloadFile(connection);
119                 if (fileLength != bytesRead) {
120                     return "Expected file of size " + fileLength + " but only received "
121                             + bytesRead;
122                 }
123                 Log.d(PMCMainActivity.TAG, "Downloaded file size " + fileLength);
124                 mFileCount += 1;
125                 mBytesCount += fileLength;
126                 publishProgress(mFileCount, getDownloadRate());
127                 Thread.sleep(10000);
128             } catch (Exception e) {
129                 Log.e(PMCMainActivity.TAG, e.toString());
130                 return e.toString();
131             } finally {
132                 if (connection != null) {
133                     connection.disconnect();
134                 }
135             }
136             return null;
137         }
138 
139         @Override
onCancelled(String result)140         protected void onCancelled(String result) {
141             mWakeLock.release();
142         }
143 
144         @Override
onProgressUpdate(Integer... values)145         protected void onProgressUpdate(Integer... values) {
146             Log.d(PMCMainActivity.TAG, "DownloadTask onProgressUpdate updating the UI");
147             mPMCMainActivity.updateProgressStatus("Total file downloaded :: "
148                     + values[0].toString() + ", Data rate :: "
149                     + values[1].toString() + " bytes/sec");
150         }
151 
152         @Override
onPostExecute(String error)153         protected void onPostExecute(String error) {
154             if (error != null) {
155                 Log.e(PMCMainActivity.TAG, error);
156                 mPMCMainActivity.updateProgressStatus(error);
157             }
158             mWakeLock.release();
159         }
160 
downloadFile(HttpURLConnection connection)161         private int downloadFile(HttpURLConnection connection) {
162             if (connection == null) return -1;
163             int totalBytesRead = 0;
164             InputStream inputStream = null;
165             // Just read out the input file, not saving it anywhere in the device
166             try {
167                 inputStream = connection.getInputStream();
168                 int bytesRead = -1;
169                 byte[] buffer = new byte[DOWNLOAD_BUFFER_SIZE];
170                 while ((bytesRead = inputStream.read(buffer)) != -1) {
171                     totalBytesRead += bytesRead;
172                 }
173             } catch (Exception e) {
174                 Log.e(PMCMainActivity.TAG, "Downloaded failed");
175             } finally {
176                 try {
177                     if (inputStream != null) inputStream.close();
178                 } catch (Exception e) {
179                     Log.e(PMCMainActivity.TAG, "Downloaded close failed");
180                 }
181             }
182             return totalBytesRead;
183         }
184     }
185 }
186