96.android 简单的更新APP、下载安装APK(四种方式)

//第一种 下载更新使用OKHttp+ProgressDialog进度条+第三方AlertDialog

 

 

//第一步 在Manifest.xml里面写权限:

 

<!-- 网络权限-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 8.0安装需要的权限 -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!-- 读写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

//第二步 导入第三方依赖:

 

//申请动态权限
implementation 'com.lovedise:permissiongen:0.0.6'
//okhttp
implementation 'com.squareup.okhttp3:okhttp:3.9.1'
//第三方AlertDialog
implementation 'com.bigkoo:alertview:1.0.3'

//第三步 我的Activity代码实现:

public class Main2Activity extends AppCompatActivity implements View.OnClickListener {

    private Button mButton;
    private ProgressDialog progressDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        initView();
        //初始化ProgressDialog进度条
        progressDialog = progress();
        //申请动态权限
        permissiongen();
    }

    private void permissiongen() {
        //处理需要动态申请的权限
        PermissionGen.with(Main2Activity.this)
                .addRequestCode(200)
                .permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
                .request();
    }

    //申请权限结果的返回
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        PermissionGen.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
    }

    //权限申请成功
    @PermissionSuccess(requestCode = 200)
    public void doSomething() {
        //在这个方法中做一些权限申请成功的事情
        Toast.makeText(getApplication(), "成功", Toast.LENGTH_SHORT).show();

    }

    //申请失败
    @PermissionFail(requestCode = 200)
    public void doFailSomething() {
        Toast.makeText(getApplication(), "失败", Toast.LENGTH_SHORT).show();
    }


    private void initView() {
        mButton = (Button) findViewById(R.id.mButton);

        mButton.setOnClickListener(this);

    }

    @Override
    public void onClick(final View v) {
        switch (v.getId()) {
            case R.id.mButton:
                new AlertView("通知", "发现新版是否更新?", null, null, new String[]{"以后再说", "立即更新"}, this, AlertView.Style.Alert, new OnItemClickListener() {
                    @Override
                    public void onItemClick(Object o, int position) {
                        switch (position) {
                            case 1:
                                progressDialog.show();//将ProgessDialog显示出来
                                download();//开始下载
                                break;
                        }
                    }
                }).show();
                break;
        }


    }

    /*
     * 方法名:progress()
     * 功    能:初始化ProgressDialog进度框
     * 参    数:无
     * 返回值:ProgressDialog
     */
    private ProgressDialog progress() {
        //自定义标题
        TextView title = new TextView(this);
        title.setText("正在更新");//设置文本
        title.setPadding(0, 40, 0, 0); //边距,左上右下
        title.setGravity(Gravity.CENTER); //位置
        title.setTextColor(Color.parseColor("#5d9eff"));//字体的颜色
        title.setTextSize(23); //字体的大小

        ProgressDialog progressDialog = new ProgressDialog(this);//创建一个ProgressDialog的实例
        progressDialog.setProgressDrawable(getResources().getDrawable(R.drawable.dialog_color));//设置背景色,设置进度条颜色
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//样式_水平
        progressDialog.setMax(100);//最大值
        progressDialog.setCancelable(false);//设置可否用back键关闭对话框
        progressDialog.setCustomTitle(title);//设置自定义标题
        progressDialog.setProgress(0);//设定进度
//        progressDialog.setMessage("内容");//内容消息
//      progressDialog.setTitle("正在更新");//标题
//      progressDialog.setProgressNumberFormat(" ");//只显示左下角的百分比,右下角的数字去掉
        return progressDialog;
    }

    /*
     * 方法名: download()
     * 功    能:下载apk,保存到本地,安装apk
     * 参    数:无
     * 返回值:无
     */
    private void download() {

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://downpack.baidu.com/appsearch_AndroidPhone_v7.9.3(1.0.64.143)_1012271b.apk")
                .build();
        Call call = client.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("TAG-失败", e.toString());
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        progressDialog.cancel();
                        Toast.makeText(getApplication(), "网络请求失败!", Toast.LENGTH_SHORT).show();
                    }
                });
            }

            @Override
            public void onResponse(Call call, final Response response) throws FileNotFoundException {
                Log.e("TAG-下载成功", response.code() + "---" + response.body().toString());

                //设置apk存储路径和名称
                File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/百度助手.apk");

                //保存文件到本地
                localStorage(response, file);
            }
        });
    }

    /*
     * 方法名:localStorage(final Response response, final File file)
     * 功    能:保存文件到本地
     * 参    数:Response response, File file
     * 返回值:无
     */
        private void localStorage(final Response response, final File file) throws FileNotFoundException {
        //拿到字节流
        InputStream is = response.body().byteStream();
        int len = 0;
        final FileOutputStream fos = new FileOutputStream(file);
        byte[] buf = new byte[2048];
//        int currentSize=0;
        try {
            while ((len = is.read(buf)) != -1) {
                fos.write(buf, 0, len);
//                currentSize+=len;
//                Log.e("TAG保存到文件进度:", currentSize + "/" + response.body().contentLength());
                Log.e("TAG每次写入到文件大小", "onResponse: " + len);
                Log.e("TAG保存到文件进度:", file.length() + "/" + response.body().contentLength());

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        progressDialog.setProgress((int) (file.length() * 100 / response.body().contentLength()));//当前文件长度除以文件总长度乘以100,返回int值。
                        //如果当前文件长度等于文件总长度与progressDialog框存在
                        if (file.length() == response.body().contentLength() && progressDialog.isShowing()) {
                            //进度重置,关闭进度框
                            progressDialog.setProgress(0);
                            progressDialog.cancel();
                            //弹出对话框,提示是否安装
                            new AlertView("下载完成", "是否立即安装?", null, null, new String[]{"取消", "安装"}, MainActivity.this, AlertView.Style.Alert, new OnItemClickListener() {
                                @Override
                                public void onItemClick(Object o, int position) {
                                    switch (position) {
                                        case 1:
                                            //安装apk
                                            installingAPK(file);
                                            break;
                                    }
                                }
                            }).show();
                        }
                    }
                });
            }
            fos.flush();
            fos.close();
            is.close();
        } catch (IOException e) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    progressDialog.setProgress(0);
                    progressDialog.cancel();
                    Toast.makeText(MainActivity.this, "下载失败!", Toast.LENGTH_SHORT).show();
                }
            });
            e.printStackTrace();
        }
    }

    /*
     * 方法名:installingAPK(File file)
     * 功    能:安装apk,适配安卓6.0,7.0,8.0
     * 参    数:File file
     * 返回值:无
     */
    private void installingAPK(File file) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //安卓7.0以上需要在在Manifest.xml里的application里,设置provider路径
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(this, "com.gannan.gannan.fileprovider", new File(file.getPath()));
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        }
        startActivity(intent);
    }

}

