Skip to content

Commit 4b0fe3a

Browse files
committed
app在线更新
0 parents  commit 4b0fe3a

File tree

33 files changed

+915
-0
lines changed

33 files changed

+915
-0
lines changed

.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
*.iml
2+
.gradle
3+
/local.properties
4+
/.idea/workspace.xml
5+
/.idea/libraries
6+
.DS_Store
7+
/build
8+
/captures
9+
.externalNativeBuild

app/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

app/build.gradle

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
apply plugin: 'com.android.application'
2+
3+
android {
4+
compileSdkVersion 25
5+
buildToolsVersion "25.0.2"
6+
defaultConfig {
7+
applicationId "com.example.teprinciple.updateappdemo"
8+
minSdkVersion 15
9+
targetSdkVersion 22
10+
versionCode 1
11+
versionName "1.0"
12+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13+
}
14+
buildTypes {
15+
release {
16+
minifyEnabled false
17+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18+
}
19+
}
20+
}
21+
22+
dependencies {
23+
compile fileTree(dir: 'libs', include: ['*.jar'])
24+
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25+
exclude group: 'com.android.support', module: 'support-annotations'
26+
})
27+
compile 'com.android.support:appcompat-v7:25.1.0'
28+
testCompile 'junit:junit:4.12'
29+
}

app/proguard-rules.pro

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Add project specific ProGuard rules here.
2+
# By default, the flags in this file are appended to flags specified
3+
# in C:\Users\Teprinciple\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
4+
# You can edit the include path and order by changing the proguardFiles
5+
# directive in build.gradle.
6+
#
7+
# For more details, see
8+
# http://developer.android.com/guide/developing/tools/proguard.html
9+
10+
# Add any project specific keep options here:
11+
12+
# If your project uses WebView with JS, uncomment the following
13+
# and specify the fully qualified class name to the JavaScript interface
14+
# class:
15+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16+
# public *;
17+
#}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.example.teprinciple.updateappdemo;
2+
3+
import android.content.Context;
4+
import android.support.test.InstrumentationRegistry;
5+
import android.support.test.runner.AndroidJUnit4;
6+
7+
import org.junit.Test;
8+
import org.junit.runner.RunWith;
9+
10+
import static org.junit.Assert.*;
11+
12+
/**
13+
* Instrumentation test, which will execute on an Android device.
14+
*
15+
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
16+
*/
17+
@RunWith(AndroidJUnit4.class)
18+
public class ExampleInstrumentedTest {
19+
@Test
20+
public void useAppContext() throws Exception {
21+
// Context of the app under test.
22+
Context appContext = InstrumentationRegistry.getTargetContext();
23+
24+
assertEquals("com.example.teprinciple.updateappdemo", appContext.getPackageName());
25+
}
26+
}

