package com.athena.asm.service;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v4.app.NotificationCompat;
import com.athena.asm.HomeActivity;
import com.athena.asm.R;
import com.athena.asm.util.FileUtil;
public class UpdateService extends Service {
private static final int TIMEOUT = 10 * 1000;// 超时
private static final String APK_URL = "https://github.com/zfdang/asm-android-client-for-newsmth/raw/master/dist/aSM.apk";
private static final int DOWN_IN_PROGRESS = 0;
private static final int DOWN_OK = 1;
private static final int DOWN_ERROR = 2;
private String app_name;
private boolean m_isRunning = false;
private NotificationManager mNotificationManager;
private Notification mNotification;
private NotificationCompat.Builder mBuilder;
private Intent mUpdateIntent;
private PendingIntent mPendingIntent;
private static final int NOTIFICATION_ID = 0;
@Override
public void onDestroy() {
mNotificationManager.cancel(NOTIFICATION_ID);
super.onDestroy();
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(m_isRunning == false){
if(intent == null){
return START_NOT_STICKY;
}
m_isRunning = true;
app_name = intent.getStringExtra("app_name");
FileUtil.createFile(app_name);
createNotification();
createThread();
}
// The service will not receive a onStartCommand(Intent, int, int) call with a null Intent with this value
return START_NOT_STICKY;
}
// this handler is responsible to update the progress bar
final Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case DOWN_OK:
// download finished, click to install
Uri uri = Uri.fromFile(FileUtil.updateFile);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
mPendingIntent = PendingIntent.getActivity(UpdateService.this, 0, intent, 0);
mBuilder.setContentTitle(getString(R.string.update_service_title_end));
mBuilder.setContentText(getString(R.string.update_service_content_end) + "("
+ FileUtil.updateFile.toString() + ")");
mBuilder.setTicker(getString(R.string.update_service_ticker_end));
mBuilder.setProgress(0, 0, false);
mBuilder.setAutoCancel(true);
mBuilder.setOngoing(false);
mBuilder.setContentIntent(mPendingIntent);
mNotification = mBuilder.build();
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
m_isRunning = false;
stopService(mUpdateIntent);
break;
case DOWN_IN_PROGRESS:
int updateCount = msg.arg1;
// update progress bar
mBuilder.setContentText(updateCount + "%");
mBuilder.setProgress(100, updateCount, false);
mNotification = mBuilder.build();
// show notification
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
break;
case DOWN_ERROR:
mBuilder.setContentText("下载失败");
mBuilder.setProgress(100, 100, true);
mBuilder.setAutoCancel(true);
mNotification = mBuilder.build();
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
m_isRunning = false;
stopService(mUpdateIntent);
break;
default:
stopService(mUpdateIntent);
mNotificationManager.cancel(NOTIFICATION_ID);
break;
}
}
};
/***
* 开线程下载
*/
public void createThread() {
new Thread(new Runnable() {
@Override
public void run() {
try {
long downloadSize = downloadUpdateFile(APK_URL, FileUtil.updateFile.toString());
if (downloadSize > 0) {
// 下载成功
final Message message = new Message();
message.what = DOWN_OK;
handler.sendMessage(message);
}
} catch (Exception e) {
e.printStackTrace();
final Message message = new Message();
message.what = DOWN_ERROR;
handler.sendMessage(message);
}
}
}).start();
}
/***
* 创建通知栏
*/
public void createNotification() {
mUpdateIntent = new Intent(this, HomeActivity.class);
mPendingIntent = PendingIntent.getActivity(this, 0, mUpdateIntent, 0);
mBuilder = new NotificationCompat.Builder(this)
.setContentTitle(getString(R.string.update_service_title_start))
.setContentText("0%")
.setProgress(100, 0, false)
.setSmallIcon(R.drawable.icon)
.setOngoing(true)
.setContentIntent(mPendingIntent)
.setTicker(getString(R.string.update_service_ticker_start));
mNotification = mBuilder.build();
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}
/***
* 下载文件
*
* @return
* @throws MalformedURLException
*/
public long downloadUpdateFile(String down_url, String file) throws Exception {
int down_step = 5;// 提示step
int totalSize;// 文件总大小
int downloadCount = 0;// 已经下载好的大小
int updateCount = 0;// 已经上传的文件大小
InputStream inputStream;
OutputStream outputStream;
URL url = new URL(down_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(TIMEOUT);
httpURLConnection.setReadTimeout(TIMEOUT);
// 获取下载文件的size
totalSize = httpURLConnection.getContentLength();
if (httpURLConnection.getResponseCode() == 404) {
throw new Exception("fail!");
}
inputStream = httpURLConnection.getInputStream();
outputStream = new FileOutputStream(file, false);// 文件存在则覆盖掉
byte buffer[] = new byte[1024];
int readsize = 0;
while ((readsize = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, readsize);
downloadCount += readsize;// 时时获取下载到的大小
/**
* 每次增张5%
*/
if (updateCount == 0 || (downloadCount * 100 / totalSize - down_step) >= updateCount) {
updateCount += down_step;
// call handler to upgrade progress bar
final Message message = new Message();
message.what = DOWN_IN_PROGRESS;
message.arg1 = updateCount;
handler.sendMessage(message);
}
}
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
inputStream.close();
outputStream.close();
return downloadCount;
}
}