//第四步 在res下的drawable里新建dialog_color.xml文件,用来给ProgressDialog设置背景色,设置进度条颜色。

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >

    <!-- 设置背景色 -->
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="5dip" />

            <gradient
                android:endColor="#cccccc"
                android:startColor="#cccccc" />
        </shape>
    </item>

    <!-- 设置进度条颜色 -->
    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="5dip" />

                <gradient
                    android:endColor="#5d9eff"
                    android:startColor="#5d9eff" />
            </shape>
        </clip>
    </item>

</layer-list>

 

 

 

//第五步 跳转安装时,安卓7.0以上需要在在Manifest.xml里的application里,设置provider路径。

 //在application里,com.gannan.gannan这是我的包名,替换成你的包名:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.gannan.gannan.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

//第六步 在res下新建xml文件夹,再从xml下新建file_paths.xml。

 //com.gannan.gannan这是我的包名,替换成你的包名:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path path="Android/data/com.gannan.gannan/" name="files_root" />
    <external-path path="." name="external_storage_root" />
</paths>

//第七步 最后就是这个Activity的布局文件,就只有一个Button,点击下载更新:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.gannan.gannan.Main2Activity"
    android:orientation="vertical"
    >

    <Button
        android:id="@+id/mButton"
        android:text="下载更新"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

//简洁版:下载工具类: 

public class DownloadUtil {
    private static DownloadUtil downloadUtil;
    private final OkHttpClient okHttpClient;

    public static DownloadUtil get() {
        if (downloadUtil == null) {
            downloadUtil = new DownloadUtil();
        }
        return downloadUtil;
    }

    private DownloadUtil() {
        okHttpClient = new OkHttpClient();
    }

