Android中使用Notification实现应用更新显示下载进度

2023-11-03

公司项目马上要进入内测阶段了,检查的时候发现还差一个更新的功能没有做,IOS那边儿有AppStore,Android可没有,虽然说各大应用市场也会推送吧,但是毕竟还要装个XX应用市场的软件不是,要是没装的话应用不就没法更新了么,考虑到这方面的原因还是决定写一下了。

然后就开始找资料吧,各种找,发现都不尽人意吧,在下资质愚钝,很多东西都是看个一只半解,希望自己写的清晰些,也能帮助一些人吧。

通知栏不会截图,,所以没办法看效果图了,直接上代码吧,最后会放出源码的。


首先是MainActivity类。其实就是个白页面,啥都没有。


package com.demo_download_notification.demo;

import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {
    Context mContext;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContext = this;
        showNoticeDialog("http://wsdownload.hdslb.net/app/BiliPlayer3.apk");
    }


    /**
     * 显示软件更新对话框
     */
    public void showNoticeDialog(final String apkUrl) {
        // 构造对话框

        AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
        builder.setTitle("软件更新");
        builder.setMessage("有新版本,建议更新!");
        // 更新
        builder.setPositiveButton("更新", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
                // 显示下载对话框
                Intent serviceIntent = new Intent(mContext, DownUpdateApk.class);
                serviceIntent.putExtra("url", apkUrl);
                startService(serviceIntent);
            }
        });
        // 稍后更新
        builder.setNegativeButton("稍后更新", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        Dialog noticeDialog = builder.create();
        noticeDialog.show();
    }
}

然后是FileUtil,工具类直接从以前项目中拖过来的。其实也就用了其中一个方法。


package com.demo_download_notification.demo.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class FileUtil {


    /**
     * 将Bitmap 图片保存到本地路径,并返回路径
     *
     * @param c
     * @param mType    资源类型,参照  MultimediaContentType 枚举,根据此类型,保存时可自动归类
     * @param fileName 文件名称
     * @param bitmap   图片
     * @return
     */
    public static String saveFile(Context c, String fileName, Bitmap bitmap) {
        return saveFile(c, "", fileName, bitmap);
    }

    public static String saveFile(Context c, String filePath, String fileName, Bitmap bitmap) {
        byte[] bytes = bitmapToBytes(bitmap);
        return saveFile(c, filePath, fileName, bytes);
    }


    public static boolean saveFile(InputStream inputStream, String path, String fileName, Handler mHandler, long fileLength) throws IOException {
        File newFile = new File(path);
        if (!newFile.exists()) {
            newFile.mkdir();
        }
        newFile = new File(path + "/" + fileName);
        OutputStream outs = new FileOutputStream(newFile);
        int byteWritten = 0;
        int byteCount = 0;
        byte[] bytes = new byte[1024];
        int percentage = 0; //保存百分比信息
        int count = 0;
        int nowCount = 1;
        while ((byteCount = inputStream.read(bytes)) != -1) {
            count += byteCount;
            percentage = (int) (((float) count / fileLength) * 100);

            if (percentage > 0 && percentage == nowCount) { //每完成百分之一 通知Handler一次
                nowCount = percentage + 1;
                Message msg = mHandler.obtainMessage();
                msg.what = 1;
                msg.obj = percentage + "";
                mHandler.sendMessage(msg);
            }
            outs.write(bytes, 0, byteCount);
            byteWritten += byteCount;
        }
        //写入完成,通知Handler 可以进行安装,改变通知栏ui
        Message msg = mHandler.obtainMessage();
        msg.what = 2;
        msg.obj = percentage + "";
        mHandler.sendMessage(msg);
        inputStream.close();
        outs.close();
        if (byteWritten > 0) {
            return true;
        } else {
            return false;
        }
    }

    public static byte[] bitmapToBytes(Bitmap bm) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(CompressFormat.JPEG, 100, baos);
        return baos.toByteArray();
    }

    public static String saveFile(Context c, String filePath, String fileName, byte[] bytes) {
        String fileFullName = "";
        FileOutputStream fos = null;
        String dateFolder = new SimpleDateFormat("yyyyMMdd", Locale.CHINA)
                .format(new Date());
        try {
            String suffix = "";
            File file = new File(getPath(filePath));
            if (!file.exists()) {
                file.mkdirs();
            }
            File fullFile = new File(filePath, fileName + suffix);
            fileFullName = fullFile.getPath();
            fos = new FileOutputStream(new File(filePath, fileName + suffix));
            fos.write(bytes);
        } catch (Exception e) {
            fileFullName = "";
        } finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                    fileFullName = "";
                }
            }
        }
        return fileFullName;
    }


    public static String getPath(String filePath) {
        if (filePath == null || filePath.trim().length() == 0) {
            filePath = Environment.getExternalStorageDirectory() + "/JiaXT/";
        } else {
            filePath = "";
        }
        return filePath;
    }

    public static String getPath() {
        return Environment.getExternalStorageDirectory() + "/TsingpuAkp/";
    }


    /**
     * 删除单个文件
     *
     * @param filePath 被删除文件的文件名
     * @return 文件删除成功返回true,否则返回false
     */
    public static boolean deleteFile(String filePath) {
        File file = new File(filePath);
        if (file.isFile() && file.exists()) {
            return file.delete();
        }
        return false;
    }

    /**
     * 删除文件夹以及目录下的文件
     *
     * @param filePath 被删除目录的文件路径
     * @return 目录删除成功返回true,否则返回false
     */
    public static boolean deleteDirectory(String filePath) {
        boolean flag = false;
        //如果filePath不以文件分隔符结尾,自动添加文件分隔符
        if (!filePath.endsWith(File.separator)) {
            filePath = filePath + File.separator;
        }
        File dirFile = new File(filePath);
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        flag = true;
        File[] files = dirFile.listFiles();
        //遍历删除文件夹下的所有文件(包括子目录)
        for (int i = 0; i < files.length; i++) {
            if (files[i].isFile()) {
                //删除子文件
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) break;
            } else {
                //删除子目录
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) break;
            }
        }
        if (!flag) return false;
        //删除当前空目录
        return dirFile.delete();
    }

    /**
     * 根据路径删除指定的目录或文件,无论存在与否
     *
     * @param filePath 要删除的目录或文件
     * @return 删除成功返回 true,否则返回 false。
     */
    public static boolean DeleteFolder(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            return false;
        } else {
            if (file.isFile()) {
                // 为文件时调用删除文件方法
                return deleteFile(filePath);
            } else {
                // 为目录时调用删除目录方法
                return deleteDirectory(filePath);
            }
        }
    }


    /**
     * 保存文件
     *
     * @param bm
     * @param fileName
     * @throws IOException
     */
    public static File getFile(Bitmap bm, String fileName, String filePath) {
        try {
            String path = getPath(filePath);
            File dirFile = new File(path);
            if (!dirFile.exists()) {
                dirFile.mkdir();
            }
            File myCaptureFile = new File(path + fileName);
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myCaptureFile));
            bm.compress(CompressFormat.JPEG, 80, bos);
            bos.flush();
            bos.close();
            return myCaptureFile;
        } catch (IOException e) {
        }
        return null;
    }


}

