/[projects]/android/AndroidUtils/src/dk/thoerup/androidutils/CheckUpdates.java
ViewVC logotype

Contents of /android/AndroidUtils/src/dk/thoerup/androidutils/CheckUpdates.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1247 - (show annotations) (download)
Wed Mar 30 19:52:31 2011 UTC (13 years, 1 month ago) by torben
File size: 7536 byte(s)
"Forced"update - download to same APK filename as found on webserver
1 package dk.thoerup.androidutils;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.File;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.RandomAccessFile;
8 import java.net.URL;
9 import java.net.URLConnection;
10
11 import android.app.AlertDialog;
12 import android.app.Notification;
13 import android.app.NotificationManager;
14 import android.app.PendingIntent;
15 import android.content.Context;
16 import android.content.DialogInterface;
17 import android.content.Intent;
18 import android.content.SharedPreferences;
19 import android.content.DialogInterface.OnClickListener;
20 import android.content.SharedPreferences.Editor;
21 import android.content.pm.PackageInfo;
22 import android.content.pm.PackageManager;
23 import android.content.pm.PackageManager.NameNotFoundException;
24 import android.net.Uri;
25 import android.os.AsyncTask;
26 import android.os.Environment;
27 import android.util.Log;
28
29 public class CheckUpdates {
30 final static long TIMESPAN_DAY = 24*60*60*1000; // one day
31
32 final static String CHECKUPDATES = "CheckUpdates";
33 final static String LASTCHECK = "lastcheck";
34
35 int versionCode;
36 String versionName;
37 String packageName;
38 String phone_model;
39 String androidVersion;
40
41 String title;
42
43
44 Context context;
45
46 public void checkForUpdates(Context context, String url, String title, String apkUrl) {
47 checkForUpdates(context, url, title, apkUrl, false);
48 }
49
50 public void checkForUpdates(Context context, String url, String title, String apkUrl, boolean forced) {
51 this.context = context;
52 this.title = title;
53
54 SharedPreferences prefs = context.getSharedPreferences(CHECKUPDATES, Context.MODE_PRIVATE);
55
56 long lastCheck = prefs.getLong(LASTCHECK, 0);
57
58 long now = System.currentTimeMillis(); //should i use android.os.SystemClock.elapsedRealtime() instead ?
59 Log.i(CHECKUPDATES, "Now=" + now + ", lastCheck=" + lastCheck + ", lastCheck+timespan=" + (lastCheck + TIMESPAN_DAY) );
60
61 if ( now > (lastCheck+TIMESPAN_DAY) ){
62
63 PackageManager pm = context.getPackageManager();
64 try {
65 PackageInfo pi;
66
67 pi = pm.getPackageInfo(context.getPackageName(), 0);
68
69 versionCode = pi.versionCode;
70 versionName = pi.versionName;
71 packageName = pi.packageName;
72 phone_model = android.os.Build.MODEL;
73 androidVersion = android.os.Build.VERSION.RELEASE;
74
75
76 UpdateTask task = new UpdateTask(forced);
77 task.execute(url, apkUrl);
78
79
80 } catch (NameNotFoundException e) {
81 Log.e(CHECKUPDATES, "NamingException", e);
82 }
83
84 }
85 }
86
87
88 class UpdateTask extends AsyncTask<String,Void,Void> {
89 boolean result = false;
90 int newestVersion = 0;
91
92 String apkUrl;
93
94 boolean forced = false;
95
96 public UpdateTask(boolean forced) {
97 this.forced = forced;
98 }
99
100 @Override
101 protected Void doInBackground(String... arg0) {
102 String requestUrl = arg0[0] + "?version=" + encode(versionName) + "&phone=" + encode(phone_model) + "&android=" + encode(androidVersion);
103 apkUrl = arg0[1];
104
105 try {
106 URL url = new URL(requestUrl);
107 URLConnection conn = url.openConnection();
108 conn.setConnectTimeout(2500);
109
110 String resultStr = readIOStream( conn.getInputStream() );
111 resultStr = resultStr.trim();
112 newestVersion = Integer.parseInt(resultStr);
113
114 result = true;
115
116 } catch (Exception e) {
117 Log.e(CHECKUPDATES, "Check for " + packageName + " failed!", e);
118 }
119
120 return null;
121 }
122
123 private String encode(String data) {
124 try {
125 return java.net.URLEncoder.encode(data, "UTF-8");
126 } catch (Exception e) {
127 return data; //if encoding fails, return original and hope all goes well
128 }
129 }
130
131 private String readIOStream(InputStream in) throws IOException {
132 ByteArrayOutputStream baos = new ByteArrayOutputStream();
133
134 byte buf[] = new byte[1024];
135 int len;
136
137 while ( (len=in.read(buf)) != -1) {
138 baos.write(buf, 0, len);
139 }
140
141 return baos.toString();
142 }
143
144 @Override
145 protected void onPostExecute(Void r) {
146 super.onPostExecute(r);
147
148 Log.i(CHECKUPDATES, "result=" + result + ", newestVersion" + newestVersion + ", versionCode=" + versionCode);
149
150 if (result == true) {
151
152 long now = System.currentTimeMillis();
153 SharedPreferences prefs = context.getSharedPreferences(CHECKUPDATES, Context.MODE_PRIVATE);
154 //when done write
155
156 Editor edit = prefs.edit();
157 edit.putLong(LASTCHECK, now );
158 edit.commit();
159
160
161 if (newestVersion > versionCode) {
162 String launchUrl = (apkUrl == null) ? "market://search?q=pname:" + packageName : apkUrl;
163
164 if (forced == true) {
165 forcedUpdate(launchUrl);
166 } else {
167 //showUpdateDialog(launchUrl);
168 showNotification(launchUrl);
169 }
170 }
171
172 }
173
174 }
175
176 private void forcedUpdate(String apkUrl) {
177 Log.e(CHECKUPDATES, "Forced update started");
178 try {
179 byte[] apkData = HttpUtil.getContent(apkUrl, 5000);
180 File tempFile = new File( Environment.getExternalStorageDirectory() + "/" + HttpUtil.getLastPart(apkUrl) );
181
182 if (tempFile.exists()) {
183 tempFile.delete();
184 }
185
186 RandomAccessFile raf = new RandomAccessFile(tempFile,"rw");
187 raf.write(apkData);
188
189 Log.e(CHECKUPDATES, "File:" + tempFile.getPath());
190
191
192
193 Intent i =new Intent();
194 i.setAction(Intent.ACTION_VIEW);
195 i.setDataAndType( Uri.fromFile(tempFile), "application/vnd.android.package-archive");
196 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
197
198
199 try {
200 context.startActivity(i);
201 } catch (Exception e) {
202 Log.e(CHECKUPDATES, "Activity launch failed", e);
203 }
204 context = null;
205
206 } catch (Exception e) {
207 Log.e(CHECKUPDATES, "forcedUpdate failed", e);
208 }
209 }
210
211 private void showNotification(String launchUrl) {
212 NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
213 //int icon = android.R.drawable.sym_action_email; //TODO: find a better icon
214 int icon = R.drawable.searchicon;
215
216
217 Notification notification = new Notification(icon, "Update available", System.currentTimeMillis() );
218 notification.flags |= Notification.FLAG_AUTO_CANCEL ;
219
220 CharSequence contentTitle = title;
221 CharSequence contentText = "New version available.";
222 Intent notificationIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(launchUrl) );
223 notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
224 PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
225
226 notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
227
228 nm.notify(1, notification);
229
230 }
231
232 private void showUpdateDialog(final String launchUrl) {
233 AlertDialog.Builder builder = new AlertDialog.Builder(context);
234 builder.setTitle(title);
235 builder.setMessage("This application has an a newer version available. Update now?");
236
237 builder.setPositiveButton("Yes", new OnClickListener() {
238 public void onClick(DialogInterface dialog, int which) {
239
240
241 Intent i = new Intent(Intent.ACTION_VIEW, Uri.parse(launchUrl) );
242 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK );
243 try {
244 context.startActivity(i);
245 } catch (Exception e) {
246 Log.e(CHECKUPDATES, "Activity launch failed", e);
247 }
248 context = null;
249
250 }
251 });
252 builder.setNegativeButton("No", new OnClickListener() {
253 public void onClick(DialogInterface dialog, int which) {
254 context = null;
255 }
256 });
257
258 try {
259 builder.show();
260 } catch (Exception e) {
261 Log.e(CHECKUPDATES, "Builder.show failed", e);
262 }
263 }
264
265 }
266
267
268 }

  ViewVC Help
Powered by ViewVC 1.1.20