package core.common.upgrade.upgradeAndroid; import android.app.AlertDialog; import android.app.DownloadManager; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.util.Log; import android.widget.Toast; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.JsonObjectRequest; import com.android.volley.toolbox.Volley; import org.json.JSONException; import org.json.JSONObject; import java.io.File; import core.common.Shell; import core.common.Version; import core.common.DownloadManagerUtil; import core.common.tuple.Tuple; import core.common.tuple.Tuple3; import core.common.upgrade.UpgradeBean; /** * Created by jone_admin on 13-12-11. * 1.UpgradeAndroid.runUpgrade(context, upgradeBean, upgradeListener) * 2.register UpgradeBroadcastReceiver in AndroidManifest.xml //安装完自动打开的广播(可选) * 3.<uses-permission android:name="android.permission.INSTALL_PACKAGES" />...//一些权限, todo */ public class UpgradeAndroid { private static String TAG = UpgradeAndroid.class.getSimpleName(); private static boolean verifyUpgradeBean(UpgradeBean upgradeBean){ if(upgradeBean != null && upgradeBean.getFormUrl() != null){return true;} else {return false;} } public static void runUpgrade(final Context context,final UpgradeBean upgradeBean, final UpgradeListener upgradeListener){ if(verifyUpgradeBean(upgradeBean)){ Log.d("UpgradeAndroid", "upgrade running..."); Toast.makeText(context, "正在检查更新...", Toast.LENGTH_LONG).show(); RequestQueue mQueue = Volley.newRequestQueue(context); mQueue.add(new JsonObjectRequest(Request.Method.GET, upgradeBean.getFormUrl(), null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { try { int code = response.getInt("code"); String version = response.getString("version"); final String apkUrl = response.getString("address"); Log.d(TAG, "code: " + code + ", currentCode: " + Version.getVerCode(context) + ", apkUrl: " + apkUrl); if(code > Version.getVerCode(context)){ if(upgradeBean.isManualUpgrade()){ new AlertDialog.Builder(context) .setTitle("升级") .setMessage("新版本: v" + version + ", 是否更新?") .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) {}}) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) {upgradeListener.onUpgrade(upgrade(context, upgradeBean, apkUrl));} }).create().show(); }else { upgradeListener.onUpgrade(upgrade(context, upgradeBean, apkUrl)); } }else { upgradeListener.onUpgrade(Tuple.tuple(false, 0l, "已经是最新版本.")); } } catch (JSONException e) { upgradeListener.onUpgrade(Tuple.tuple(false, -1l, "Json解析错误" + e.getMessage())); } } }, new Response.ErrorListener(){ @Override public void onErrorResponse(VolleyError error) { upgradeListener.onUpgrade(Tuple.tuple(false, -1l, "连接服务器失败,请检查网络是否连接")); } })); mQueue.start(); }else { Log.e(TAG, "upgradeBean传递有误"); } } private static Tuple3<Boolean, Long, String> upgrade(final Context context, UpgradeBean upgradeBean, String apkUrl){ long downloadId = DownloadManagerUtil.download(context, apkUrl, upgradeBean.getDownloadSavePath(), upgradeBean.getDownloadSaveFileName(), new DownloadManagerUtil.DownloadCompleteListener() { @Override public void onComplete(DownloadManager downloadManager, long completeDownloadId) { DownloadManager.Query myDownloadQuery = new DownloadManager.Query(); myDownloadQuery.setFilterById(completeDownloadId); Cursor myDownload = downloadManager.query(myDownloadQuery); if (myDownload.moveToFirst()) { int fileNameIdx = myDownload.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME); int fileUriIdx =myDownload.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI); String fileName = myDownload.getString(fileNameIdx); String fileUri = myDownload.getString(fileUriIdx); Log.d("CompleteReceiver", fileName + " : " + fileUri); if(UpgradeAndroid.installSilent(fileName) != 0){ Log.e("CompleteReceiver", "静默升级失败,采用显式升级"); UpgradeAndroid.installApk(context, fileName); } } myDownload.close(); } }); return Tuple.tuple(true, downloadId, "apk下载中..."); } public static void installApk(Context c, String filePath){ Uri uri = Uri.fromFile(new File(filePath)); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(uri,"application/vnd.android.package-archive"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); c.startActivity(intent); } public static void uninstallAPK(Context c, String packageName) { Uri packageURI = Uri.parse("package:" + packageName); Intent intent = new Intent(Intent.ACTION_DELETE); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setData(packageURI); c.startActivity(intent); } /** * install silent * @param filePath * @return 0 means normal, 1 means file not exist, 2 means other exception error */ public static int installSilent(String filePath) { int result; File file = new File(filePath); if (filePath == null || filePath.length() == 0 || (file = new File(filePath)) == null || file.length() <= 0 || !file.exists() || !file.isFile()) { return 1; } Tuple3<Integer, String, String> resultTuple = Shell.runCommandAndReturn("pm install -r " + filePath); result = verifyResultTuple(Shell.runCommandAndReturn("pm install -r " + filePath)); if(result == 2){ result = verifyResultTuple(Shell.runRootCommandAndReturn("pm install -r " + filePath)); } Log.d(TAG, resultTuple.toString()); return result; } private static Integer verifyResultTuple(Tuple3<Integer, String, String> resultTuple){ if (resultTuple.v2.contains("Success") || resultTuple.v2.contains("success")) { return 0; } else { return 2; } } public interface UpgradeListener { void onUpgrade(Tuple3<Boolean, Long, String> result); } }