    /**
     * @param url      下载连接
     * @param path     储存下载文件的本地目录
     * @param listener 下载监听
     */
    public void download(final String url, final String path, final OnDownloadListener listener) {
        File file = new File(path);
        if (!file.mkdirs()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        Request request = new Request.Builder().url(url).build();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 下载失败
                listener.onDownloadFailed();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = response.body().byteStream();
                byte[] buf = new byte[2048];
                int len = 0;
                final FileOutputStream fos = new FileOutputStream(path);
                int total = (int) response.body().contentLength();
                int sum = 0;
                try {
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        int progress = (int) (sum * 1.0f / total * 100);
                        // 下载中
                        listener.onDownloading(progress);
                    }
                } catch (Exception e) {
                    //下载失败
                    listener.onDownloadFailed();
                    e.printStackTrace();
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (IOException e) {
                    }
                    try {
                        if (fos != null)
                            fos.close();
                    } catch (IOException e) {
                    }
                }

                // 下载完成
                if (sum == response.body().contentLength()) {
                    listener.onDownloadSuccess();
                }
            }
        });
    }


    public interface OnDownloadListener {
        /**
         * 下载成功
         */
        void onDownloadSuccess();

        /**
         * @param progress 下载进度
         */
        void onDownloading(int progress);

        /**
         * 下载失败
         */
        void onDownloadFailed();
    }
}

//在点击事件中使用:

                                //将ProgessDialog显示出来
                                progressDialog.show();
                                //设置apk存储路径和名称
                                String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/百度助手呦/百度助手呦.apk";
                                //url地址
                                String url = "https://downpack.baidu.com/appsearch_AndroidPhone_v7.9.3(1.0.64.143)_1012271b.apk";
                                //开始下载
                                DownloadUtil.get().download(url, path, new DownloadUtil.OnDownloadListener() {
                                    @Override
                                    public void onDownloadSuccess() {
                                        progressDialog.cancel();
                                        runOnUiThread(new Runnable() {
                                            @Override
                                            public void run() {
                                                Toast.makeText(MainActivity.this, "下载完成", Toast.LENGTH_SHORT).show();
                                            }
                                        });
                                    }

                                    @Override
                                    public void onDownloading(int progress) {
                                        //进度条
                                        progressDialog.setProgress(progress);
                                    }

                                    @Override
                                    public void onDownloadFailed() {
                                        progressDialog.cancel();
                                        runOnUiThread(new Runnable() {
                                            @Override
                                            public void run() {
                                                Toast.makeText(MainActivity.this, "下载失败", Toast.LENGTH_SHORT).show();
                                            }
                                        });
                                    }
                                });

//------------------------------------------------------(第一种方式完成)----------------------------------------------------------------

 

//第二种 通过Okhttp+Notification通知的方式进行下载更新:

//第一步 在Manifest.xml里面写权限:

 

<!-- 网络权限-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 8.0安装需要的权限 -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!-- 读写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

//第二步 导入第三方依赖:

 

//申请动态权限
implementation 'com.lovedise:permissiongen:0.0.6'
//okhttp
implementation 'com.squareup.okhttp3:okhttp:3.9.1'

 

 //第三步 我的Activity代码实现:

 

public class Main3Activity extends AppCompatActivity implements View.OnClickListener {