最后就是最关键的service服务类了,DownUpdateApk

package com.demo_download_notification.demo;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.Nullable;
import android.widget.RemoteViews;
import com.demo_download_notification.demo.utils.FileUtil;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by color on 16/5/16.
 */
public class DownUpdateApk extends Service {

    NotificationManager notificationManager;
    Notification myNotify;

    private String url;

    private Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            int progress = Integer.parseInt(message.obj.toString());
            RemoteViews rv;
            switch (message.what) {
                case 1:  //更改通知栏UI布局
                    rv = new RemoteViews(getPackageName(),
                            R.layout.my_notification);
                    rv.setTextViewText(R.id.text_title, "正在下载中");
                    rv.setProgressBar(R.id.progress, 100, progress, false);
                    rv.setTextViewText(R.id.text_content, progress + "%");
                    myNotify.contentView = rv;
                    notificationManager.notify(0, myNotify);
                    break;
                case 2:
                    rv = new RemoteViews(getPackageName(),
                            R.layout.my_notification);
                    rv.setTextViewText(R.id.text_title, "下载完成,点击安装");
                    rv.setProgressBar(R.id.progress, 100, progress, false);
                    rv.setTextViewText(R.id.text_content, progress + "%");
                    myNotify.contentView = rv;


                    //下载完成,点击可以去安装文件
                    Intent intent = new Intent();
                    intent.setAction(Intent.ACTION_VIEW);// android.intent.action.VIEW
                    intent.setDataAndType(Uri.fromFile(new File(FileUtil.getPath() + "/Tsingpu.apk")),
                            "application/vnd.android.package-archive");
                    myNotify.flags = Notification.FLAG_AUTO_CANCEL;
                    myNotify.contentIntent = PendingIntent.getActivity(DownUpdateApk.this, 1, intent, 0);
                    notificationManager.notify(0, myNotify);


                    break;
            }
            return false;
        }
    });

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        myNotify = new Notification();
        myNotify.icon = R.mipmap.ic_launcher;
        myNotify.tickerText = "准备下载...";
        myNotify.when = System.currentTimeMillis();

        myNotify.flags = Notification.FLAG_NO_CLEAR;// 不能够自动清除

        RemoteViews rv = new RemoteViews(getPackageName(),
                R.layout.my_notification);
        rv.setProgressBar(R.id.progress, 100, 0, false);
        rv.setTextViewText(R.id.text_content, "开始下载"); //这里就是使用自定义布局了 初始化的时候不设置Intent,点击的时候就不会有反应了,亏得我还找了好久  T-T

        myNotify.contentView = rv;
        notificationManager.notify(0, myNotify);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        url = null;
        myNotify = null;
        notificationManager = null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        url = intent.getStringExtra("url");
        init();

        return super.onStartCommand(intent, flags, startId);
    }


    public void init() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                OkHttpClient client = new OkHttpClient(); //使用okhttp下载文件
                Request request = new Request.Builder()
                        .url(url)
                        .build();

                client.newCall(request).enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        String s = e.getMessage();
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        if (!response.isSuccessful())
                            throw new IOException("Unexpected code " + response);
                        InputStream is = response.body().byteStream(); //成功的回调中拿到字节流
                        String path = FileUtil.getPath();
                        long fileLength = response.body().contentLength(); //获取文件长度
                        FileUtil.saveFile(is, path, "test.apk", mHandler, fileLength); //保存下载的apk文件
                    }

                });


            }
        }).start();
    }
}


