1.使用蒲公英平台上传app,能够自动检测版本,进行更新提示,以及下载app。同时能够摇一摇进行反馈意见,对app下载数量进行统计,错误日志的反馈等实现。
2.蒲公英地址:https://www.pgyer.com/
3.下载android sdk
4.sdk只有一个jar包,没有so文件。复制过来添加为依赖就行了。
5.project 下的gradle需要改点东西,[加粗部分]
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven { url "https://raw.githubusercontent.com/Pgyer/mvn_repo_pgyer/master" }
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
6.module下的gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "myapplication.com.mypugongying"
minSdkVersion 15
targetSdkVersion 23
versionCode 1
versionName "1.6"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile files('libs/pgyer_sdk_2.4.4.jar')
compile 'com.jiechic.library:xUtils:2.6.14'
}
7.加入的权限以及appid
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="myapplication.com.mypugongying" android:versionCode="1" android:versionName="1.6"> <!-- 蒲公英权限 开始--> <!-- 必选--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <!-- 获取网络状态 --> <uses-permission android:name="android.permission.INTERNET"/> <!-- 网络通信--> <uses-permission android:name="android.permission.READ_PHONE_STATE"/> <!-- 获取设备信息 --> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <!-- 获取MAC地址--> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!-- 读写sdcard,storage等等 --> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <!-- 允许程序录制音频 --> <!-- 可选--> <uses-permission android:name="android.permission.READ_LOGS"/> <!-- 获取logcat日志 --> <!-- 蒲公英权限 结束--> <application android:name=".PgyApplication" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- pgy--> <meta-data android:name="PGYER_APPID" android:value="44dd260d8834e5b779b242fe77545681" > </meta-data> <!-- pgy --> </application> </manifest>
8. 下载工具类:Httputils
package myapplication.com.mypugongying; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.HttpURLConnection; import java.net.URL; /** * Created by Administrator on 2016/10/18. */ public class Httputils { public static String doPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); // 打开和URL之间的连接 HttpURLConnection conn = (HttpURLConnection) realUrl .openConnection(); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("charset", "utf-8"); conn.setUseCaches(false); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // conn.setReadTimeout(TIMEOUT_IN_MILLIONS); //conn.setConnectTimeout(TIMEOUT_IN_MILLIONS); if (param != null && !param.trim().equals("")) { // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(param); // flush输出流的缓冲 out.flush(); } // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader( new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { e.printStackTrace(); } // 使用finally块来关闭输出流、输入流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (Exception ex) { ex.printStackTrace(); } } return result; } }
9.PgyApplication.这里的名称需要在配置文件中加入: android:name=".PgyApplication"
package myapplication.com.mypugongying; /** * Created by Administrator on 2016/10/18. */ import com.pgyersdk.crash.PgyCrashManager; import com.pgyersdk.javabean.AppBean; import com.pgyersdk.update.PgyUpdateManager; import com.pgyersdk.update.UpdateManagerListener; import android.app.Application; import android.content.DialogInterface; import android.support.v7.app.AlertDialog; public class PgyApplication extends Application { @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); PgyCrashManager.register(this); } }
10. mainactivity.java
package myapplication.com.mypugongying; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Environment; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import com.lidroid.xutils.HttpUtils; import com.lidroid.xutils.exception.HttpException; import com.lidroid.xutils.http.ResponseInfo; import com.lidroid.xutils.http.callback.RequestCallBack; import com.pgyersdk.crash.PgyCrashManager; import com.pgyersdk.javabean.AppBean; import com.pgyersdk.update.PgyUpdateManager; import com.pgyersdk.update.UpdateManagerListener; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.File; public class MainActivity extends AppCompatActivity { String checkurl="http://www.pgyer.com/apiv1/app/viewGroup"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String codeversin=getVersion(); new Thread(new Runnable() { @Override public void run() { check(); } }).start(); } private void installAPK(File savedFile) { //调用系统的安装方法 Intent intent=new Intent(); intent.setAction(intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(savedFile), "application/vnd.android.package-archive"); startActivity(intent); finish(); } public void check(){ //当所用app前版本号 String codeversin=getVersion(); String s="aId=44dd260d8834e5b779b242fe77545681&_api_key=1482c455937aee3ecd2611f901f1759b"; // String sss= Httputils.doPost(checkurl,s); System.out.println("ttt"+sss); try { JSONObject object=new JSONObject(sss); JSONArray array=object.getJSONArray("data"); for(int i=0;i<array.length();i++){ JSONObject object1=array.getJSONObject(i); String appVersion=object1.getString("appVersion"); double x1=Double.valueOf(appVersion); double x2=Double.valueOf(codeversin); if(x1>x2){ download(); } } } catch (JSONException e) { e.printStackTrace(); } // } public void download(){ String target = Environment.getExternalStorageDirectory()+ "/update.apk"; String path="https://www.pgyer.com/apiv1/app/install?aId=44dd260d8834e5b779b242fe77545681&_api_key=1482c455937aee3ecd2611f901f1759b"; HttpUtils utils = new HttpUtils(); utils.download(path, target, new RequestCallBack<File>() { @Override public void onLoading(long total, long current, boolean isUploading) { super.onLoading(total, current, isUploading); System.out.println("current:"+current+"/"+total); } @Override public void onSuccess(ResponseInfo<File> arg0) { System.out.print("****"+arg0.toString()); System.out.println("下载成功"); String path=Environment.getExternalStorageDirectory()+ "/update.apk"; File file=new File(path); installAPK(file); } @Override public void onFailure(HttpException arg0, String arg1) { System.out.print("*1***"+arg0.toString()); System.out.print("**1**"+arg1); System.out.println("下载失败"); } }); } private String getVersion(){ PackageInfo pkg; String versionName=""; try { pkg = getPackageManager().getPackageInfo(getApplication().getPackageName(), 0); String appName = pkg.applicationInfo.loadLabel(getPackageManager()).toString(); versionName = pkg.versionName; System.out.println("appName:" + appName); System.out.println("versionName:" + versionName); } catch (PackageManager.NameNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return versionName; } }
插张图:
<!-------------上面的已经实现检查版本号,更新功能了-------- 看下面的细节------------------------------------>
1.请求利用的:xUtils
2.
POST http://www.pgyer.com/apiv1/app/viewGroup
参数 | 类型 | 说明 |
---|---|---|
aId | String | App Id |
_api_key | String | API Key 点击获取API Key |
请求结果示例:
{
"code": 0,
"message": "",
"data": [
{
"appKey": "4afb80cd8d647540800fc0f94ad0d433",
"appType": "2",
"appIsLastest": "2",
"appFileName": "mypugongying-debug.apk",
"appFileSize": "1319716",
"appName": "MyPuGongYing",
"appVersion": "1.0.4",
"appVersionNo": "1",
"appBuildVersion": "4",
"appIdentifier": "myapplication.com.mypugongying",
"appIcon": "83378890c501827f74e4daade7227c8b",
"appDescription": "",
"appUpdateDescription": "",
"appScreenshots": "",
"appShortcutUrl": "g361",
"appCreated": "2016-10-18 14:00:30",
"appUpdated": "2016-10-18 14:00:30",
"appQRCodeURL": "http://static.pgyer.com/app/qrcodeHistory/9d280728c3c7dffc912921fcf1553ba618338284c4da159b4d098aebbd490f15"
},
{
"appKey": "ec8ee876789755c35d3343dc1e23125d",
"appType": "2",
"appIsLastest": "1",
"appFileName": "mypugongying-debug (2).apk",
"appFileSize": "1319717",
"appName": "MyPuGongYing",
"appVersion": "1.0.5",
"appVersionNo": "1",
"appBuildVersion": "5",
"appIdentifier": "myapplication.com.mypugongying",
"appIcon": "0cf04c160f1254a808679f1a510aa674",
"appDescription": "",
"appUpdateDescription": "",
"appScreenshots": "",
"appShortcutUrl": "g361",
"appCreated": "2016-10-18 14:02:25",
"appUpdated": "2016-10-18 14:02:25",
"appQRCodeURL": "http://static.pgyer.com/app/qrcodeHistory/07c5c9d7a22cc4e8af8a13a1414523a8db84716089ae8ed9f048cea2d3774ea7"
}
]
}
可以找到所有版本的 "appVersion": "1.0.4",,然后在得到当前appverision,判断是不是最新版本。
3.然后下载安装就行了。
4.当然也可以加入摇一摇反馈功能,看图
这个很简单,在需要感应摇一摇的activity中加入下面的代码就行:
1 @Override 2 protected void onResume() { 3 // TODO Auto-generated method stub 4 super.onResume(); 5 6 // 自定义摇一摇的灵敏度,默认为950,数值越小灵敏度越高。 7 PgyFeedbackShakeManager.setShakingThreshold(1000); 8 9 // 以对话框的形式弹出 10 PgyFeedbackShakeManager.register(MainActivity.this); 11 12 // 以Activity的形式打开,这种情况下必须在AndroidManifest.xml配置FeedbackActivity 13 // 打开沉浸式,默认为false 14 // FeedbackActivity.setBarImmersive(true); 15 PgyFeedbackShakeManager.register(MainActivity.this, false); 16 17 } 18 19 @Override 20 protected void onPause() { 21 // TODO Auto-generated method stub 22 super.onPause(); 23 PgyFeedbackShakeManager.unregister(); 24 }
当然摇一摇,有时手机锁屏了还能感应,对此可以改成点击事件,弹出反馈界面:
如下,加一行代码就行:
1 textView.setOnClickListener(new View.OnClickListener() { 2 @Override 3 public void onClick(View v) { 4 PgyFeedback.getInstance().showDialog(AboutMe_Activity.this); 5 6 // 以Activity的形式打开,这种情况下必须在AndroidManifest.xml配置FeedbackActivity 7 // 打开沉浸式,默认为false 8 // FeedbackActivity.setBarImmersive(true); 9 // PgyFeedback.getInstance().showActivity(AboutMe_Activity.this); 10 11 } 12 });
<!-- 结束了,就这么多。上面的调用接口实现的检查更新下载,蒲公英毕竟也是没怎么-用过。完整的代码:http://pan.baidu.com/s/1jIsc5Hs-->
<!-- 下面调用蒲公英sdk方法自动检查版本更新下载-->
1.步骤和上面一样,就是在activity里面加入这些加粗部分代码,实现自动更新即可。
1 package myapplication.com.mypugongying; 2 3 import android.content.DialogInterface; 4 import android.content.Intent; 5 import android.content.pm.PackageInfo; 6 import android.content.pm.PackageManager; 7 import android.net.Uri; 8 import android.os.Environment; 9 import android.support.v7.app.AlertDialog; 10 import android.support.v7.app.AppCompatActivity; 11 import android.os.Bundle; 12 13 import com.lidroid.xutils.HttpUtils; 14 import com.lidroid.xutils.exception.HttpException; 15 import com.lidroid.xutils.http.ResponseInfo; 16 import com.lidroid.xutils.http.callback.RequestCallBack; 17 import com.pgyersdk.activity.FeedbackActivity; 18 import com.pgyersdk.crash.PgyCrashManager; 19 import com.pgyersdk.feedback.PgyFeedbackShakeManager; 20 import com.pgyersdk.javabean.AppBean; 21 import com.pgyersdk.update.PgyUpdateManager; 22 import com.pgyersdk.update.UpdateManagerListener; 23 24 import org.json.JSONArray; 25 import org.json.JSONException; 26 import org.json.JSONObject; 27 28 import java.io.File; 29 30 public class MainActivity extends AppCompatActivity { 31 32 String checkurl="http://www.pgyer.com/apiv1/app/viewGroup"; 33 @Override 34 protected void onCreate(Bundle savedInstanceState) { 35 super.onCreate(savedInstanceState); 36 setContentView(R.layout.activity_main); 37 38 String codeversin=getVersion(); 39 40 PgyUpdateManager.register(this); 41 FeedbackActivity.setBarImmersive(true); 42 43 PgyCrashManager.register(this); 44 45 // new Thread(new Runnable() { 46 // @Override 47 // public void run() { 48 // check(); 49 // } 50 // }).start(); 51 52 53 54 PgyUpdateManager.register(MainActivity.this,new UpdateManagerListener() { 55 56 @Override 57 public void onUpdateAvailable(final String result) { 58 59 // 将新版本信息封装到AppBean中 60 final AppBean appBean = getAppBeanFromString(result); 61 new AlertDialog.Builder(MainActivity.this) 62 .setTitle("更新") 63 .setMessage("") 64 .setNegativeButton("确定", new DialogInterface.OnClickListener() { 65 @Override 66 public void onClick(DialogInterface dialog, int which) { 67 startDownloadTask(MainActivity.this, appBean.getDownloadURL()); 68 } 69 }).show(); 70 } 71 72 @Override 73 public void onNoUpdateAvailable() { 74 } 75 }); 76 } 77 78 79 80 private void installAPK(File savedFile) { 81 //调用系统的安装方法 82 Intent intent=new Intent(); 83 intent.setAction(intent.ACTION_VIEW); 84 intent.setDataAndType(Uri.fromFile(savedFile), "application/vnd.android.package-archive"); 85 startActivity(intent); 86 finish(); 87 } 88 89 90 public void check(){ 91 //当所用app前版本号 92 String codeversin=getVersion(); 93 94 String s="aId=44dd260d8834e5b779b242fe77545681&_api_key=1482c455937aee3ecd2611f901f1759b"; 95 // 96 String sss= Httputils.doPost(checkurl,s); 97 System.out.println("ttt"+sss); 98 try { 99 JSONObject object=new JSONObject(sss); 100 JSONArray array=object.getJSONArray("data"); 101 for(int i=0;i<array.length();i++){ 102 JSONObject object1=array.getJSONObject(i); 103 String appVersion=object1.getString("appVersion"); 104 double x1=Double.valueOf(appVersion); 105 double x2=Double.valueOf(codeversin); 106 if(x1>x2){ 107 download(); 108 109 } 110 } 111 112 } catch (JSONException e) { 113 e.printStackTrace(); 114 } 115 116 // 117 } 118 119 public void download(){ 120 String target = Environment.getExternalStorageDirectory()+ "/update.apk"; 121 String path="https://www.pgyer.com/apiv1/app/install?aId=44dd260d8834e5b779b242fe77545681&_api_key=1482c455937aee3ecd2611f901f1759b"; 122 123 HttpUtils utils = new HttpUtils(); 124 utils.download(path, target, new RequestCallBack<File>() { 125 @Override 126 public void onLoading(long total, long current, boolean isUploading) { 127 super.onLoading(total, current, isUploading); 128 System.out.println("current:"+current+"/"+total); 129 } 130 @Override 131 public void onSuccess(ResponseInfo<File> arg0) { 132 System.out.print("****"+arg0.toString()); 133 System.out.println("下载成功"); 134 String path=Environment.getExternalStorageDirectory()+ "/update.apk"; 135 File file=new File(path); 136 installAPK(file); 137 } 138 139 @Override 140 public void onFailure(HttpException arg0, String arg1) { 141 System.out.print("*1***"+arg0.toString()); 142 System.out.print("**1**"+arg1); 143 144 145 System.out.println("下载失败"); 146 } 147 }); 148 149 } 150 151 152 private String getVersion(){ 153 PackageInfo pkg; 154 String versionName=""; 155 try { 156 pkg = getPackageManager().getPackageInfo(getApplication().getPackageName(), 0); 157 String appName = pkg.applicationInfo.loadLabel(getPackageManager()).toString(); 158 versionName = pkg.versionName; 159 System.out.println("appName:" + appName); 160 System.out.println("versionName:" + versionName); 161 162 } catch (PackageManager.NameNotFoundException e) { 163 // TODO Auto-generated catch block 164 e.printStackTrace(); 165 } 166 return versionName; 167 } 168 169 170 171 @Override 172 protected void onResume() { 173 // TODO Auto-generated method stub 174 super.onResume(); 175 176 // 自定义摇一摇的灵敏度,默认为950,数值越小灵敏度越高。 177 PgyFeedbackShakeManager.setShakingThreshold(1000); 178 179 // 以对话框的形式弹出 180 PgyFeedbackShakeManager.register(MainActivity.this); 181 182 // 以Activity的形式打开,这种情况下必须在AndroidManifest.xml配置FeedbackActivity 183 // 打开沉浸式,默认为false 184 // FeedbackActivity.setBarImmersive(true); 185 PgyFeedbackShakeManager.register(MainActivity.this, false); 186 187 } 188 189 @Override 190 protected void onPause() { 191 // TODO Auto-generated method stub 192 super.onPause(); 193 PgyFeedbackShakeManager.unregister(); 194 } 195 196 197 198 }