为啥下载管理器完成后广播接收器不调用?

Posted

技术标签:

【中文标题】为啥下载管理器完成后广播接收器不调用?【英文标题】:Why Broadcast Receiver doesn't Call after download manager is completed?为什么下载管理器完成后广播接收器不调用? 【发布时间】:2019-11-17 19:33:29 【问题描述】:

我正在设置下载管理器以下载服务器 URL 的 PDF 文件。 文件已完全下载,但广播接收器不调用打开文件。 我使用 AsyncTask 和 doInBackground 类下载并在清单中设置 permission.INTERNET,permission.WRITE_EXTERNAL_STORAGE,permission.WRITE_INTERNAL_STORAGE ,permission.READ_EXTERNAL_STORAGE。 我在真实设备中检查了我的目录,并且 PDF 文件已完全下载,没有任何崩溃。

在 OnCreate 中

        registerReceiver(onComplete, filter);

在点击按钮中

                    downloadPdf(v);
                 else 
                    requestStoragePermission(v);
                

并且还设置了 onDestroy

    public void onDestroy() 
        super.onDestroy();
        unregisterReceiver(onComplete);
    

下载文件

        @Override
        protected Void doInBackground(String... strings) 
            String fileUrl = strings[0];
            String fileName = strings[1];
            String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
            File folder = new File(extStorageDirectory, DIRECTORY_PDF_NAME);
            if (!folder.exists()) 
                folder.mkdir();
            
//            File pdfFile = new File(folder, fileName);
            file_download(fileUrl);
            return null;
        

        public void file_download(String fileUrl) 

            File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + DIRECTORY_PDF_NAME + "/" + "au.pdf");
            if (file.exists()) 
                Intent target = new Intent(Intent.ACTION_VIEW);
                target.setDataAndType(Uri.fromFile(file), "application/pdf");
                target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

                Intent intent = Intent.createChooser(target, "انتخاب برنامه");
                try 
                    startActivity(intent);
                 catch (ActivityNotFoundException e) 
                    Toast.makeText(LoginActivity.this, "عدم موفقیت در نمایش فایل", Toast.LENGTH_SHORT).show();
                
             else 
                mgr = (DownloadManager) LoginActivity.this.getSystemService(Context.DOWNLOAD_SERVICE);
                Uri downloadUri = Uri.parse(fileUrl);
                DownloadManager.Request request = new DownloadManager.Request(
                        downloadUri);
                request.setAllowedNetworkTypes(
                        DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE)
                        .setAllowedOverRoaming(false)
                        .setTitle("راهنمای ثبت نام")
                        .setDescription("  در حال دانلود..." + "فایل راهنمای ثبت نام")
                        .setDestinationInExternalPublicDir("/" + DIRECTORY_PDF_NAME + "/", "au.pdf");

                try 
                    refid = mgr.enqueue(request);
                    Log.d(TAG, "Checking download status for id: " + refid);

                 catch (ActivityNotFoundException e) 
                    Toast.makeText(LoginActivity.this, "عدم موفقیت در دانلود فایل", Toast.LENGTH_SHORT).show();
                
            
        
    

最后

        public void onReceive(Context ctxt, Intent intent) 

            File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + DIRECTORY_PDF_NAME + "/" + "au.pdf");
            Intent target = new Intent(Intent.ACTION_VIEW);
            target.setDataAndType(Uri.fromFile(file), "application/pdf");
            target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
            Intent intentPdf = Intent.createChooser(target, "انتخاب برنامه");
            try 
                startActivity(intentPdf);
             catch (ActivityNotFoundException e) 
            
        

【问题讨论】:

【参考方案1】:

我用这个解决方案解决了这个问题 我创建了一个 PDF 类并在其中传输我的下载代码。

public Pdf(Context context, String url, String fileName) 
    this.context = context;
    this.url = url;
    this.fileName = fileName;
    init();



private void init() 
    downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
    context.registerReceiver(onComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
    Download_Uri = Uri.parse(url);


public void checkAndDownload() 
    if (isStoragePermissionGranted()) 
        if (isExistPdfFile()) 
            openGeneratedPDF();
        else
            downloadPdf();
        

    


public void permissionGranted(int[] grantResults) 
    if(grantResults[0]== PackageManager.PERMISSION_GRANTED)
        downloadPdf();
    


private boolean isStoragePermissionGranted() 
    if (Build.VERSION.SDK_INT >= 23) 
        if (context.checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) 
            return true;
         else 
            ActivityCompat.requestPermissions((Activity) context, new String[]Manifest.permission.WRITE_EXTERNAL_STORAGE, 1);
            return false;
        
     else 
        return true;
    



public BroadcastReceiver onComplete = new BroadcastReceiver() 
    public void onReceive(Context ctxt, Intent intent) 
        isCompeleted = true;
        openGeneratedPDF();
    

;

private boolean isExistPdfFile() 
    File target = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
    file = new File(target, DIRECTORY_PDF_NAME + "/" + fileName + ".pdf");
    if (file.exists()) 
        return true;
    else
        return false;
    


private void openGeneratedPDF() 
    if (isExistPdfFile()) 
        Intent intent = new Intent(Intent.ACTION_VIEW);
        Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", file);
        Log.e("uri is",uri.toString());
        intent.setDataAndType(uri, "application/pdf");
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        try 
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            context.startActivity(intent);
         catch (ActivityNotFoundException e) 
            Toast.makeText(context, "برنامه‌ای برای نمایش فایل PDF وجود ندارد", Toast.LENGTH_LONG).show();
        
    else 
        Toast.makeText(context,"فایل مورد نظر یافت نشد",Toast.LENGTH_LONG).show();
    


private void downloadPdf() 
    DownloadManager.Request request = new DownloadManager.Request(Download_Uri);
    request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
    request.setAllowedOverRoaming(true);
    request.setVisibleInDownloadsUi(true);
    request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, Constant.DIRECTORY_PDF_NAME + "/" + fileName + ".pdf");
    refid = downloadManager.enqueue(request);
    Log.e("OUT", "" + refid);


public boolean getIsCompeleted() 
    return isCompeleted;

并在我的需求活动中调用它,我也使用文件提供程序,例如

  Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".fileprovider", file);

【讨论】:

以上是关于为啥下载管理器完成后广播接收器不调用?的主要内容,如果未能解决你的问题,请参考以下文章

android app中的服务为啥接收不到广播

使用Android服务,实现报警管理器和广播接收器

如何使用警报管理器将数据从片段传递到广播接收器

onResume 后广播接收器不工作

从广播接收器更新片段中的列表视图

我如何将字符串从主要活动传递到带有警报管理器的广播接收器?