    private Button mButton2;
    private NotificationCompat.Builder builder;
    private NotificationManager notificationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        initView();
        permissiongen();
    }

    private void initView() {
        mButton2 = (Button) findViewById(R.id.mButton2);

        mButton2.setOnClickListener(this);
    }

    private void permissiongen() {
        //处理需要动态申请的权限
        PermissionGen.with(Main3Activity.this)
                .addRequestCode(200)
                .permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
                .request();
    }

    //申请权限结果的返回
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        PermissionGen.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
    }

    //权限申请成功
    @PermissionSuccess(requestCode = 200)
    public void doSomething() {
        //在这个方法中做一些权限申请成功的事情
        Toast.makeText(getApplication(), "成功", Toast.LENGTH_SHORT).show();

    }

    //申请失败
    @PermissionFail(requestCode = 200)
    public void doFailSomething() {
        Toast.makeText(getApplication(), "失败", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.mButton2:
                initialNotification();
                download();
                break;
        }
    }

    /*
     * 方法名:initialNotification()
     * 功    能:初始化通知管理器,创建Notification
     * 参    数:无
     * 返回值:无
     */
    private void initialNotification() {
        //Notification跳转页面
        Intent notificationIntent = new Intent(this, Main3Activity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);

        //初始化通知管理器
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        //8.0及以上需要设置好“channelId”(没有特殊要求、唯一即可)、“channelName”(用户看得到的信息)、“importance”(重要等级)这三个重要参数,然后创建到NotificationManager。
        String PUSH_CHANNEL_ID = "PUSH_NOTIFY_ID";
        String PUSH_CHANNEL_NAME = "PUSH_NOTIFY_NAME";
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(PUSH_CHANNEL_ID, PUSH_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH);
            if (notificationManager != null) {
                notificationManager.createNotificationChannel(channel);
            }
        }

        //创建Notification
        builder = new NotificationCompat.Builder(Main3Activity.this);
        builder.setContentTitle("正在更新...") //设置通知标题
                .setContentIntent(contentIntent)
                .setSmallIcon(R.mipmap.bbb)//设置通知的小图标(有些手机设置Icon图标不管用,默认图标就是Manifest.xml里的图标)
                .setLargeIcon(BitmapFactory.decodeResource(Main3Activity.this.getResources(), R.mipmap.bbb)) //设置通知的大图标
                .setDefaults(Notification.DEFAULT_LIGHTS) //设置通知的提醒方式: 呼吸灯
                .setPriority(Notification.PRIORITY_MAX) //设置通知的优先级:最大
                .setAutoCancel(false)//设置通知被点击一次是否自动取消
                .setContentText("下载进度:0%")
                .setChannelId(PUSH_CHANNEL_ID)
                .setProgress(100, 0, false);//进度最大100,默认是从0开始

        //构建通知对象
        Notification notification = builder.build();
        notificationManager.notify(1, notification);

//        问题来了,默认情况下,点击了通知栏,会弹出一个新的activity实例,也就是说会重复打开同一个Activity。
//        解决办法是在Manifest.xml里面把此activity的android:launchMode设为singleTop就搞定了。

    }

    /*
     * 方法名: download()
     * 功    能:下载apk,保存到本地,安装apk
     * 参    数:无
     * 返回值:无
     */
    private void download() {

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url("https://downpack.baidu.com/appsearch_AndroidPhone_v7.9.3(1.0.64.143)_1012271b.apk")
                .build();
        Call call = client.newCall(request);

        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("TAG-失败", e.toString());
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplication(), "网络请求失败!", Toast.LENGTH_SHORT).show();
                    }
                });
            }

            @Override
            public void onResponse(Call call, final Response response) throws FileNotFoundException {
                Log.e("TAG-下载成功", response.code() + "---" + response.body().toString());

                //设置apk存储路径和名称
                File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/百度助手.apk");

                //保存文件到本地
                localStorage(response, file);
            }
        });
    }

    /*
     * 方法名:localStorage(final Response response, final File file)
     * 功    能:保存文件到本地
     * 参    数:Response response, File file
     * 返回值:无
     */
    private void localStorage(final Response response, final File file) throws FileNotFoundException {
        //拿到字节流
        InputStream is = response.body().byteStream();
        int len = 0;
        final FileOutputStream fos = new FileOutputStream(file);
        byte[] buf = new byte[2048];
        try {
            while ((len = is.read(buf)) != -1) {
                fos.write(buf, 0, len);
                //Log.e("TAG每次写入到文件大小", "onResponse: "+len);
                Log.e("TAG保存到文件进度:", file.length() + "/" + response.body().contentLength());

                //notification进度条和显示内容不断变化,并刷新。
                builder.setProgress(100, (int) (file.length() * 100 / response.body().contentLength()), false);
                builder.setContentText("下载进度:" + (int) (file.length() * 100 / response.body().contentLength()) + "%");
                Notification notification = builder.getNotification();
                notificationManager.notify(1, notification);
            }
            fos.flush();
            fos.close();
            is.close();

            //下载完成,点击通知,安装
            installingAPK(file);

        } catch (IOException e) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(getApplication(), "下载失败!", Toast.LENGTH_SHORT).show();
                }
            });
            e.printStackTrace();
        }
    }

    /*
     * 方法名:installingAPK(File file)
     * 功    能:下载完成,点击通知,安装apk,适配安卓6.0,7.0,8.0
     * 参    数:File file
     * 返回值:无
     */
    private void installingAPK(final File file) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //安卓7.0以上需要在在Manifest.xml里的application里,设置provider路径
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(this, "com.gannan.gannan.fileprovider", new File(file.getPath()));
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        }
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);

        //下载完成后,设置notification为点击一次就关闭,并设置完成标题内容。并设置跳转到安装页面。
        builder.setContentTitle("下载完成")
                .setContentText("点击安装")
                .setAutoCancel(true)//设置通知被点击一次是否自动取消
                .setContentIntent(contentIntent);

        Notification notification = builder.getNotification();
        notificationManager.notify(1, notification);
    }

}

 

