精华内容
下载资源
问答
  • Firefox浏览器强制取消自动更新

    千次阅读 2019-04-07 21:08:49
    Firefox浏览器,在浏览器的设置中已经设置了取消自动升级,实际退出Firefox浏览器重新启动浏览器后还是会升级到最新版本。影响: Firefox浏览器不同的版本的插件的支持兼容不一样,如果需要使用某款插件,需保证...

    问题: 
    Firefox浏览器,在浏览器的设置中已经设置了取消自动升级,实际退出Firefox浏览器重新启动浏览器后还是会升级到最新版本。 
    影响: 
    Firefox浏览器不同的版本的插件的支持兼容不一样,如果需要使用某款插件,需保证浏览器的版本保持固定。 
    解决: 
    1、浏览器设置,选项–>常规—>更新:设置为不允许检查更新 
    这里写图片描述

    2、如果通过上面步骤的设置,火狐浏览器还会自动升级的话,那么需要找到火狐浏览器的配置文件夹,修改配置文件: 
    Windows7下配置文件路径为:

    \Mozilla Firefox\defaults\pref

    如图: 
    这里写图片描述 
    找到以上路径下的channel-prefs.js文件,打开编辑如下: 
    在文件后面加上以下代码:

    user_pref("app.update.migrated.updateDir", false);
    user_pref("app.update.lastUpdateTime.browser-cleanup-thumbnails", 0);
    user_pref("app.update.lastUpdateTime.datareporting-healthreport-lastDailyCollection", 0);
    user_pref("app.update.disable_button.showUpdateHistory", false);
    user_pref("app.update.service.enabled", false);
    user_pref("browser.search.update", false);
    user_pref("extensions.update.enabled", false);

    如图: 
    这里写图片描述

    代码添加成功后,保存并关闭。 
    这样重新启动Firefox浏览器时便不会再升级了,彻底禁止了火狐浏览器更新升级。

    本文转自 作者 ElenaYu 的 firefox浏览器强制取消自动更新 文章。如需看原版,请点击作者或文章链接!

    展开全文
  • 最新版本的chrome浏览器,不但占用的系统资源越来越大,同时还强迫我们自动升级,而在chrome浏览器中找不到关闭自动更新的方法,怎么样关闭chrome浏览器的自动升级呢?下面我们就一起来看一下关闭chrome浏览器自动...

    https://jingyan.baidu.com/article/0aa223754076f788cc0d6492.html

    最新版本的chrome浏览器,不但占用的系统资源越来越大,同时还强迫我们自动升级,而在chrome浏览器中找不到关闭自动更新的方法,怎么样关闭chrome浏览器的自动升级呢?下面我们就一起来看一下关闭chrome浏览器自动升级的方法吧。

    取消或关闭自动升级 怎么样禁止chrome自动更新

    工具/原料

    • chrome

    方法/步骤

    1. 在Windows7系统桌面,依次点击桌面左下角的“开始/控制面板”菜单项。

      取消或关闭自动升级 怎么样禁止chrome自动更新

    2. 在打开的控制面板窗口中,点击右上角的查看方式下拉按钮,在弹出菜单中选择“大图标”菜单项

      取消或关闭自动升级 怎么样禁止chrome自动更新

    3. 这时可以在窗口中看到所有控制面板项窗口,找到“管理工具”图标,并双击该图标打开管理工具窗口

      取消或关闭自动升级 怎么样禁止chrome自动更新

    4. 在管理工具窗口中,找到服务图标,双击打开Windows7系统的服务窗口

      取消或关闭自动升级 怎么样禁止chrome自动更新

    5. 在打开的服务窗口中,在右侧服务中找到“Google更新服务(Gupdate)"服务 项与“Google更新服务(Gupdatem)”服务项

      取消或关闭自动升级 怎么样禁止chrome自动更新

    6. 双击Google更新服务(Gupdate)项,在打开的窗口中点击启动类型下拉菜单,在弹出菜单中选择“禁用”菜单项,然后点击确定按钮

      取消或关闭自动升级 怎么样禁止chrome自动更新

    7. 双击Google更新服务(Gupdatem)项,在打开的窗口中点击启动类型下拉菜单,在弹出菜单中选择“禁用”菜单项,然后点击确定按钮,重新启动电脑后,chrome浏览器就不再自动升级了

      取消或关闭自动升级 怎么样禁止chrome自动更新

      END

    注意事项

    • 此经验文章中的图文皆由 lqlxhua 独立编撰,并首发于百度经验,如要转载,请留出处。

    • 有帮助,点投票。要细品,可收藏。要继续,请关注。如成功,请点赞。有疑问,请留评。

    展开全文
  • 而且我发现在android8.0中除了一些bug,比如说:在小米6(Android 8.0系统)中无法自动安装的问题,那么之前做的更新系统就要稍微调整下。  那根据android 8.0我们重新理一下更新的思路:  1、写一个接口调用是....

     

           随着android 7.0的普及android 8.0的也逐渐流行起来,那么google对权限方面又有了新的修改。而且我发现在android8.0中除了一些bug,比如说:在小米6(Android 8.0系统)中无法自动安装的问题,那么之前做的更新系统就要稍微调整下。

            那根据android 8.0我们重新理一下更新的思路:

           1、写一个接口调用是否有更新,可以读取版本号后台判断是否有更新,也可拉去最新信息,app内部判断:

           2、创建网络监听,监听网络变化,在application中初始化,

           3、创建更新service,根据service的机制,我们可以创建一个service不销毁,调用startService方法,service无论你创建多少次onCreate方法只会执行一次(当你没有stop的时候),而onStartCommand可以多次调用

           4、调用更新接口,在回调中判断是否需要更新,如果需要更新就创建更新BroadcastReceiver广播,用来通知更新的开始,进度更新,结束,和各种失败的情况,然后创建更新提示dialog(这个不用我说了吧),为了防止更新按钮多次点击和重复下载的问题,我使用了三个全局静态变量来控制

        public static boolean hasNewAppVersion = false;//是否有新版本
        public static boolean isDownLoadApk = false;//apk是否正在下载
        public static boolean isSuccessRequestUpdate = false;//更新请求是否成功了

           5.点击更新弹框的,更新按钮,创建更新下载的service,注意下载需要在子线程中做。同时根据下载的开始,下载进度,或者结束,失败等情况利用广播器进行通知。

           6、下载完成调用安装,这里一定要注意,android O更新了未知来源的权限,需要在配置文件中添加配置

        <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

    那么接下来我们一步一步讲解

    一、接口调用是否有更新,返回数据如下大致如下:

                    

    {
        "status":true,
        "code":200,
        "data":{
            "VersionName":"1.1.8",
            "VersionCode":19,
            "AppUrl":"https://********/appfile/*****.apk",//更新地址
            "Content":"部分BUG修复",//提示内容
            "Status":1,
            "isMustUpdate":true//是否强制更新
        },
        "msg":"返回成功"
    }

    二、网络状态监听

          创建网络状态变化广播器

    /**
     * Created by CherishTang on 2016/12/29.
     * 自定义广播接收器,监听网络状态是否发生改变
     */
    public class NetworkStateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (NetworkStateUtil.isNetWorkConnected(context) && NetworkStateUtil.isWifiConnected(context)) {
                WifiInfo wifiInfo = NetworkStateUtil.getWifiInfo(context);
    //            MThoast.showShort(context, "已连接到"+(wifiInfo.getSSID()==null?"wifi":wifiInfo.getSSID())+"网络");
                processCustomMessage(context, 1);
            } else if (NetworkStateUtil.isNetWorkConnected(context) && NetworkStateUtil.isMobileConnected(context)) {
    //            MThoast.showShort(context, "已连接到数据流量网络");
                processCustomMessage(context, 2);
            } else {
                StaticUtil.isDownLoadApk = false;
                processCustomMessage(context, 3);
    //            MThoast.showShort(context, "已进入无网络次元,请检查网络设置!");
            }
        }
    
        //send msg to MainActivity
        private void processCustomMessage(Context context, Integer message) {
    //        Intent mIntent = new Intent(BaseActivity.ACTION_INTENT_RECEIVER_MESSAGE);
    //        mIntent.putExtra("message", message);
    //        context.sendBroadcast(mIntent);
            if (networkChangeListener != null) {
                networkChangeListener.networkChanger(message);
            }
        }
    
        private NetworkChangeListener networkChangeListener;
    
        public void setNetworkChangeListener(NetworkChangeListener networkChangeListener) {
            this.networkChangeListener = networkChangeListener;
        }
    }

    添加网络状态变化监听权限

    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />

    为了防止重复注册我们再application中注册广播

       
     public final static String ACTION_INTENT_RECEIVER ="android.net.conn.CONNECTIVITY_CHANGE";
     public final static String ACTION_INTENT_RECEIVER_8 = "android.net.wifi.SCAN_RESULTS";
      
        
        /**
         * 注册广播,在onCreate中调用
         */
        private void initNetWorkReceiver() {
            intentFilter = new IntentFilter();
            intentFilter.addAction(ACTION_INTENT_RECEIVER);
            intentFilter.addAction(ACTION_INTENT_RECEIVER_8);
            networkChangeReceiver = new NetworkStateReceiver();
            registerReceiver(networkChangeReceiver, intentFilter);
        }
    
        /**
         * 回收广播
         */
      @Override
        public void onTerminate() {
            super.onTerminate();
            if (networkChangeReceiver != null)
                unregisterReceiver(networkChangeReceiver);
        }
    
        /**
         * 获取NetworkStateReceiver 实例
         */
    
        public NetworkStateReceiver getNetworkChangeReceiver(){
            return networkChangeReceiver;
        }
    

    三、创建更新service

           在你的MainActivity中开启更新service,同时监听网络变化状态,在onStartConmmand中检查给更新

    四、调用接口检查更新

        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
    
            
            checkVersionUpdate();//检查更新网络请求
    
            //获取网络状态变化广播器
            NetworkStateReceiver networkStateReceiver = 
                        MyApplication.getInstance().getNetworkChangeReceiver();
    
            //如果广播器不为空,在添加网络变化监听回调
            if (networkStateReceiver != null)
                        networkStateReceiver.setNetworkChangeListener(this);
            
            return super.onStartCommand(intent, flags, startId);
        }
    
       /**
         * 注册更新BroadcastReceiver
         *
         * @param versionMessage 更新数据
         */
        public void updateCheck(VersionMessage versionMessage) {
            StaticUtil.hasNewAppVersion = true;
    
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(DownloadApkService.ACTION_START);
            intentFilter.addAction(DownloadApkService.ACTION_UPDATE);
            intentFilter.addAction(DownloadApkService.ACTION_FINISHED);
            intentFilter.addAction(DownloadApkService.ACTION_CANCEL);
            intentFilter.addAction(DownloadApkService.ACTION_ERROR);
            intentFilter.addAction(DownloadApkService.ACTION_REDIRECT_ERROR);
    
            downloadApkReceiver = new DownloadApkReceiver();//创建更新下载广播器
            registerReceiver(downloadApkReceiver, intentFilter);
            //获取当前activity
            Activity mContext = AppManager.getAppManager().currentActivity();
    
            //如果程序在前台,并且当前activity没有销毁的话,创建更新弹框, 
            //我封装在UpdateManger方法中了
            if (AppManager.isForeground(this) && mContext != null) {
                UpdateManger.getInstance().checkUpdateInfo(mContext,
                        versionMessage.getAppUrl(), versionMessage.getContent(),
                        versionMessage.getVersionName(), versionMessage.getMustUpdate());
            }
        }

    五、点击更新按钮下载新版app

    首先判断任务是否正在下载,避免重复下载

    if (StaticUtil.isDownLoadApk) {
                MThoast.showShort(mContext, "已存在下载任务,请勿重复下载");
                return;
            }

    检查并动态获取文件的读取权限

    if (ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {
                //申请WRITE_EXTERNAL_STORAGE权限
                ActivityCompat.requestPermissions(mContext, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        0x01);
                return;
            }

    创建更新service并关闭更新提示框

        if (customDialog != null && customDialog.isShowing())
                customDialog.dismiss();
            Intent intent = new Intent(mContext, DownloadApkService.class);
            intent.setAction(DownloadApkService.ACTION_START);
            intent.putExtra("id", 0);
            intent.putExtra("url", apkUrl);
            intent.putExtra("name", "保存到本地的app名称");
            mContext.startService(intent);

    更新下载service代码:

    /**
     * Created by CherishTang on 2017/10/17.
     * 更新app服务
     */
    
    public class DownloadApkService extends Service {
    
        public static final String ACTION_START = "ACTION_START";
        public static final String ACTION_UPDATE = "ACTION_UPDATE";
        public static final String ACTION_FINISHED = "ACTION_FINISHED";
        public static final String ACTION_CANCEL = "ACTION_CANCEL";
        public static final String ACTION_ERROR = "ACTION_ERROR";
        public static final String ACTION_REDIRECT_ERROR = "ACTION_REDIRECT_ERROR";
        public static final String HIDE_DIALOG = "HIDE_DIALOG";
    
        // 文件的保存路径
        public static final String path = Environment.getExternalStorageDirectory().getAbsolutePath() +
                File.separator + StaticUtil.ROOTFILEPATH + File.separator + "download" + File.separator;
    
        @Nullable
        @Override
        public IBinder onBind(Intent intent) {
            return null;
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            if (intent != null) {
                if (ACTION_START.equals(intent.getAction())) {
                    new DownLoadApkThread(intent.getIntExtra("id", 0)
                            , intent.getStringExtra("url"), intent.getStringExtra("name")).start();
                }
            }
            return super.onStartCommand(intent, flags, startId);
        }
    
       
        public class DownLoadApkThread extends Thread {
    
            private int id;
            private String downloadUrl;
            private String fileName;
    
            public DownLoadApkThread(int id, String downloadUrl, String fileName) {
                this.id = id;
                this.downloadUrl = downloadUrl;
                this.fileName = fileName;
    
            }
    
            @Override
            public void run() {
                HttpURLConnection connLength = null;
                HttpURLConnection connFile = null;
                RandomAccessFile randomAccessFile = null;
                InputStream inputStream = null;
                URL url = null;
                try {
                    url = new URL(downloadUrl);
                    //获取apk文件长度
                    connLength = (HttpURLConnection) url.openConnection();
                    connLength.setConnectTimeout(5000);
                    connLength.setRequestMethod("GET");
                    int code = connLength.getResponseCode();
                    int length = 0;
                    if (code == HttpURLConnection.HTTP_OK) {
                        length = connLength.getContentLength();
                    } else if (code == 301) {
                        
                      sendBroadcast(new Intent().setAction(ACTION_REDIRECT_ERROR));
                       return;
                        
                    } else {
                        sendBroadcast(new Intent().setAction(ACTION_ERROR));
                        return;
                    }
    
                    //判断文件是否存在,不存在则创建
                    File dir = new File(path);
                    if (!dir.exists()) {
                        dir.mkdirs();
                    }
                    File file = new File(dir, fileName);
                    randomAccessFile = new RandomAccessFile(file, "rwd");
                    randomAccessFile.setLength(length);
    
                    //下载文件
                    connFile = (HttpURLConnection) url.openConnection();
                    connFile.setConnectTimeout(5000);
                    connFile.setRequestMethod("GET");
                    connFile.setRequestProperty("Range", "bytes=" + 0 + "-" + length);
                    code = connFile.getResponseCode();
    
                    //显示通知栏进度条
                    Intent intent = new Intent();
                    intent.setAction(ACTION_START);
                    intent.putExtra("id", id);
                    sendBroadcast(intent);
    
                    if (code == HttpURLConnection.HTTP_PARTIAL) {
                        inputStream = connFile.getInputStream();
                        int finished = 0;
                        byte[] bytes = new byte[1024 * 1024];
                        int len = -1;
                        long time = System.currentTimeMillis();
                        while ((len = inputStream.read(bytes)) != -1) {
                            //文件写入
                            randomAccessFile.write(bytes, 0, len);
                            //更新通知栏进度条
                            finished += len;
                            if (System.currentTimeMillis() - time > 1000) {
                                time = System.currentTimeMillis();
                                intent.setAction(ACTION_UPDATE);
                                int pro = (int) (((float) finished / length) * 100);
                                intent.putExtra("finished", pro);
                                sendBroadcast(intent);
                            }
                        }
                    }
                    //关闭通知栏
                    intent.setAction(ACTION_FINISHED);
                    sendBroadcast(intent);
    
                } catch (MalformedURLException e) {
                    sendBroadcast(new Intent().setAction(ACTION_ERROR));
                    e.printStackTrace();
                } catch (IOException e) {
                    sendBroadcast(new Intent().setAction(ACTION_ERROR));
                    e.printStackTrace();
                } finally {
                    if (connLength != null) {
                        connLength.disconnect();
                    }
                    if (connFile != null) {
                        connFile.disconnect();
                    }
                    try {
                        if (inputStream != null) {
                            inputStream.close();
                        }
                        if (randomAccessFile != null) {
                            randomAccessFile.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                super.run();
            }
        }
    }
    

    更新下载通知广播:

    
    /**
     * Created by 方舟 on 2017/10/17.
     *  更新下载广播接收器
     */
    
    public class DownloadApkReceiver extends BroadcastReceiver {
    
        private UpdateNotificationUtil mNotificationUtil;
    
        @Override
        public void onReceive(Context context, Intent intent) {
            mNotificationUtil = new UpdateNotificationUtil(context);
    
            if (DownloadApkService.ACTION_START.equals(intent.getAction())) {
                StaticUtil.isDownLoadApk = true;//单例下载,防止多任务进行
                // 下载开始的时候启动通知栏
                mNotificationUtil.showNotification(intent.getIntExtra("id", 0));
            } else if (DownloadApkService.ACTION_UPDATE.equals(intent.getAction())) {
                // 更新进度条
                mNotificationUtil.updateNotification(intent.getIntExtra("id",0), intent.getIntExtra("finished", 0));
            } else if (DownloadApkService.ACTION_FINISHED.equals(intent.getAction())) {
                StaticUtil.isDownLoadApk = false;//变更未任务未下载
                mNotificationUtil.cancelNotification(intent.getIntExtra("id", 0));// 下载结束后取消通知
                UpdateManger.installApk(context, new File(DownloadApkService.path + StaticUtil.apkName));
            } else if (DownloadApkService.ACTION_CANCEL.equals(intent.getAction())) {
                StaticUtil.isDownLoadApk = false;//变更未任务未下载
                mNotificationUtil.cancelNotification(intent.getIntExtra("id", 0));// 下载结束后取消通知
            } else if (DownloadApkService.ACTION_ERROR.equals(intent.getAction())) {
                MThoast.showShort(context, "读取文件失败,请前往官方网站扫码下载最新版本!");
            }else if (DownloadApkService.ACTION_REDIRECT_ERROR.equals(intent.getAction())) {
                MThoast.showShort(context, "下载地址重定向出现错误,请稍后再试!");
            }
        }
    }

    由于android 8.0添加了NotificationChannel的概念因此这个UpdateNotificationUtil工具类可以根据新的方式自己写,我贴一个仅供参考其中

    StaticUtil.updateVerisonChannelId,StaticUtil.updateVerisonChannelName,两个静态变量最好不要重复

        public static final String updateVerisonChannelId = "包名.updateVersionApp";
        public static final String updateVerisonChannelName = "版本更新";
    /**
     * Created by CherishTang on 2017/10/13.
     * 更新通知
     */
    public class UpdateNotificationUtil {
    
        private Context mContext;
        private NotificationManager mManager;
        private NotificationCompat.Builder mBuilder;
    
        public UpdateNotificationUtil(Context context) {
            this.mContext = context;
            mManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationUtils.createNotificationChannel(
                        false,false,
                        StaticUtil.updateVerisonChannelId,
                        StaticUtil.updateVerisonChannelName,
                        NotificationManager.IMPORTANCE_DEFAULT);
            }
            mBuilder = new NotificationCompat.Builder(context, StaticUtil.updateVerisonChannelId);
        }
    
        /**
         * 显示通知栏
         *
         * @param id
         */
        public void showNotification(final int id) {
    
            mBuilder.setTicker("正在下载");//Ticker是状态栏显示的提示
            mBuilder.setOngoing(true);
            mBuilder.setContentTitle("正在下载最新版本");
            mBuilder.setProgress(100, 0, false);
            mBuilder.setContentText(0 + "%");
            mBuilder.setSmallIcon(R.mipmap.icon_launcher);
            mBuilder.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.icon_launcher));//通知栏的大图标
            Intent msgIntent = new Intent();
            msgIntent.setClass(mContext, MainActivity.class);
            msgIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 100, msgIntent, PendingIntent.FLAG_UPDATE_CURRENT);
            mBuilder.setContentIntent(pendingIntent);//点击跳转
            mManager.notify(id, mBuilder.build());
        }
    
        /**
         * 取消通知栏通知
         */
        public void cancelNotification(int id) {
            mManager.cancel(id);
        }
    
        /**
         * 更新通知栏进度条
         *
         * @param id       获取Notification的id
         * @param progress 获取的进度
         */
        public void updateNotification(int id, int progress) {
            if (mBuilder != null) {
                mBuilder.setTicker("开始下载");//Ticker是状态栏显示的提示
                mBuilder.setOngoing(true);
                mBuilder.setContentTitle("app名称");
                mBuilder.setSmallIcon(R.mipmap.icon_launcher);
                mBuilder.setLargeIcon(BitmapFactory.decodeResource(mContext.getResources(), R.mipmap.icon_launcher));//通知栏的大图标
                mBuilder.setProgress(100, progress, false);
                mBuilder.setContentText(progress + "%");
                mManager.notify(id, mBuilder.build());
            }
        }
    }
    
    /**
     * Created by CherishTang on 2018/7/19.
     * 通知栏工具类
     */
    
    public class NotificationUtils {
        private static NotificationManager mManager;
        private static NotificationCompat.Builder notification;
        private String contentText, contentTitle, channelId;
        private boolean autoCancel = true;
        private static Application application;
    
        public static void init(Application application) {
            NotificationUtils.application = application;
            mManager = (NotificationManager) application.getSystemService(NOTIFICATION_SERVICE);
        }
    
        public NotificationUtils Builder(String channelId) {
            if (notification == null) {
                notification = new NotificationCompat.Builder(application, channelId == null ? "chat" : channelId);
            } else {
                notification.setChannelId(channelId);
            }
            this.channelId = channelId;
            return this;
        }
    
        public static NotificationManager getManager() {
            return mManager;
        }
    
        public static NotificationCompat.Builder getNotification() {
            return notification;
        }
    
        @TargetApi(Build.VERSION_CODES.O)
        public static void createNotificationChannel(boolean isVibrate,
                                                     boolean hasSound,
                                                     String channelId,
                                                     String channelName,
                                                     int importance) {
            NotificationChannel channel = new NotificationChannel(channelId, channelName, importance);
            NotificationManager notificationManager = (NotificationManager) application.getSystemService(
                    NOTIFICATION_SERVICE);
            channel.enableVibration(isVibrate);
            channel.enableLights(true);
            if (!hasSound)
                channel.setSound(null, null);
            if (notificationManager != null)
                notificationManager.createNotificationChannel(channel);
        }
    
        public NotificationUtils setChannelId(String channelId) {
            notification.setChannelId(channelId);
            this.channelId = channelId;
            return this;
        }
    
        public NotificationUtils setContentText(String contentText) {
            notification.setContentText(contentText);
            this.contentText = contentText;
            return this;
        }
    
        public NotificationUtils setContentTitle(String contentTitle) {
            notification.setContentTitle(contentTitle);
            this.contentTitle = contentTitle;
            return this;
        }
    
        public NotificationUtils setAutoCancel(boolean autoCancel) {
            notification.setAutoCancel(autoCancel);
            this.autoCancel = autoCancel;
            return this;
        }
    
        public NotificationUtils notifyMessage(int id) {
            if (mManager != null) {
                notification.setContentTitle(contentTitle)
                        .setContentText(contentText)
                        .setWhen(System.currentTimeMillis())
                        .setSmallIcon(R.mipmap.icon_launcher)
                        .setLargeIcon(BitmapFactory.decodeResource(application.getResources(), R.mipmap.icon_launcher))
                        .setAutoCancel(autoCancel)
                        .build();
                mManager.notify(id, notification.build());
            }
            return this;
        }
    
    }
    

    六、下载完成后启动自动安装

    首先注意在Android O新增权限,必须添加,最后调用安装方法

        <!--适配android 8.0-->
        <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
     public static void installApk(Context mContext, File apkFile) {
            try{
                if (!apkFile.exists()) {
                    return;
                }
                Intent i = new Intent(Intent.ACTION_VIEW);
                if (Build.VERSION.SDK_INT >= 24) { //适配安卓7.0
                    i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK); //添加这一句表示对目标应用临时授权该Uri所代表的文件
                    Uri apkFileUri = FileProvider.getUriForFile(mContext.getApplicationContext(),
                            mContext.getPackageName() + ".FileProvider", apkFile);
                    i.setDataAndType(apkFileUri, "application/vnd.android.package-archive");
                } else {
                    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    i.setDataAndType(Uri.parse("file://" + apkFile.toString()),
                            "application/vnd.android.package-archive");// File.toString()会返 
            回路径信息
                }
                mContext.startActivity(i);
            }catch (Exception e){
                e.printStackTrace();
                MThoast.showShort(mContext,"自动安装失败,请尝试手动安装!");
            }
        }

    到这里版本更新就好了,大家有问题可以留言。

    demo地址:https://download.csdn.net/download/fzkf9225/10679015

    我做了两个下载进度条,通知栏和dialog,我觉得一般用通知栏就可以了,dialog最好不用如果关闭下载进度的dialog弹框的话,注销相关DownloadProgressDialog类的相关代码即可

     

    展开全文
  • 友盟更新 自动更新替换方案

    万次阅读 2016-05-09 10:58:51
    自动更新替换方案 这个服务因为目前面临N多非技术的挑战,导致我们很难再维护好这个服务: iOS的自动更新已经被苹果官方严格禁止了,苹果官方也数次联系友盟,要求我们及早把iOS的更新服务停掉; ...


    自动更新替换方案


    这个服务因为目前面临N多非技术的挑战,导致我们很难再维护好这个服务:

    • iOS的自动更新已经被苹果官方严格禁止了,苹果官方也数次联系友盟,要求我们及早把iOS的更新服务停掉;
    • Android面临的问题更多,比如应用市场(集成友盟自动更新插件会导致市场审核被拒)、部分系统厂商(部分厂商系统上,增量更新功能不能正常工作)以及部分运营商的拦截(比如有开发者反馈我们的下载CDN链接在某些地区的运营商会被禁止访问)。

    4.1日起,我们已经停止向新用户透出该服务;今年10.15以后,老用户也不再提供更新包上传服务(网站上传入口不可见,已经发版的SDK,后端仍然提供服务,待自然流量消亡)。下面我们为开发者提供了两种服务迁移方式:

    1. 使用友盟消息推送(http://push.umeng.com/pushIndex)的方式,前提是必须集成友盟的消息推送SDK,通过推送下载链接的方式来通知终端用户有新版本下载。 用户点击通知栏后,跳转到App下载页面。此种方式目前比较安全,受应用市场、厂商系统、运营商的干扰不大。此外,使用消息推送方式的好处是,即使App在没有打开的情况下,仍有可能主动触达到用户(借助于消息推送业务线强大的App互保联盟,只要设备上有一个集成过友盟消息推送的App是活跃的,其它集成友盟推送的App的消息也可以送达,当前应用内更新的方案是App必须打开过,才会触发自动更新的请求),增加触达面。 友盟消息推送的后台截图如下:

     

    消息下发后,终端用户在通知栏就可以看到“新版本更新提示了”,参照图中右上角的红框部分。

    2. 如果对该服务有强依赖,建议自己去实现一套(不建议使用其它第三方自动更新服务,会面临和使用友盟自动更新同样的问题), 我们已经为大家整理了友盟的技术方案,大家可以仿照友盟的技术方案去实现自己的自动更新服务:




    是否可以把源码放出来?

    iOS的逻辑比较简单,我们抽象出来代码放在了github上了:https://github.com/kkme/CheckUpdateiOS 
    Android的由于牵涉到不少友盟自己的类库,所以我们只公开了技术方案,开发者可以参照我们的方案自己去实现。



    友盟自动更新技术解决方案(安卓版)

    系统结构

    友盟自动更新系统的示意图如下:

    图中手机代表客户端。服务端的各个模块描述如下:


    • WebConsole:提供上传更新包的网站操作界面。
    • FS:文件系统,存储apk文件和增量更新包,增量更新的原理后文会提到。
    • DB:用于存储文件的属性,例如版本号,更新描述,文件的md5等。
    • Server: 接收客户端请求,返回文件下载链接。
    • CDN:提供文件下载服务(友盟用到的是阿里云的CDN服务)。


    基本流程

    1 用户在WebConsole上传更新包、填写更新版本和更新日志,程序将更新包存储到FS,版本(version-code)、更新日志、文件md5及其他配置信息存储到DB。
    2 客户端请求Server,传入客户端的appkey、版本号、md5等信息。Server与DB存储的信息比较,如果需要更新则返回更新包的url,否则返回不更新。
    3 客户端收到服务器端的返回结果后判断是否需要更新,如果需要更新,则弹窗提示用户有新版本更新,用户确认后下载安装包,安装新版本。


    交互协议(示例)

    客户端和Server之间使用https接口通信。使用POST请求方式,交互的信息都在http的content中,格式为json。以下简单示例协议中的关键字段。


    Request:

    [Java] 纯文本查看 复制代码
    ?
    1
    2
    3
    4
    5
    {
    "appkey":"xxxxxxxxxx",
    "version_code":1,
    "old_md5":"xxxxxxxxxxxxxxxxx"
    }

    其中version_code是客户端软件的版本号,old_md5是客户端apk文件的md5值。


    Response:
    如果不需要更新则返回下面的response

    [Java] 纯文本查看 复制代码
    ?
    1
    2
    3
    {
    "update": "No"
    }

    如果需要更新, 则返回下面的reponse:

    [Java] 纯文本查看 复制代码
    ?
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    // 全量更新
    {
    "update":"Yes",
    "new_version":"xxxxx",
    "apk_url":"http://cdn.the.url.of.apk/or/patch", // CDN链接下载地址
    "update_log":"xxxx"// 更新日志,用于在界面上显示
    "delta":false,
    "new_md5":"xxxxxxxxxxxxxx",
    "target_size":"601132"
    }[/p][p=21, null, left]

    [Java] 纯文本查看 复制代码
    ?
    01
    02
    03
    04
    05
    06
    07
    08
    09
    10
    11
    12
    // 增量更新
    {
    "update":"Yes",
    "new_version":"xxxxx",
    "apk_url":"http://cdn.the.url.of.apk/or/patch", // CDN链接下载地址
    "update_log":"xxxx"// 更新日志,用于在界面上显示",
    "delta":true,
    "new_md5":"xxxxxxxxxxxxxx", // full-apk的md5
    "target_size":"601132", // full-apk的size
    "patch_md5":"xxxxxxxxxxxxxxxxx", // patch文件的size
    "size":"337852" // patch文件的md5
    }



    服务端处理流程

    流程图如下:
     

    1. 客户端发送请求至服务端,请求内容除了必要的验证信息以外,最重要的信息就是version_code,或者类似的用于比较版本号以判断是否需要升级的字段信息。

    2. 服务端接收到请求后,验证请求的有效性。

    3. 若请求有效,则对比请求中的version_code是否是最新的。

    4. 若不是最新的version_code,则说明需要进行更新,此时需要首先判断是否能够进行增量更新。如果请求中version_code对应的apk文件在服务端存在且md5一致,则可以进行增量更新,否则不能。

    5 如果不能增量更新,则直接返回apk文件的CDN下载链接。

    6 如果能进行增量更新,首先判断对应的patch文件是否存在,如果不存在则调用bsdiff命令生成patch文件后返回patch文件的CDN链接;如果存在就直接返回patch文件CDN链接。


    客户端处理流程

    1.客户端首先请求server,获得是否有新版本的更新信息。

    2. 如果没有更新,则客户端不进行更新动作。

    3. 如果服务端返回的是有更新,客户端会根据全量更新和增量更新两种情况来处理:  如果服务器端返回的是全量更新,则会开启service下载完整版的apk文件; 如果服务器端返回的是增量更新,则会开启service下载patch文件到本地,然后使用JNI进行bspatch,给原apk文件打补丁,生成新版本的apk文件,生成的apk文件要进行MD5校验,如果与后台上传的apk文件的MD5值相等,则认为bspatch成功。

    更新对话框如下:

    4. 客户端在下载完成后,会提示安装,若用户忽略,则会在下次检测更新的时候,首先判断本地是否已经存在最新版的apk文件,若已存在,则会提示安装。


    一些经验

    0. 客户端与服务器端之间的数据传输要进行加密处理,推荐使用https协议。

    1. 建议使用全量更新,目前已知增量更新方案在部分系统厂商上不能正常工作。

    2. 当遇到apk有较大改动时,可能会出现差分包和新apk大小相差不大的情况。这种情况下,建议进行全量升级。因为合并差分包的耗费的时间可能会超过全量升级所花费的时间。

    3. 当apk本身较小时,全量更新更加合适

    4. 若系统内置的apk文件无法获取到,则无法进行增量更新(bspatch是根据系统内置的apk文件与patch文件来合并生成新版本的apk文件)。

    5. 为防止增量更新合成的apk文件有误,需要对合成的apk文件和最新版的apk文件进行MD5校验。


    What's more
    渠道更新

    在本文描述的处理流程基础上,增加很少的扩展就可以实现分渠道更新。具体的做法是:
    1 在上传安装文件时分不同渠道存储,相应的DB里面存储的时候也增加channel的字段。
    2 客户端请求中增加一个字段channel,用于标识客户端的渠道。
    3 服务端根据不同的渠道返回不同的下载链接。


    iOS自动更新

    参见http://bbs.umeng.com/thread-11135-1-1.html


    参考资料

    bsdiff & bspatch:http://www.daemonology.net/bsdiff/




    博主在开发线上APP时就准备了一套自己的更新逻辑~ 
    将在下一篇博文中公布代码 希望共同进步



    展开全文
  • Android应用更新自动检测下载

    千次阅读 2013-08-06 22:04:29
    因此我们有必要给我们的Android应用增加自动更新的功能。 既然实现自动更新,我们首先必须让我们的应用知道是否存在新版本的软件,因此我们可以在自己的网站上放置配置文件,存放软件的版本信息: upda
  • 关闭小米系统自动更新通知

    千次阅读 2018-12-27 10:54:14
    设置--应用管理--更多应用--搜索“系统更新”--点进去选“通知管理”--关闭所有开关即可。
  • 自动适时同步通讯录,ABAddressBookRegisterExternalChangeCallback
  • 前言  之前实现过基于无障碍服务的自动更新(如想了解请移步 http://blog.csdn.net/zxc514257857/article/details/72667640),但是在测试及使用过程中发现有如下缺陷: 无障碍服务只出现在android5.0以上系统中,...
  • Android如何实现APP自动更新

    千次阅读 2017-12-07 16:36:07
    对于安卓用户来说,手机应用市场说满天飞可是一点都不夸张,比如小米,魅族,百度,360,机锋,应用宝等等,当我们想上线一款新版本APP时,先不说渠道打包的麻烦,单纯指上传APP到各大应用市场的工作量就已经很大了...
  • 火狐浏览器关闭自动更新、历史版本下载 此文仅供参考(转载请注明出处): 我使用的版本是 44.0 ; 浏览器设置,选项–>高级:取消勾选 不检查更新 ; 进入火狐浏览器的配置文件夹,修改配置文件,我的路径...
  • web打包app(h5+app)版本自动更新的实现

    千次阅读 2019-09-11 17:19:56
    文章目录背景说明原生app自动更新实现android自动更新实现ios自动更新实现h5+app的特点说明h5+app自动更新实现 背景说明 web打包的app(也称为h5+app),是指将基于html5等移动端web技术,开发的web应用打包成的app。...
  • Android7.0 自动更新适配,包解析异常

    千次阅读 2017-09-04 17:06:00
    问题:在Android7.0的手机上,自动更新的时候出现包解析异常,在其他的手机上没有这个问题。 原因: Android7.0引入私有目录被限制访问和StrictMode API 。私有目录被限制访问是指在Android7.0中为了提高应用...
  • ubuntu13.04取消自动挂载U盘

    千次阅读 2014-04-04 11:42:03
    ubuntu默认是自动查看可移动介质,当U盘手机等与PC连接后,会自动弹出。这在一般情况下是方便用户的,但某些时候比较尴尬。 手机被我更新了以后,文件系统出了问题,连接PC后疯狂弹出挂载和挂载失败的提示,导致我...
  • 华为通过ADB取消系统更新

    千次阅读 2020-06-20 20:29:34
    (2)设置,系统,关于手机,开发人员选项,系统自动更新,关闭 2、设置,系统,系统更新,右上角菜单,什么WIFI自动下载,关。 3、【重点】设置,应用与通知,应用管理,系统更新。 (1)“存诸”里的“数据”...
  • 自动更新很多APP都会有,也有很多第三方的库,但是这些库很多也都是两三年之前写的,当时并没有8.0,9.0这些高版本的手机,如果贸然使用,在测试的时候发现没有问题,到了新版本上就会在很多手机上发现自动更新下载...
  • iphone5s怎么取消iphone系统更新如何关闭系统更新提醒iphone5s怎么取消iphone系统更新如何关闭系统更新提醒网友回答:进入“设置”-“通知中心”,在下面的列表里找到,点进去,把声音那一项取消选中就好了题主亲测...
  • APP版本自动更新(js)

    千次阅读 2019-06-03 14:21:59
    "state": "yes",//是否自动更新 "mark": "V1.0.1",//最新版本号 "url": "http:\/\/*\/app.apk"//安装包路径 } //检查自动更新方法(当前设备在用版本号) function svn(t) { var xhr = new plus.net....
  • Android 插上U盘自动更新

    千次阅读 2018-07-05 16:19:03
    插上U盘自动更新的原理1、检测是否有指定路径下的文件夹String apkPath = "/storage/usbhost1/apk";//本地APK的根目录,不同的屏路径不同我这里是将要更新的apk文件放在U盘里apk这个文件夹下(不同的屏,...
  • 目前很多网站已经出现了手机版的网站,手机网站是和互联网上的网站同步更新的,大多数人访问我们的网站是直接访问电脑上的域名,不可能为了手机网站重新记住一个域名,大家都知道,中国人都是比较懒的,那么遇到这个...
  • 手机自动阅读挣钱,这次用脚本写

    万次阅读 多人点赞 2019-05-16 16:28:48
    如何让趣头条自动阅读挣钱》中,我用c++实现趣头条的自动阅读,挣钱拿去买瓜吃了。最近刚好发现薅羊毛的大户很多都被封号做不下去了,我想这不就刚好是我们散户薅羊毛的大好时机吗?今天我也找了个用脚本编写的方法...
  • Win10 彻底关闭自动更新 2019.8.28本人亲测有效

    万次阅读 热门讨论 2018-11-22 20:16:20
    烦人的自动更新。 不能再忍了! 方法来自知乎大佬 2019年10月15日12:13:50 更新 但是大佬好像放弃这个软件,但是我觉得还挺好用的,我用后,没有一次自动更新。 链接: ...
  • Android应用自动更新功能的代码实现

    千次阅读 2017-04-28 11:38:15
    因此我们有必要给我们的Android应用增加自动更新的功能。 既然实现自动更新,我们首先必须让我们的应用知道是否存在新版本的软件,因此我们可以在自己的网站上放置配置文件,存放软件的版本信息: update
  • ①软件自动更新的的原理实现:我们对于软件版本更新的实现首先需要一个服务器端和我们本地手机客户端,我们在服务器端将有一个 接口提供实时信息 和一个 “最新”版本的apk文件 ;首先我们打开软件的时候会通过接口...
  • 一直说会更新解决,至今仍然没有消息。。。  并且曾开放过白名单,加入白名单的域名可以不受此影响(包括腾讯集团的各个网站)。但如今白名单已经关闭申请。。。 注意: 确认webkit-playsinline在安卓上...
  • 自动更新功能的实现原理

    千次阅读 2012-02-28 22:04:56
    大家好,发现半年没有更新博客了,最近一直都比较忙,决定在凌晨 英超 阿森纳VS富勒姆 中场休息的时候,给大家分享Android里应用版本更新功能这一块的实现。...自动更新功能的实现原理,就是我们事先和后台协商好一个
  • 一、C/S自动更新原理  C/S程序自动升级是一个很重要的功能,原理其实很简单,一般包含两个程序一个是主程序,也就是除了升级功能以外的程序,另一个就是升级程序,常见的360,金山安全卫士都是这样。  ...
  • 因此,在app里实现自动更新的功能,就显得很有必要了。 今天,就来聊一下,如何使用蒲公英第三方平台和DownLoadManager来实现app自动更新的功能。从以下三个方面来说明:** app自动更新流程阐述 如何集成第三方平台...
  • //不可取消 .setCancelable( false ) .create().show(); } else if (version.isHasNewVersion()){ //选择更新 new AlertDialog.Builder(MainActivity. this ) .setTitle( "版本更新" ) .setMessage( ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 29,398
精华内容 11,759
关键字:

如何取消手机自动更新