android7.0 照相和图片剪裁 以及 应用内部apk更新下载安装适配

一 核心思想:

     由于android7.0对私有存储的限制,导致在获取资源的时候,不能通过Uri.fromFile(..)来获取uri了,但是在写入数据的时候是可以通过Uri.fromFile(..)来获取uri的

    7.0其他适配和原理讲解,这位已经讲的很清楚了分享地址:http://www.devio.org/2016/09/28/Android7.0适配心得/

二 适配后的代码段

      demo下载地址

        在做照相,图片剪裁,自动安装功能适配之前,需要以下操作:

        第一步,在AndroidManifest的application中添加一下代码段,作用设置存储空间可以共享

       
     第二步,创建
@xml/file_paths

  

     

     (1)照相

      

 
@Override
public void onClickCamera() {
    String status = Environment.getExternalStorageState();
    if (status.equals(Environment.MEDIA_MOUNTED)) {
        if (!PHOTO_DIR.exists()) {
            PHOTO_DIR.mkdirs();// 创建照片的存储目录
        }
        FileName = System.currentTimeMillis() + ".jpg";
        mCurrentPhotoFile = new File(PHOTO_DIR, FileName);
        Intent intentC = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri imageUri = FileProvider.getUriForFile(VMAddActivity.this, "com.qqwl.fileprovider", mCurrentPhotoFile);
            intentC.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intentC.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

        } else {
            intentC.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mCurrentPhotoFile));
        }
        startActivityForResult(intentC, CAMERA_WITH_DATA);
    } else {
        Toast.makeText(VMAddActivity.this, "没有SD", Toast.LENGTH_LONG).show();
    }

}

   

  (2)剪裁

    这里有的人就会有疑问,为什么同是获取uri有些需要使用FileProvider,有些不需要呢?答案是:在访问手机资源的时候需要使用FileProvider,在不访问资源,仅仅是创建目录的时候不需要。因为7.0限制访问的是资源而不是手机存储空间。


下面是代码

/**
 * 裁剪图片
 *
 * @param uri
 */
public void startPhotoZoom(Uri uri) {

    String fileName = System.currentTimeMillis() + ".jpg";
    if (!PHOTO_DIR.exists()) {
        PHOTO_DIR.mkdirs();// 创建照片的存储目录
    }
    mCacheFile = new File(PHOTO_DIR, fileName);
    Uri   outputUri = Uri.fromFile(new File(mCacheFile.getPath()));
    String url = FileUtils.getPath(VMAddActivity.this, uri);
    Intent intent = new Intent("com.android.camera.action.CROP");

    //sdk>=24
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N){

        Uri imageUri = FileProvider.getUriForFile(VMAddActivity.this, "com.qqwl.fileprovider", new File(url));//通过FileProvider创建一个content类型的Uri
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.putExtra("noFaceDetection", true);//去除默认的人脸识别,否则和剪裁匡重叠
        intent.setDataAndType(imageUri, "image/*");

        //19=<sdk<24
    }else if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT&&android.os.Build.VERSION.SDK_INT<Build.VERSION_CODES.N) {
        intent.setDataAndType(Uri.fromFile(new File(url)), "image/*");

        //sdk<19
    }else {
        intent.setDataAndType(uri, "image/*");
    }
    intent.putExtra("crop", "true");// crop=true 有这句才能出来最后的裁剪页面.
    intent.putExtra("aspectX", 19);// 这两项为裁剪框的比例.
    intent.putExtra("aspectY", 20);// x:y=1:2
    intent.putExtra("outputX", 600);
    intent.putExtra("outputY", 600);
    intent.putExtra("output", outputUri);
    intent.putExtra("outputFormat", "JPEG");// 返回格式
    startActivityForResult(intent, CROP_PHOTO);
}

             

(3)apk下载,自动安装

 

/**
 * 用来下载app的服务
 */
public class DownloadService extends IntentService {
    private static final int BUFFER_SIZE = 10 * 1024; // 8k ~ 32K
    private static final String TAG = "DownloadService";
    private NotificationManager mNotifyManager;
    private Builder mBuilder;
    private  File apkFile;
    private LocalBroadcastManager lbm;
    private BroadcastReceiver receiver;