//第四步 跳转安装时,安卓7.0以上需要在在Manifest.xml里的application里,设置provider路径。

 //在application里,com.gannan.gannan这是我的包名,替换成你的包名:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.gannan.gannan.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

//第五步 在res下新建xml文件夹,再从xml下新建file_paths.xml。

 //com.gannan.gannan这是我的包名,替换成你的包名:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path path="Android/data/com.gannan.gannan/" name="files_root" />
    <external-path path="." name="external_storage_root" />
</paths>

//第六步 我的Activity布局,就有个Button:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.gannan.gannan.Main3Activity">

    <Button
        android:id="@+id/mButton2"
        android:text="下载"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

//第七步 某些手机的Notification通知默认是不允许通知的,要自己去打开,设置为允许通知,要不然通知还是不显示。

 

//----------------------------------------------------------(第二种方式结束)------------------------------------------------------------------

 

//第三种 方式是使用DownloadManager系统的下载管理器来进行下载更新的:

 

//第一步 在Manifest.xml里面写权限:

 

<!-- 网络权限-->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 8.0安装需要的权限 -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<!-- 读写权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

//第二步 导入第三方依赖:

 

//申请动态权限
implementation 'com.lovedise:permissiongen:0.0.6'

//第三步 我的Activity代码实现:

 

public class Main4Activity extends AppCompatActivity implements View.OnClickListener {

    private Button mButton3;

    private String versionName = "百度助手呦.apk";
    private String versionUrl = "https://downpack.baidu.com/appsearch_AndroidPhone_v7.9.3(1.0.64.143)_1012271b.apk";
    private long mTaskId;
    private DownloadManager downloadManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main4);
        initView();
        permissiongen();
    }

    private void permissiongen() {
        //处理需要动态申请的权限
        PermissionGen.with(Main4Activity.this)
                .addRequestCode(200)
                .permissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE)
                .request();
    }

    //申请权限结果的返回
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        PermissionGen.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
    }

    //权限申请成功
    @PermissionSuccess(requestCode = 200)
    public void doSomething() {
        //在这个方法中做一些权限申请成功的事情
        Toast.makeText(getApplication(), "成功", Toast.LENGTH_SHORT).show();

    }

    //申请失败
    @PermissionFail(requestCode = 200)
    public void doFailSomething() {
        Toast.makeText(getApplication(), "失败", Toast.LENGTH_SHORT).show();
    }

    private void initView() {
        mButton3 = (Button) findViewById(R.id.mButton3);

        mButton3.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.mButton3:
                downloadAPK(versionUrl, versionName);
                break;
        }
    }

    //使用系统下载器下载
    private void downloadAPK(String versionUrl, String versionName) {//创建下载任务

        DownloadManager.Request request = new DownloadManager.Request(Uri.parse(versionUrl));
        request.setAllowedOverRoaming(false);//漫游网络是否可以下载
//设置文件类型,可以在下载结束后自动打开该文件
        MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
        String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(versionUrl));
        request.setMimeType(mimeString);
        request.setMimeType("application/vnd.android.package-archive");//设置类型为apk文件
        //使用系统默认的下载路径 此处为应用内 /android/data/packages ,所以兼容7.0
//        request.setDestinationInExternalFilesDir(this, Environment.DIRECTORY_DOWNLOADS, versionName);
        //设置WIFI下进行更新
//        request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
//在通知栏中显示,默认就是显示的
        request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
        request.setVisibleInDownloadsUi(true);