自定义Notification的布局文件也贴出来吧


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">


        <TextView
            android:id="@+id/text_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="正在下载中"
            android:textSize="12sp"
            android:visibility="visible" />

        <TextView
            android:id="@+id/text_finish"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_below="@id/text_title"
            android:text="下载完成,点击安装"
            android:textSize="12sp"
            android:visibility="gone" />

        <TextView
            android:id="@+id/text_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="下载进度"
            android:textSize="12sp"
            android:visibility="visible" />


        <ProgressBar
            android:id="@+id/progress"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_alignParentBottom="true"
            android:layout_below="@id/text_content"
            android:layout_weight="1"
            android:max="100"
            android:visibility="visible" />

    </RelativeLayout>


</LinearLayout>


就是这么多了,关键的地方我应该都写了注释的。


最后附上下载地址 :https://github.com/color9169/DownloadUpdateOnNotification/tree/master









本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android中使用Notification实现应用更新显示下载进度 的相关文章

  • Android 主机意图过滤器通配符

    是否可以在 android host 属性上使用通配符 就像是 android host site com android pathPattern android pathPrefix m android scheme http gt Or
  • 定期运行任务(每天一次/每周一次)

    我想定期 每周 每天一次 运行一些任务 即获取我的网站新闻页面 即使我的应用程序已关闭 是否可以 是的 您需要查看报警管理器 http developer android com reference android app AlarmMan
  • 按回键隐藏软键盘

    我有一个EditText in an Activity我希望当我打开它时它处于活动状态并且软键盘处于打开状态Activity 这是我的xml for EditText
  • Android 上的 Firebase:如何检查 Firebase 身份验证失败原因?

    我在 Android 上使用 Firebase 和 Firebase Auth 功能 I try FirebaseAuth signInWithEmailAndPassword如果失败 我想知道为什么登录过程失败 The signInWit
  • 如何在出现“无法解析放置符号”错误时向哈希图添加键和值

    我正在与安卓工作室 https en wikipedia org wiki Android Studio1 4 1 我刚刚创建了一个 Hashmap 并正在遵循有关如何填充和操作它的教程 Java 语言 但是 我收到 无法解析符号放置 错误
  • AppCompat v21 工具栏更改徽标大小

    我正在从以前的操作栏迁移到 appcompat v21 中的新工具栏功能 我仍然想将徽标保留在操作栏 工具栏 的左上角 为此 我在布局中添加了支持工具栏 并为其创建了一个新的工具栏 app theme style NewToolBarSty
  • Android - 当不在栏顶部时推送通知空白

    我在使用 Android 推送通知时遇到一个小问题 如果有 3 个通知 并且只有其中一个显示标题和消息 位于酒吧顶部的那个 如果有人知道可能是什么问题 请告诉我 请参阅此链接上的图像 这就是我接收通知的方式http postimg org
  • Android中不同线程的数据库访问

    我有一个在 AsyncTasks 中从互联网下载数据的服务 它解析数据并将其存储在数据库中 该服务持续运行 当服务写入数据库时 活动会尝试从数据库中读取更改 我有一个数据库助手 有多种写入和读取方法 这会导致问题吗 可能尝试从两个不同的线程
  • SQLite支持android的数据类型有哪些

    谁能告诉我 SQLITE 中支持 ANDROID 的数据类型列表 我想确认 TIME 和 DATE 数据类型 这里有一个list http www sqlite org datatype3 htmlSQLite 的数据类型 支持时间和日期间
  • android 确定设备是否采用从右到左的语言/布局

    有没有办法确定设备是否使用从右到左的语言 例如阿拉伯语 而不是从左到右的语言 英语 与较旧的 API 级别 低至 10 兼容的东西是必要的 SOLUTION 我最终在接受的答案中使用了 xml 方法 接下来 我还添加了此处指示的代码 以应对
  • 没有调用addToBackStack,片段仍然添加到backstack,为什么?

    我正在制作我的片段更换器助手类 但我遇到了一些问题 我称之为FragmentChanger 它有一个fragmentContainer 这是一个ViewGroup 其中包含我想展示的所有片段 我已经做了我自己的replace Fragmen
  • Android ListView setSelection() 似乎不起作用

    我有一个ListActivity实现onListItemClick 并调用doSomething 类的功能 后者包含l setSelection position where l is the ListView object 现在有一个on
  • window.onbeforeunload 在 Android Chrome 上不会触发 [alt.解决方案?]

    我开发了一个简单的聊天应用程序 我正在使用 window onbeforeunload当有人关闭选项卡 浏览器时 基本上是当用户离开房间时 通知其他用户 这是我的代码 scope onExit function scope chatstat
  • 如何从android获取应用程序安装时间

    我尝试了一些方法 但没有成功 请帮助我 PackageManager pm context getPackageManager ApplicationInfo appInfo pm getApplicationInfo app packag
  • jar 中的 apklib 有什么优点?

    我正在关注这个问题 https stackoverflow com questions 6059502 whats the difference between apklib and jar files但它并没有完全回答我的问题 jar 中
  • 从手机访问本地主机[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我正在使用
  • Android:打开和关闭SQLite数据库

    我正在开发Android应用程序 我经常在其中访问本地数据库 该数据库可以从不同的主题访问 因此我遇到了数据库的协调问题 我使用以下open and close method public void open mDb mDbHelper g
  • 内部存储的安全性如何?

    我需要的 对于 Android 我需要永久保存数据 但也能够编辑 并且显然是读取 它 用户不应访问此数据 它可以包含诸如高分之类的内容 用户不得对其进行编辑 我的问题 我会 并且已经 使用过Internal Storage 但我不确定它实际
  • 检测 ListView(或 ScrollView)内的滚动位置

    我正在构建一个聊天室应用程序 其中每 X 秒就会轮询一次新事件 每次发生这种情况时 此代码都会使用新数据更新 RoomAdapter ArrayAdapter 的自定义子类 并将其滚动到底部 RoomAdapter adapter Room
  • Android - iphone 风格 tabhost [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi

随机推荐

  • 解决一个安装office2016缺少vcruntime140.dll的问题

    问题描述 在安装并激活好office2016之后 双击word 显示 缺少vcruntime140 dll 解决方案一 1 下载vcruntime140 dll 2 复制到C盘windows sysWOW64 3 然后寻找下载文件夹里zhu
  • 一文详解 Spring Bean 循环依赖

    一 背景 有好几次线上发布老应用时 遇到代码启动报错 具体错误如下 Caused by org springframework beans factory BeanCurrentlyInCreationException Error cre
  • chooseAddress:fail the api need to be declared in the requiredPrivateInfos field in app.json/ext.js

    错误描述 在使用uni app开发微信小程序的时候 想要通过uni chooseLocation获取用户地理位置的时候出现chooseAddress fail the api need to be declared in the requi
  • Linux环境安装配置ffmpeg

    最近需要在云主机上配置ffmpeg 租的服务器上面的环境往往是Linux 参考别人的文章配好了环境 在此进行综合记录 参考文章 https zhuanlan zhihu com p 347780238 https blog csdn net
  • Python 变量类型

    变量是存储在内存中的值 这就意味着在创建变量时会在内存中开辟一个空间 基于变量的数据类型 解释器会分配指定内存 并决定什么数据可以被存储在内存中 因此 变量可以指定不同的数据类型 这些变量可以存储整数 小数或字符 变量赋值 Python 中
  • python技能描述_【python】利用python爬虫 将LOL所有英雄的技能介绍给爬取下来

    工欲善其事 必先利其器 要想玩好LOL 那了解所有英雄的技能必然是其最基本的 所以此爬虫就应运而生 运行环境 python 3 7 此爬虫所用的库有 requests 获取网页信息 openpyxl Excel相关操作 pymysql My
  • UE4 命令行创建Pak

    原创文章 转载请注明出处 回头还会出一个通过编辑器扩展创建Pak的 命令行的还是比较麻烦 命令行打包如下 引擎版本4 25 由于使用新的引擎版本 感觉pak这块变化挺大的 1 gt 注意中间的空格 2 gt 解析 1 E engine 4
  • 2021全国大学生信息安全竞赛初赛部分WP

    第一阶段 Misc tiny traffic 分析pcap包 能发现几个可疑的请求 flag wrapper test secret 分别把它们传输的文件提取出来 得到三个压缩包 通过flag gzip的内容可以确认这个IP就是我们要分析的
  • 初次使用PPYOLOE-R

    目的 优化基于yolov5 obb旋转目标检测算法的证件区域检测 之前的方法是基于anchor 每次使用都要调试anchor 而ppyoloe r是free anchor的算法 源码位置 https github com PaddlePad
  • 网络IO的阻塞与非阻塞、异步与同步

    1 阻塞与非阻塞 IO默认是阻塞的 设置非阻塞方法如下 include
  • Oracle自动工作量资料档案库(AWR)和自动数据库诊断监视器(ADDM)基础知识

    OracleDB内置的AWR存放一些快照 这些快照的内容是重要的统计信息和工作量的信息 默认每隔60分钟自动从SGA中获取一次 被易管理性监视器 MMOM 存在磁盘上 默认保存8天 可以在EM中单击 Server 服务器 选项卡 然后单击
  • 【PI控制】位置式PI的拉普拉斯变化和离散化(在开关电源的应用)

    0 导读 开关电源主要是利用MCU的PWM波控制MOS管导通与截止 以达到控制输出电压或则输出电流的作用 以下描述均建立在开关电源控制上 1 位置式PI 位置式PI控制式对于咱这种小白是一种比较友善和直观的控制算法 很形象的描述了对控制对象
  • C# 序列化原码分析

    mcs class referencesource mscorlib system runtime serialization formatterservices cs private static MemberInfo GetSerial
  • 华为OD机试真题【滑动窗口最大值】Java版本

    滑动窗口最大值 题目描述 有一个N个整数的数组 和一个长度为M的窗口 窗口从数组内的第一个数开始滑动直到窗口不能滑动为止 每次窗口滑动产生一个窗口和 窗口内所有数和和 求窗口滑动产生的所有窗口和的最大值 输入描述 第一行输入一个正整数N 表
  • C语言函数大全-- l 开头的 Linux 内核函数(链表管理函数)

    l 开头的 Linux 内核函数 链表管理函数 1 list add list add tail 1 1 函数说明 1 2 演示示例 2 list cut before list cut position 2 1 函数说明 2 2 演示示例
  • MCP

    文献名 Identification of candidate plasma protein biomarkers for cervical cancer using the multiplex proximity extension as
  • 半岛铁盒平板测评--真的很垃圾的平板-怎么修改CPU型号

    兼职 赚了点钱 双十一到了 于是想买个平板 看了老久了 大牌太贵 买不起 正在犹豫的时候发现了这个什么鸟半岛铁盒出来了 这个该死的淘宝 真是让人又恨又爱 然后选了半天 决定入坑这个 看着参数不错 1200的价格也差不多对得上这个参数 就动手
  • 权重计算方法一:层次分析法(AHP)

    目录 1 层次分析法原理介绍 2 层次分析法建模步骤 3 案例分析 3 1 题目简述 3 2 确定评价指标 建立层次关系 3 3 构造判断矩阵 3 3 1 标度定义 3 3 2 构造判断矩阵 3 4 一致性检验 3 5 层次总排序 4 代码
  • 兜兜转转,2020已过半

    兜兜转转间 这个开局有些艰难的2020就已经过半了 这些日子 你过得还好吗 不管是努力抵抗病痛 还是奋力工作生活 其实一直以来 我们都在路上 摸爬滚打 艰难前行 我们总是在追寻 在求索 为了所爱的人 而默默付出努力 却仍时时觉得对不起他们
  • Android中使用Notification实现应用更新显示下载进度

    公司项目马上要进入内测阶段了 检查的时候发现还差一个更新的功能没有做 IOS那边儿有AppStore Android可没有 虽然说各大应用市场也会推送吧 但是毕竟还要装个XX应用市场的软件不是 要是没装的话应用不就没法更新了么 考虑到这方面