批处理如何 批量结束 TXT文件改名批处理里的多个进程

开发一款原生移动App需要多长时间?
近年来移动应用的数量正在以几何级数增长,2013年底,两大移动应用平台——Android的Google Play应用市场和苹果的iOS应用商店的应用数量都将突破百万大关。数以万计的移动开发者正夜以继日地开发游戏、社交、新闻、办公、时尚等各种移动应用。
随着移动应用开发门槛的降低,如今越来越多的企业甚至个人已经或者正在筹划开发自己的移动应用,有一个重要问题的答案所有人都想知道,那就是开发一款原生移动App(不包括移动web站点和HTML5 web app)到底需要多少时间?波士顿的移动云开发平台提供商最近调查了100位原生移动开发者后制作了一张信息图,直观地解答了这个问题。
最少需要18周(4个半月)?!
Kinvey的调查显示,开发一款界面美观功能完备的原生移动App需要一个开发团队平均忙活18周(4个半月)。开发工作包括前端设计、用户界面以及后端的集成,如消息推送、用户认证与管理、数据缓存以及社交渠道分享等。
对于原生App开发周期为18周的说法,不同的开发者有着不同的判断。很多app开发者嗤之以鼻,认为是“龟速”;但企业应用开发者则认为18周时间太短,连一半都完成不了。
2012年9月至2013年1月期间,苹果应用商店平均每天上架641个新应用,其中精品应用只是少数,也更花时间。实际上不同的原生App的开发周期确实存在很大差异,应用的复杂度不同,品质不同,开发速度也存在很大差异。又快又好的App开发不是没有,不过大多属于通过反向工程抄袭,例如业界传闻Facebook工程师只花费了几天时间就“开发”出了Snapchat的克隆产品——Poke。
ioS游戏开发工作室“The Tap Lab”的首席执行官Dave Bisceglia总结道:
“一个不太让人兴奋的答案是,App开发周期并无定论,需视情况而定。我见过天才团队只需数周就能开发出一款高质量应用。但是随着对高质量应用的要求不断增长,App开发的周期也在不断拉长,如今一些复杂项目的周期会长达6-12个月。”
Android和iOS应用开发周期哪个长?
这是企业和开发者关心的另外一个问题,同一款应用的Android版和iOS版哪个开发周期更长?
这个问题的答案似乎显而易见:Android应用开发更费时间。因为Android生态存在严重的碎片化问题 (),Android应用开发者需要面对五花八门的手机机型和屏幕分辨率。
但随着情况的变化,我们需要重新评估这个问题。
近来,Android应用开发效率正在不断提升,2012年Google下大力气更新并优化Android软件开发工具包(SDK),帮开发者更好地处理屏幕尺寸,象素密度以及操作系统版本问题。此外,Android4.0(冰激凌三明治)和4.1(果冻豆)版本系统在应用开发流程上也都得到了改进。
总的来说Android应用与iOS应用开发周期的差异正在缩小,Kinvey市场副总裁Joe Chernov认为:
如果开发者技术水平相当的话,开发Android应用和iOS应用需要的时间应该差不多相同。不久以前,Android应用开发更费时,因为Android设备的碎片化问题,但是随着Google大幅提升SDK开发工具包这个问题得到了很好的解决。如今Android开发者通过设计工具可以很直观地看到应用在不同设备上的用户界面效果。
虽然应用开发耗时相同,但两大应用市场的审核时间却大不相同,Google Play只需要数小时(甚至还有自助服务选项可以免去审核),而苹果的审核则需要数周甚至数月。来电显示应用Privus Mobile的开发者Martino曾说:
在苹果应用商店,开发一个更新需要三个月,通过苹果审核又要一个月,而且还不一定能通过。你在苹果应用商店更新一次的时间,在Android市场都够发布第三个版本的应用了。
以下是Kinvey用生成的调查信息图(点击查看大图),Kinvey将移动开发分解成12个阶段,受调查的开发者对每个阶段的用时给出自己的估计值,18周是每个阶段的平均用时的累计数值:
第一时间获取面向IT决策者的独家深度资讯,敬请关注IT经理网微信号:ctociocom
&&&除非注明,本站文章均为原创或编译,转载请务必注明出处并保留: 文章来自
相关文章:
IT到底是重要呢还是重要呢还是重要呢
本白皮书从硬件基础设施、服务部署、用户身份、存储服务、网络通讯和运营安全五个层面为我们系统介绍了Google基础设施的安全设计架构和方法
两款联网智能玩具充斥着大量安全漏洞,而且存在用户条款非法条文、共享儿童隐私、询问敏感问题以及诱导儿童聆听隐藏广告等等问题。
Netwrix最新发布的云安全报告显示,越来越多的企业开始担心云安全问题。
《2016互联网有组织犯罪威胁评估报告》预警了八大网络犯罪趋势
报告详细分析了FitBit智能手环的硬件、网络、APP、云服务四个攻击面的安全性和隐私保护问题,风风火火搞智能硬件的务必要抽空看下。
针对不同类型的设备和使用场景,教育机构如何能够确保学生安全进入Wi-Fi网络并获得最佳质量的连接呢?
瑞萨电子宣布推出高度自动驾驶(HAD)解决方案套件。这款套件可针对汽车功能安全提供高运算性能,以缩短电子控制单元(ECU)的开发时间。
经过对中国防雷业务 审核为期9个月的学习和研究,世界十大开源ERP开发商之一,法国开源软件企业Nexedi 开发了首个开源防雷业务电子政务管理平台。
Cray的这套系统将成为瑞典和斯堪地纳维亚地区首台千万亿次规模的超级计算机。瑞典研究人员和产业合作伙伴因此可以在气候模拟、流体动力学、神经科学、等离子物理、材料科学和分子模拟等领域进行复杂的模拟。
&Copyright (C) 2011,ctocio.cc - IT经理网02-0902-09
02-0902-09
02-0902-09
@ 适新素材网
@ 版权所有声明:论坛言论仅代表网友个人观点,不代表超级大本营军事网站立场
Powered by Discuz &
超级大本营军事网站
(违法及不良信息举报电话:)
最具影响力中文军事论坛 - Most Influential Chinese Military Forum安卓开发实战之app之版本更新升级(DownloadManager和http下载)完整实现
安卓开发实战之app之版本更新升级(DownloadManager和http下载)完整实现
来源:极客头条
本文将讲解app的升级与更新。一般而言用户使用App的时候升级提醒有两种方式获得:
一种是通过应用市场 获取
一种是打开应用之后提醒用户更新升级
而更新操作一般是在用户点击了升级按钮之后开始执行的,这里的升级操作也分为两种形式:
app升级操作:
在App Store中升级需要为App Store上传新版App,我们在新版本完成之后都会上传到App Store中,在审核完成之后就相当于完成了这个应用市场的发布了,也就是发布上线了。这时候如果用户安装了这个应用市场,那么就能看到我们的App有新版本的升级提醒了。
除了可以在应用市场升级,我们还可以在应用内升级,在应用内升级主要是通过调用服务器端接口获取应用的升级信息,然后通过获取的服务器升级应用信息与本地的App版本比对,若服务器下发的最新的App版本高于本地的版本号,则说明有新版本发布,那么我们就可以执行更新操作了,否则忽略掉即可。
显然应用市场提醒的升级不是我们的重点,本篇主要是对于app升级的场景来进行不同角度的实现,便于以后开发过程中直接拿去用就ok了。
服务器端:
服务端提供一个接口,或者网址,这里提供一个网址如下:
一般作为一个安卓程序员要测试还得写一个服务端(醉了),这里我就使用nodejs来搞一个本地的服务器来测试下app的版本更新检验。
然后我电脑上是装了webstrom的,没有装也没有关系但是必须有nodejs,现在都自带了express,表示并没有学过,所以简单的写个express_demo.js:
var express = require('express');
var app = express();
var fs = require();
app.get('/update', function (req, res) {
fs.readFile( __dirname +
+ , 'utf8', function (err, data) {
console.log( data );
res.end( data );
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log(, host, port)
有webstrom的直接选中文件run就ok了,没有直接
node express_demo.js,可以直接浏览器打开:
上图为打开浏览器后的显示结果。
上图为webstrom的终端显示结果。
客户端需要实现:
我们知道不同的需求有不同的操作方法和界面显示:
从是否为app内部下载还是通知栏更新:
这时我们必须等下载安装完全后才能进行操作,效果是这样的:
这种情况是不在应用内更新,放在通知栏并不会影响当前app的使用,效果是这样的:
app更新分3种:强制更新,推荐更新,无需更新
具体思路:
实现bean用于对接后端接口实现app的更新(不写网络请求模拟本地数据也需要这个模型)
使用retrofit来请求版本更新接口
下载apk我们分别使用DownloadManager和普通的httpurlconnection
通过BroadcastReceiver来监听是否下载完成
首先我们要去解析服务端给的json,那么我们就要来创建一个bean类了,这里是严格根据json文件的格式来的:
package com.losileeya.appupdate.
* User: Losileeya ()
* Time: 11:20
* 类描述:版本更新的实体与你服务器的字段相匹配
* @version :
public class UpdateAppInfo
public UpdateI
public Integer error_
public String error_
public static class UpdateInfo{
public String serverV
public String serverF
public String lastF
网络接口的实现
这里使用retrofit和rxjava来练笔
先加入 依赖
compile 'io.reactivex:rxandroid:1.1.0'
compile 'io.reactivex:rxjava:1.1.0'
compile 'com.squareup.retrofit:retrofit:2.0.0-beta2'
compile 'com.squareup.retrofit:adapter-rxjava:2.0.0-beta2'
compile 'com.squareup.retrofit:converter-gson:2.0.0-beta2'
接下来网络接口的定制:
public interface ApiService {
Observable getUpdateInfo(@Query() String
appname, @Query() String appVersion);
Observable getUpdateInfo();
通过工厂模式来创建ApiService :
public class ServiceFactory {
private static final String BASEURL=;
public static
T createServiceFrom(final Class serviceClass) {
Retrofit adapter = new Retrofit.Builder()
.baseUrl(BASEURL)
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
return adapter.create(serviceClass);
版本检测接口的使用:
* 检查更新
@SuppressWarnings()
public static void checkUpdate(String appCode, String curVersion,final CheckCallBack updateCallback) {
ApiService apiService=
ServiceFactory.createServiceFrom(ApiService.class);
apiService.getUpdateInfo()
.subscribeOn(Schedulers.newThread())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber() {
public void onCompleted() {
public void onError(Throwable e) {
public void onNext(UpdateAppInfo updateAppInfo) {
if (updateAppInfo.error_code == 0 || updateAppInfo.data == null ||
updateAppInfo.data.updateurl == null) {
updateCallback.onError();
updateCallback.onSuccess(updateAppInfo);
以上就是版本更新接口的调用,具体的rxjava+retrofit请自行学习
附上结果回调监听:
public interface CheckCallBack{
void onSuccess(UpdateAppInfo updateInfo);
void onError();
具体使用接口的处理:
CheckUpdateUtils.checkUpdate(, , new CheckUpdateUtils.CheckCallBack() {
public void onSuccess(UpdateAppInfo updateInfo) {
String isForce=updateInfo.data.getLastForce();
String downUrl= updateInfo.data.getUpdateurl();
String updateinfo = updateInfo.data.getUpgradeinfo();
String appName = updateInfo.data.getAppname();
if(isForce.equals()&& !TextUtils.isEmpty(updateinfo)){
forceUpdate(MainActivity.this,appName,downUrl,updateinfo);
normalUpdate(MainActivity.this,appName,downUrl,updateinfo);
public void onError() {
noneUpdate(MainActivity.this);
实在不想写网络也好,直接使用假想数据做相关操作如下:
UpdateAppInfo.UpdateInfo
info =new UpdateAppInfo.UpdateInfo();
info.setLastForce();
info.setAppname();
info.setUpgradeinfo();
info.setUpdateurl();
if(info.getLastForce().equals()){
更新dialog的使用注意:
private void forceUpdate(final Context context, final String appName, final String downUrl, final String updateinfo) {
mDialog = new AlertDialog.Builder(context);
mDialog.setTitle(appName+);
mDialog.setMessage(updateinfo);
mDialog.setPositiveButton(, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (!canDownloadState()) {
showDownloadSetting();
AppInnerDownLoder.downLoadApk(MainActivity.this,downUrl,appName);
}).setCancelable(false).create().show();
上面以强制更新举个例子,因为AlertDialog在不同的版本下面表现的美观度不一致,所以我们需要
import android.support.v7.app.AlertD
然后显然是不能按返回键取消的,我们需要
.setCancelable(false)
使用谷歌推荐的DownloadManager实现下载
Android自带的DownloadManager模块来下载,在api level 9之后,我们通过通知栏知道, 该模块属于系统自带, 它已经帮我们处理了下载失败、重新下载等功能。整个下载 过程全部交给系统负责,不需要我们过多的处理。
DownLoadManager.Query:主要用于查询下载信息。
DownLoadManager.Request:主要用于发起一个下载请求。
先看下简单的实现:
创建Request对象的代码如下:
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(apkurl));
request.setAllowedNetworkTypes(Request.NETWORK_WIFI);
request.setNotificationVisibility(Request.VISIBILITY_VISIBLE);
request.setTitle();
request.setDescription();
request.setAllowedOverRoaming(false);
request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, );
取得系统服务后,调用downloadmanager对象的enqueue方法进行下载,此方法返回一个编号用于标示此下载任务:
downManager = (DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
id= downManager.enqueue(request);
这里我们可以看下request的一些属性:
addRequestHeader(String header,String value):添加网络下载请求的http头信息
allowScanningByMediaScanner():用于设置是否允许本MediaScanner扫描。
setAllowedNetworkTypes(int flags):设置用于下载时的网络类型,默认任何网络都可以下载,提供的网络常量有:NETWORK_BLUETOOTH、NETWORK_MOBILE、NETWORK_WIFI。
setAllowedOverRoaming(Boolean allowed):用于设置漫游状态下是否可以下载
setNotificationVisibility(int visibility):用于设置下载时时候在状态栏显示通知信息
setTitle(CharSequence):设置Notification的title信息
setDescription(CharSequence):设置Notification的message信息
setDestinationInExternalFilesDir、setDestinationInExternalPublicDir、 setDestinationUri等方法用于设置下载文件的存放路径,注意如果将下载文件存放在默认路径,那么在空间不足的情况下系统会将文件删除,所 以使用上述方法设置文件存放目录是十分必要的。
具体实现思路:
我们通过downloaderManager来下载apk,并且本地保存downManager.enqueue(request)返回的id值,并且通过这个id获取apk的下载文件路径和下载的状态,并且通过状态来更新通知栏的显示。
第一次下载成功,弹出安装界面
如果用户没有点击安装,而是按了返回键,在某个时候,又再次使用了我们的APP
如果下载成功,则判断本地的apk的包名是否和当前程序是相同的,并且本地apk的版本号大于当前程序的版本,如果都满足则直接启动安装程序。
具体代码实现:
文件下载管理的实现,包括创建request和加入队列下载,通过返回的id来获取下载路径和下载状态。
public class FileDownloadManager {
private DownloadManager downloadM
private static FileDownloadM
private FileDownloadManager(Context context) {
downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
this.context = context.getApplicationContext();
public static FileDownloadManager getInstance(Context context) {
if (instance == null) {
instance = new FileDownloadManager(context);
* @param uri
* @param title
* @param description
* @return download id
public long startDownload(String uri, String title, String description,String appName) {
DownloadManager.Request req = new DownloadManager.Request(Uri.parse(uri));
req.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
req.setDestinationInExternalFilesDir(context, Environment.DIRECTORY_DOWNLOADS, appName+);
req.setTitle(title);
req.setDescription(description);
return downloadManager.enqueue(req);
* 获取文件保存的路径
* @param downloadId an ID for the download, unique across the system.
This ID is used to make future calls related to this download.
* @return file path
* @see FileDownloadManager#getDownloadUri(long)
public String getDownloadPath(long downloadId) {
DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
Cursor c = downloadManager.query(query);
if (c != null) {
if (c.moveToFirst()) {
return c.getString(c.getColumnIndexOrThrow(DownloadManager.COLUMN_LOCAL_URI));
} finally {
c.close();
* 获取保存文件的地址
* @param downloadId an ID for the download, unique across the system.
This ID is used to make future calls related to this download.
* @see FileDownloadManager#getDownloadPath(long)
public Uri getDownloadUri(long downloadId) {
return downloadManager.getUriForDownloadedFile(downloadId);
public DownloadManager getDownloadManager() {
return downloadM
* 获取下载状态
* @param downloadId an ID for the download, unique across the system.
This ID is used to make future calls related to this download.
* @return int
* @see DownloadManager#STATUS_PENDING
* @see DownloadManager#STATUS_PAUSED
* @see DownloadManager#STATUS_RUNNING
* @see DownloadManager#STATUS_SUCCESSFUL
* @see DownloadManager#STATUS_FAILED
public int getDownloadStatus(long downloadId) {
DownloadManager.Query query = new DownloadManager.Query().setFilterById(downloadId);
Cursor c = downloadManager.query(query);
if (c != null) {
if (c.moveToFirst()) {
return c.getInt(c.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS));
} finally {
c.close();
return -1;
app的检测安装的实现:
public class DownLoadApk {
public static final String TAG = DownLoadApk.class.getSimpleName();
public static void download(Context context, String url, String title,final String appName) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
long downloadId =sp.getLong(DownloadManager.EXTRA_DOWNLOAD_ID,-1L);
if (downloadId != -1L) {
FileDownloadManager fdm = FileDownloadManager.getInstance(context);
int status = fdm.getDownloadStatus(downloadId);
if (status == DownloadManager.STATUS_SUCCESSFUL) {
Uri uri = fdm.getDownloadUri(downloadId);
if (uri != null) {
if (compare(getApkInfo(context, uri.getPath()), context)) {
startInstall(context, uri);
fdm.getDownloadManager().remove(downloadId);
start(context, url, title,appName);
} else if (status == DownloadManager.STATUS_FAILED) {
start(context, url, title,appName);
Log.d(TAG, );
start(context, url, title,appName);
private static void start(Context context, String url, String title,String appName) {
long id = FileDownloadManager.getInstance(context).startDownload(url,
title, ,appName);
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
sp.edit().putLong(DownloadManager.EXTRA_DOWNLOAD_ID,id).commit();
Log.d(TAG,
public static void startInstall(Context context, Uri uri) {
Intent install = new Intent(Intent.ACTION_VIEW);
install.setDataAndType(uri, );
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(install);
* 获取apk程序信息[packageName,versionName...]
* @param context Context
* @param path
private static PackageInfo getApkInfo(Context context, String path) {
PackageManager pm = context.getPackageManager();
PackageInfo info = pm.getPackageArchiveInfo(path, PackageManager.GET_ACTIVITIES);
if (info != null) {
* 下载的apk和当前程序版本比较
* @param apkInfo apk file's packageInfo
* @param context Context
* @return 如果当前应用版本小于apk的版本则返回true
private static boolean compare(PackageInfo apkInfo, Context context) {
if (apkInfo == null) {
String localPackage = context.getPackageName();
if (apkInfo.packageName.equals(localPackage)) {
PackageInfo packageInfo = context.getPackageManager().getPackageInfo(localPackage, 0);
if (apkInfo.versionCode > packageInfo.versionCode) {
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
上面的代码可知:我们通过获取当前app的信息来比较是否需要下载和是否立即安装。第一次下载把downloadId保存到本地,用户下次进来的时候,取出保存的downloadId,然后通过downloadId来获取下载的状态信息。如果下载失败,则重新下载并且把downloadId存起来。如果下载成功,则判断本地的apk的包名是否和当前程序是相同的,并且本地apk的版本号大于当前程序的版本,如果都满足则直接启动安装程序。
监听app是否安装完成
public class ApkInstallReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)){
long downloadApkId =intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
installApk(context, downloadApkId);
private void installApk(Context context,long downloadApkId) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
long downId =sp.getLong(DownloadManager.EXTRA_DOWNLOAD_ID,-1L);
if(downloadApkId == downId){
DownloadManager downManager= (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadFileUri = downManager.getUriForDownloadedFile(downloadApkId);
if (downloadFileUri != null) {
Intent install= new Intent(Intent.ACTION_VIEW);
install.setDataAndType(downloadFileUri, );
install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(install);
Toast.makeText(context, , Toast.LENGTH_SHORT).show();
DownloadManager下载完成后会发出一个广播 android.intent.action.DOWNLOAD_COMPLETE 新建一个广播接收者即可:
清单配置:
先添加网络下载的权限:
再添加静态广播:
使用HttpUrlConnection下载
这种情况下载的话我们就不需要考虑id的问题,因为是直接在项目中下载,所以我们就是一个网络下载的过程,并且使用ProgressDialog显示下载信息及进度更新就ok了。
public class AppInnerDownLoder {
public final static String SD_FOLDER = Environment.getExternalStorageDirectory()+ ;
private static final String TAG = AppInnerDownLoder.class.getSimpleName();
* 从服务器中下载APK
@SuppressWarnings()
public static void downLoadApk(final Context mContext,final String downURL,final String appName ) {
final ProgressD
pd = new ProgressDialog(mContext);
pd.setCancelable(false);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage();
pd.setTitle();
pd.show();
new Thread() {
public void run() {
File file = downloadFile(downURL,appName, pd);
sleep(3000);
installApk(mContext, file);
pd.dismiss();
} catch (Exception e) {
pd.dismiss();
}.start();
* 从服务器下载最新更新文件
* @param path
* @param pd
* @throws Exception
private static File downloadFile(String path,String appName ,ProgressDialog pd) throws Exception {
if (Environment.MEDIA_MOUNTED.equals(Environment
.getExternalStorageState())) {
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5000);
pd.setMax(conn.getContentLength());
InputStream is = conn.getInputStream();
String fileName = SD_FOLDER
+ appName+;
File file = new File(fileName);
if (!file.getParentFile().exists())
file.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(file);
BufferedInputStream bis = new BufferedInputStream(is);
byte[] buffer = new byte[1024];
int total = 0;
while ((len = bis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
pd.setProgress(total);
fos.close();
bis.close();
is.close();
throw new IOException();
private static void installApk(Context mContext, File file) {
Uri fileUri = Uri.fromFile(file);
Intent it = new Intent();
it.setAction(Intent.ACTION_VIEW);
it.setDataAndType(fileUri, );
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(it);
* 获取应用程序版本(versionName)
* @return 当前应用的版本号
private static double getLocalVersion(Context context) {
PackageManager manager = context.getPackageManager();
PackageInfo info =
info = manager.getPackageInfo(context.getPackageName(), 0);
} catch (NameNotFoundException e) {
Log.e(TAG,
+ e.getMessage());
return 0.0;
return Double.valueOf(info.versionName);
* byte(字节)根据长度转成kb(千字节)和mb(兆字节)
* @param bytes
public static String bytes2kb(long bytes) {
BigDecimal filesize = new BigDecimal(bytes);
BigDecimal megabyte = new BigDecimal(1024 * 1024);
float returnValue = filesize.divide(megabyte, 2, BigDecimal.ROUND_UP)
.floatValue();
if (returnValue > 1)
return (returnValue + );
BigDecimal kilobyte = new BigDecimal(1024);
returnValue = filesize.divide(kilobyte, 2, BigDecimal.ROUND_UP)
.floatValue();
return (returnValue + );
基本上具体的代码就写完了,但是说如果停止了下载管理程序 调用dm.enqueue(req);就会上面的错误,从而程序闪退.
所以在使用该组件的时候,需要判断该组件是否可用:
private boolean canDownloadState() {
int state = this.getPackageManager().getApplicationEnabledSetting();
if (state == PONENT_ENABLED_STATE_DISABLED
|| state == PONENT_ENABLED_STATE_DISABLED_USER
|| state == PONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
} catch (Exception e) {
e.printStackTrace();
可以通过如下代码进入 启用/禁用 下载管理 界面:
String packageName = ;
Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse( + packageName));
startActivity(intent);
本文意在讲解app的更新逻辑以及不同的表现形式的处理附带的介绍了使用nodejs写一个简单的api接口,重点是如何使用DownloadManager来实现apk的下载更新安装,顺带讲一下retrofit+rxjava的使用以及如何监听app是否下载完成。
DownloadManager的使用概括:
构建下载请求:
new DownloadManager.Request(url)
设置请求属性
request.setXXX()
调用downloadmanager对象的enqueue方法进行下载,此方法返回一个编号用于标示此下载任务:
downManager = (DownloadManager)getSystemService(Context.DOWNLOAD_SERVICE);
id= downManager.enqueue(request);
DownManager会对所有的现在任务进行保存管理,那么我们如何获取这些信息呢?这个时候就要用到DownManager.Query对象,通过此对象,我们可以查询所有下载任务信息。
setFilterById(long… ids):根据任务编号查询下载任务信息
setFilterByStatus(int flags):根据下载状态查询下载任务
如果想取消下载,则可以调用remove方法完成,此方法可以将下载任务和已经下载的文件同时删除:
downManager.remove(id);
好了具体的都讲的差不多了,本文以同步到我的
demo 传送门:
即使是一小步也想与你分享}

我要回帖

更多关于 批处理批量修改文件名 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信