以编程方式更新apk(下载和启动安装)Android API v26

以编程方式更新apk(下载和启动安装)Android API v26,android,Android,我阅读了关于这个问题的所有解决方案。我也知道它可以被认为是重复的,但它不是。 我看到错误:重试toast消息,我看到更新错误日志消息 我认为android v26改变了intent.setDataAndType的某些方面,或者我不知道为什么这不起作用 我还获得了类似于此代码的权限 ActivityCompat.requestPermissions(Update.this, new String[]{Manifest.permission.WRITE_EXTERNA

我阅读了关于这个问题的所有解决方案。我也知道它可以被认为是重复的,但它不是。 我看到错误:重试toast消息,我看到更新错误日志消息

我认为android v26改变了intent.setDataAndType的某些方面,或者我不知道为什么这不起作用

我还获得了类似于此代码的权限

ActivityCompat.requestPermissions(Update.this,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_WRITE_STORAGE);
这个问题无法解决。我只想下载并安装apk文件

AndroidManifest.xml(我添加了写权限)


Update.java

package com.my.testapp;

public class Update extends AppCompatActivity {

ProgressDialog bar;
private static String TAG = "Update";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    new DownloadNewVersion().execute();

}

class DownloadNewVersion extends AsyncTask<String,Integer,Boolean> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        bar = new ProgressDialog(Update.this);
        bar.setCancelable(false);

        bar.setMessage("Downloading...");

        bar.setIndeterminate(true);
        bar.setCanceledOnTouchOutside(false);
        bar.show();

    }

    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);

        bar.setIndeterminate(false);
        bar.setMax(100);
        bar.setProgress(progress[0]);
        String msg = "";
        if(progress[0]>99){

            msg="Finishing... ";

        }else {

            msg="Downloading... "+progress[0]+"%";
        }
        bar.setMessage(msg);

    }
    @Override
    protected void onPostExecute(Boolean result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);

        bar.dismiss();

        if(result){

            Toast.makeText(getApplicationContext(),"Update Done",
                    Toast.LENGTH_SHORT).show();

        }else{

            Toast.makeText(getApplicationContext(),"Error: Try Again",
                    Toast.LENGTH_SHORT).show();

        }

    }

    @Override
    protected Boolean doInBackground(String... arg0) {
        Boolean flag = false;

        try {


            URL url = new URL("http://mydownloadurl.com/_download/update.apk");

            HttpURLConnection c = (HttpURLConnection) url.openConnection();
            c.setRequestMethod("GET");
            c.setDoOutput(true);
            c.connect();


            String PATH = Environment.getExternalStorageDirectory()+"/Download/";
            File file = new File(PATH);
            file.mkdirs();

            File outputFile = new File(file,"app-debug.apk");

            if(outputFile.exists()){
                outputFile.delete();
            }

            FileOutputStream fos = new FileOutputStream(outputFile);
            InputStream is = c.getInputStream();

            int total_size = 277962;//size of apk

            byte[] buffer = new byte[1024];
            int len1 = 0;
            int per = 0;
            int downloaded=0;
            while ((len1 = is.read(buffer)) != -1) {
                fos.write(buffer, 0, len1);
                downloaded +=len1;
                per = (int) (downloaded * 100 / total_size);
                publishProgress(per);
            }
            fos.close();
            is.close();

            OpenNewVersion(PATH);

            flag = true;
        } catch (Exception e) {
            Log.e(TAG, "Update Error: " + e.getMessage());
            flag = false;
        }
        return flag;

    }

}

void OpenNewVersion(String location) {

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(new File(location + "app-debug.apk")),
            "application/vnd.android.package-archive");
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);

}
package com.my.testapp;
公共类更新扩展了AppCompatActivity{
进程对话框栏;
私有静态字符串TAG=“Update”;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
新下载NewVersion().execute();
}
类DownloadNewVersion扩展异步任务{
@凌驾
受保护的void onPreExecute(){
super.onPreExecute();
bar=新建进度对话框(更新.this);
可设置可取消(错误);
设置消息(“下载…”);
bar.setUndeterminate(真);
条形图设置取消到外部(假);
bar.show();
}
受保护的void onProgressUpdate(整数…进度){
super.onProgressUpdate(进度);
bar.setUndeterminate(假);
bar.setMax(100);
bar.setProgress(进度[0]);
字符串msg=“”;
如果(进度[0]>99){
msg=“整理…”;
}否则{
msg=“下载…”+进度[0]+“%”;
}
设置消息(msg);
}
@凌驾
受保护的void onPostExecute(布尔结果){
//TODO自动生成的方法存根
super.onPostExecute(结果);
bar.dispose();
如果(结果){
Toast.makeText(getApplicationContext(),“更新完成”,
吐司。长度(短)。show();
}否则{
Toast.makeText(getApplicationContext(),“错误:重试”,
吐司。长度(短)。show();
}
}
@凌驾
受保护的布尔doInBackground(字符串…arg0){
布尔标志=假;
试一试{
URL=新URL(“http://mydownloadurl.com/_download/update.apk");
HttpURLConnection c=(HttpURLConnection)url.openConnection();
c、 setRequestMethod(“GET”);
c、 设置输出(真);
c、 connect();
String PATH=Environment.getExternalStorageDirectory()+“/Download/”;
文件=新文件(路径);
mkdirs()文件;
File outputFile=新文件(文件“app debug.apk”);
if(outputFile.exists()){
outputFile.delete();
}
FileOutputStream fos=新的FileOutputStream(outputFile);
InputStream=c.getInputStream();
int total_size=277962;//apk的大小
字节[]缓冲区=新字节[1024];
int len1=0;
int per=0;
int=0;
而((len1=is.read(buffer))!=-1){
fos.写入(缓冲区,0,len1);
下载+=len1;
per=(int)(下载*100/总尺寸);
出版进度(per);
}
fos.close();
is.close();
OpenNewVersion(路径);
flag=true;
}捕获(例外e){
Log.e(标记“更新错误:+e.getMessage());
flag=false;
}
返回标志;
}
}
void OpenNewVersion(字符串位置){
意向意向=新意向(意向.行动\视图);
intent.setDataAndType(Uri.fromFile(新文件(位置+“app debug.apk”)),
“application/vnd.android.package归档文件”);
intent.setFlags(intent.FLAG\u活动\u新任务);
星触觉(意向);
}

}非常感谢,我浪费了2-3个小时去做不同的事情

实际上,我以前添加过这段代码,但问题没有解决。 我再试了一次,它成功了,这可能是一个懒惰的解决方案,但它正在工作

,可以应用其他解决方案, 但对我来说已经足够了

        if(Build.VERSION.SDK_INT>=24){
        try{
            Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
            m.invoke(null);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
已经完全修好了,再次非常感谢。 应用程序还需要此存储权限


ActivityCompat.requestPermissions(Update.this,新字符串[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE

您好,我以前试过这么做,但现在我会再试一次,我会在10分钟内给您提供信息。另外,将
Log.e(标记,“更新错误:+e.getMessage());
修改为
Log.e(标记,“更新错误:”+e.getMessage(),e);
,这样您就可以转到LogCat,查看与可能遇到的任何崩溃相关的完整堆栈跟踪。
        if(Build.VERSION.SDK_INT>=24){
        try{
            Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
            m.invoke(null);
        }catch(Exception e){
            e.printStackTrace();
        }
    }