app/src/main/AndroidManifest.xml

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.example.teprinciple.updateappdemo">
4+
5+
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
6+
<uses-permission android:name="android.permission.INTERNET"/>
7+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
8+
9+
10+
<application
11+
android:allowBackup="true"
12+
android:icon="@mipmap/ic_launcher"
13+
android:label="@string/app_name"
14+
android:supportsRtl="true"
15+
android:theme="@style/AppTheme">
16+
<activity android:name=".MainActivity">
17+
<intent-filter>
18+
<action android:name="android.intent.action.MAIN"/>
19+
<category android:name="android.intent.category.LAUNCHER"/>
20+
</intent-filter>
21+
</activity>
22+
23+
<receiver
24+
android:name=".updateapp.UpdateAppReceiver"
25+
android:enabled="true"
26+
android:exported="true">
27+
<intent-filter>
28+
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
29+
<action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED"/>
30+
</intent-filter>
31+
</receiver>
32+
</application>
33+
34+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.example.teprinciple.updateappdemo;
2+
3+
import android.support.v7.app.AppCompatActivity;
4+
import android.os.Bundle;
5+
import android.view.View;
6+
7+
import com.example.teprinciple.updateappdemo.updateapp.UpdateAppUtil;
8+
9+
public class MainActivity extends AppCompatActivity {
10+
11+
@Override
12+
protected void onCreate(Bundle savedInstanceState) {
13+
super.onCreate(savedInstanceState);
14+
setContentView(R.layout.activity_main);
15+
}
16+
17+
public void updateApp(View view) {
18+
UpdateAppUtil.updateApp(this);
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.example.teprinciple.updateappdemo.customview;
2+
3+
import android.app.Dialog;
4+
import android.content.Context;
5+
import android.view.LayoutInflater;
6+
import android.view.View;
7+
import android.widget.TextView;
8+
9+
import com.example.teprinciple.updateappdemo.R;
10+
import com.example.teprinciple.updateappdemo.customview.feature.Callback;
11+
12+
13+
/**
14+
* Created by Teprinciple on 2016/10/13.
15+
*/
16+
public class ConfirmDialog extends Dialog implements View.OnClickListener {
17+
18+
Callback callback;
19+
private TextView content;
20+
private TextView sureBtn;
21+
private TextView cancleBtn;
22+
23+
public ConfirmDialog(Context context, Callback callback) {
24+
super(context, R.style.CustomDialog);
25+
this.callback = callback;
26+
setCustomDialog();
27+
}
28+
29+
private void setCustomDialog() {
30+
View mView = LayoutInflater.from(getContext()).inflate(R.layout.dialog_confirm, null);
31+
sureBtn = (TextView)mView.findViewById(R.id.dialog_confirm_sure);
32+
cancleBtn = (TextView)mView.findViewById(R.id.dialog_confirm_cancle);
33+
content = (TextView) mView.findViewById(R.id.dialog_confirm_title);
34+
sureBtn.setOnClickListener(this);
35+
cancleBtn.setOnClickListener(this);
36+
super.setContentView(mView);
37+
}
38+
39+
40+
public ConfirmDialog setContent(String s){
41+
content.setText(s);
42+
return this;
43+
}
44+
45+
46+
@Override
47+
public void onClick(View v) {
48+
switch (v.getId()){
49+
case R.id.dialog_confirm_cancle:
50+
this.cancel();
51+
break;
52+
53+
case R.id.dialog_confirm_sure:
54+
callback.callback();
55+
this.cancel();
56+
break;
57+
}
58+
}
59+
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.example.teprinciple.updateappdemo.customview.feature;
2+
3+
/**
4+
* Created by sanmu on 2016/10/13 0013.
5+
*/
6+
public interface Callback {
7+
public void callback();
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
package com.example.teprinciple.updateappdemo.updateapp;
2+
3+
import android.app.DownloadManager;
4+
import android.content.Context;
5+
import android.content.Intent;
6+
import android.net.Uri;
7+
import android.os.Environment;
8+
import android.text.TextUtils;
9+
import android.util.Log;
10+
import android.widget.Toast;
11+
12+
import java.io.File;
13+
14+
15+
16+
/**
17+
*Created by Teprinciple on 2016/12/13.
18+
*/
19+
public class DownloadAppUtils {
20+
private static final String TAG = DownloadAppUtils.class.getSimpleName();
21+
public static long downloadUpdateApkId = -1;//下载更新Apk 下载任务对应的Id
22+
public static String downloadUpdateApkFilePath;//下载更新Apk 文件路径
23+
24+
/**
25+
* 通过浏览器下载APK包
26+
* @param context
27+
* @param url
28+
*/
29+
public static void downloadForWebView(Context context, String url) {
30+
Uri uri = Uri.parse(url);
31+
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
32+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
33+
intent.setDataAndType(Uri.fromFile(new File(Environment
34+
.getExternalStorageDirectory(), "tmp.apk")),
35+
"application/vnd.android.package-archive");
36+
context.startActivity(intent);
37+
}
38+
39+
40+
/**
41+
* 下载更新apk包
42+
* 权限:1,<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
43+
* @param context
44+
* @param url
45+
*/
46+
public static void downloadForAutoInstall(Context context, String url, String fileName, String title) {
47+
//LogUtil.e("App 下载 url="+url+",fileName="+fileName+",title="+title);
48+
if (TextUtils.isEmpty(url)) {
49+
return;
50+
}
51+
try {
52+
Uri uri = Uri.parse(url);
53+
DownloadManager downloadManager = (DownloadManager) context
54+
.getSystemService(Context.DOWNLOAD_SERVICE);
55+
DownloadManager.Request request = new DownloadManager.Request(uri);
56+
//在通知栏中显示
57+
request.setVisibleInDownloadsUi(true);
58+
request.setTitle(title);
59+
String filePath = null;
60+
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {//外部存储卡
61+
filePath = Environment.getExternalStorageDirectory().getAbsolutePath();
62+
63+
} else {
64+
Log.i(TAG,"没有SD卡");
65+
return;
66+
}
67+
downloadUpdateApkFilePath = filePath + File.separator + fileName;
68+
// 若存在,则删除
69+
deleteFile(downloadUpdateApkFilePath);
70+
Uri fileUri = Uri.parse("file://" + downloadUpdateApkFilePath);
71+
request.setDestinationUri(fileUri);
72+
downloadUpdateApkId = downloadManager.enqueue(request);
73+
} catch (Exception e) {
74+
e.printStackTrace();
75+
downloadForWebView(context, url);
76+
}finally {
77+
// registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
78+
}
79+
}
80+
81+
82+
private static boolean deleteFile(String fileStr) {
83+
File file = new File(fileStr);
84+
return file.delete();
85+
}
86+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.example.teprinciple.updateappdemo.updateapp;
2+
3+
import android.app.DownloadManager;
4+
import android.content.BroadcastReceiver;
5+
import android.content.Context;
6+
import android.content.Intent;
7+
import android.database.Cursor;
8+
import android.net.Uri;
9+
import android.util.Log;
10+
11+
12+
/**
13+
* 注册
14+
* <action android:name="android.intent.action.DOWNLOAD_COMPLETE" />
15+
* <action android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED"/>
16+
*/
17+
public class UpdateAppReceiver extends BroadcastReceiver {
18+
public UpdateAppReceiver() {
19+
}
20+
21+
@Override
22+
public void onReceive(Context context, Intent intent) {
23+
24+
// 处理下载完成
25+
Cursor c=null;
26+
try {
27+
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
28+
if (DownloadAppUtils.downloadUpdateApkId >= 0) {
29+
long downloadId = DownloadAppUtils.downloadUpdateApkId;
30+
DownloadManager.Query query = new DownloadManager.Query();
31+
query.setFilterById(downloadId);
32+
DownloadManager downloadManager = (DownloadManager) context
33+
.getSystemService(Context.DOWNLOAD_SERVICE);
34+
c = downloadManager.query(query);
35+
if (c.moveToFirst()) {
36+
int status = c.getInt(c
37+
.getColumnIndex(DownloadManager.COLUMN_STATUS));
38+
if (status == DownloadManager.STATUS_FAILED) {
39+
downloadManager.remove(downloadId);
40+
41+
} else if (status == DownloadManager.STATUS_SUCCESSFUL) {
42+
if (DownloadAppUtils.downloadUpdateApkFilePath != null) {
43+
Intent i = new Intent(Intent.ACTION_VIEW);
44+
i.setDataAndType(
45+
Uri.parse("file://"
46+
+ DownloadAppUtils.downloadUpdateApkFilePath),
47+
"application/vnd.android.package-archive");
48+
//todo 针对不同的手机 以及sdk版本 这里的uri地址可能有所不同
49+
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
50+
context.startActivity(i);
51+
}
52+
}
53+
}
54+
}
55+
}/* else if (DownloadManager.ACTION_NOTIFICATION_CLICKED.equals(intent.getAction())) {//点击通知取消下载
56+
DownloadManager downloadManager = (DownloadManager) context
57+
.getSystemService(Context.DOWNLOAD_SERVICE);
58+
long[] ids = intent.getLongArrayExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS);
59+
//点击通知栏取消下载
60+
downloadManager.remove(ids);
61+
}*/
62+
63+
} catch (Exception e) {
64+
e.printStackTrace();
65+
}finally {
66+
if (c != null) {
67+
c.close();
68+
}
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)