    public DownloadService() {
        super("DownloadService");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        lbm = LocalBroadcastManager.getInstance(this);
        receiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent.getAction().equals("com.notification.click")){
                    Intent installAPKIntent = new Intent(Intent.ACTION_VIEW);
                    installAPKIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//安装完成后打开新的apk
                    installAPKIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                    installAPKIntent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
                    DownloadService.this.startActivity(installAPKIntent);
                    android.os.Process.killProcess(android.os.Process.myPid());
                }

            }
        };
        lbm.registerReceiver(receiver, new IntentFilter("com.notification.click"));

    }

    @Override
    protected void onHandleIntent(Intent intent) {

        mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        mBuilder = new Builder(this);

        String appName = getString(getApplicationInfo().labelRes);
        int icon = getApplicationInfo().icon;

        mBuilder.setContentTitle(appName).setSmallIcon(icon);

        //开始下载新的apk
        String urlStr = intent.getStringExtra("url");
        InputStream in = null;
        FileOutputStream out = null;

        try {
            URL url = new URL(urlStr);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

            urlConnection.setRequestMethod("GET");
            urlConnection.setDoOutput(false);
            urlConnection.setConnectTimeout(10 * 1000);
            urlConnection.setReadTimeout(10 * 1000);
            urlConnection.setRequestProperty("Connection", "Keep-Alive");
            urlConnection.setRequestProperty("Charset", "UTF-8");
            urlConnection.setRequestProperty("Accept-Encoding", "gzip, deflate");

            urlConnection.connect();
            long bytetotal = urlConnection.getContentLength();
            long bytesum = 0;
            int byteread = 0;
            in = urlConnection.getInputStream();
            File dir = StorageUtils.getCacheDirectory(this);
            String apkName = urlStr.substring(urlStr.lastIndexOf("/") + 1, urlStr.length());
            apkFile = new File(dir, apkName);
            out = new FileOutputStream(apkFile);
            byte[] buffer = new byte[BUFFER_SIZE];

            int oldProgress = 0;

            while ((byteread = in.read(buffer)) != -1) {
                bytesum += byteread;
                out.write(buffer, 0, byteread);

                int progress = (int) (bytesum * 100L / bytetotal);
                // 如果进度与之前进度相等,则不更新,如果更新太频繁,否则会造成界面卡顿
                if (progress != oldProgress) {
                    updateProgress(progress);
                }
                oldProgress = progress;
            }
            //下载完成
            mBuilder.setDefaults(Notification.DEFAULT_SOUND);
            mBuilder.setContentText(getString(R.string.download_success)).setProgress(0, 0, false);
            mNotifyManager.notify(0, mBuilder.build());
            mNotifyManager.cancelAll();

            //下载完成后直接安装打开
            Intent installAPKIntent = new Intent(Intent.ACTION_VIEW);
            installAPKIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//安装完成后打开新的apk
            installAPKIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.N){
                Uri fileUri = FileProvider.getUriForFile(DownloadService.this,"com.qqwl.fileprovider",apkFile);

                installAPKIntent.setDataAndType(fileUri, "application/vnd.android.package-archive");
            }else{
                installAPKIntent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
            }

            this.startActivity(installAPKIntent);
            android.os.Process.killProcess(android.os.Process.myPid());


        } catch (Exception e) {
            Log.e(TAG, "download apk file error", e);
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }




    private void updateProgress(int progress) {
        //"正在下载:" + progress + "%"
        mBuilder.setContentText(this.getString(R.string.download_progress, progress)).setProgress(100, progress, false);

        //setContentInent如果不设置在4.0+上没有问题,在4.0以下会报异常
        PendingIntent pendingintent = PendingIntent.getActivity(this, 0, new Intent(), PendingIntent.FLAG_CANCEL_CURRENT);
        mBuilder.setContentIntent(pendingintent);
        mNotifyManager.notify(0, mBuilder.build());

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        lbm.unregisterReceiver(receiver);
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值