1package com.android.pmc;
2
3import android.app.AlarmManager;
4import android.app.PendingIntent;
5import android.content.BroadcastReceiver;
6import android.content.Context;
7import android.content.Intent;
8import android.os.AsyncTask;
9import android.os.PowerManager;
10import android.os.SystemClock;
11import android.util.Log;
12
13import java.io.InputStream;
14import java.net.HttpURLConnection;
15import java.net.URL;
16/**
17 * Call wifi Download data whenever an alarm is received.
18 */
19public 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
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
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     */
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     */
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     */
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
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
140        protected void onCancelled(String result) {
141            mWakeLock.release();
142        }
143
144        @Override
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
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
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