//sdcard的目录下的download文件夹,必须设置
        request.setDestinationInExternalPublicDir("/download/", versionName);
//request.setDestinationInExternalFilesDir(),也可以自己制定下载路径
//将下载请求加入下载队列
        downloadManager = (DownloadManager) this.getSystemService(Context.DOWNLOAD_SERVICE);
//加入下载队列后会给该任务返回一个long型的id,
//通过该id可以取消任务,重启任务等等,看上面源码中框起来的方法
        mTaskId = downloadManager.enqueue(request);
//注册广播接收者,监听下载状态
        this.registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    }

    //广播接受者,接收下载状态
    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            checkDownloadStatus();//检查下载状态
        }
    };

    //检查下载状态
    private void checkDownloadStatus() {

        DownloadManager.Query query = new DownloadManager.Query();
        query.setFilterById(mTaskId);//筛选下载任务,传入任务ID,可变参数
        Cursor c = downloadManager.query(query);
        if (c.moveToFirst()) {
            int status = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
            switch (status) {
                case DownloadManager.STATUS_PAUSED:
                    Log.e("TAGM", ">>>下载暂停");
                case DownloadManager.STATUS_PENDING:
                    Log.e("TAGM", ">>>下载延迟");
                case DownloadManager.STATUS_RUNNING:
                    Log.e("TAGM", ">>>正在下载");
                    break;
                case DownloadManager.STATUS_SUCCESSFUL:
                    Log.e("TAGM", ">>>下载完成");
                    //下载完成安装APK
                    String downloadPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() + File.separator + versionName;
                    installAPK(new File(downloadPath));
                    break;
                case DownloadManager.STATUS_FAILED:
                    Log.e("TAGM", ">>>下载失败");
                    break;

            }
        }
    }

    //下载到本地后执行安装
    private void installAPK(File file) {
        if (!file.exists()) return;
        Intent intent = new Intent(Intent.ACTION_VIEW);
        //安卓7.0以上需要在在Manifest.xml里的application里,设置provider路径
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(this, "com.gannan.gannan.fileprovider", new File(file.getPath()));
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        }
        startActivity(intent);
    }

}

//第四步 跳转安装时,安卓7.0以上需要在在Manifest.xml里的application里,设置provider路径。

 //在application里,com.gannan.gannan这是我的包名,替换成你的包名:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.gannan.gannan.fileprovider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>

//第五步 在res下新建xml文件夹,再从xml下新建file_paths.xml。

 //com.gannan.gannan这是我的包名,替换成你的包名:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path path="Android/data/com.gannan.gannan/" name="files_root" />
    <external-path path="." name="external_storage_root" />
</paths>

//第六步 我的Activity布局里就一个Button:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.gannan.gannan.Main4Activity">

    <Button
        android:id="@+id/mButton3"
        android:text="下载"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

//-------------------------------------------------------------(第三种方式结束)------------------------------------------------------------

 

//第四种 调用第三方浏览器打开网址下载文件

 //这种方式比较简单:

 //调用第三方浏览器方法:

/*
 * 方法名:openBrowser(Context context, String url)
 * 功    能:调用第三方浏览器打开
 * 参    数:Context context, String url
 * 返回值:无
 */
private void openBrowser(Context context, String url) {
    final Intent intent = new Intent();
    intent.setAction(Intent.ACTION_VIEW);
    intent.setData(Uri.parse(url));
    //intent.resolveActivity()可以返回显示该Intent的Activity对应的组件名
    if (intent.resolveActivity(context.getPackageManager()) != null) {
        final ComponentName componentName = intent.resolveActivity(context.getPackageManager());
        //componentName我的是com.android.browser.BrowserActivity
        Log.e("android自带的浏览器访问:", componentName.getClassName());
        context.startActivity(Intent.createChooser(intent, "请选择浏览器"));
    } else {
        Toast.makeText(context.getApplicationContext(), "请下载浏览器", Toast.LENGTH_SHORT).show();
    }
}

//使用的时候  调用就行了:

openBrowser(this, "https://downpack.baidu.com/appsearch_AndroidPhone_v7.9.3(1.0.64.143)_1012271b.apk");

//-----------------------------------------------------------------第四种结束----------------------------------------------------------------------------

//------------------------------------------------------------------------完--------------------------------------------------------------------------------- 

  • 27
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值