Android프로그래밍

Caused by: java.lang.IllegalArgumentException: Couldn’t find meta-data for provider with authority xxx provider 오류 해결하기(PdfDocument를 사용하여 pdf 만드는 과정에 발생)

리스트뷰 내용을 pdf 문서로 생성하는 예제를 테스트 하는 과정에 발생한 오류 내용을 기록해둔다. 어떤 앱 사용자가 기록한 내용을 pdf로 다운 받을 수 있게 해달라는 요청이 들어와서 코드 테스트를 진행하고 있다.

    private void makePdf(){
        int A4Short = PaperSize.A3_WIDTH ;//594; // Postscript points
        int A4Long = PaperSize.A3_HEIGHT;//841; // Postscript points
        int itemCount = adapter.getCount();


        if(itemCount > 0) {
            PdfDocument document = new PdfDocument();
            int pageNumber = 1;
            PdfDocument.PageInfo.Builder pageBuilder = new PdfDocument.PageInfo.Builder(A4Short, A4Long, pageNumber);
            PdfDocument.PageInfo pageInfo = pageBuilder.create();
            PdfDocument.Page page = document.startPage(pageInfo);

            int combinedHeight = 0;

            LinearLayout parent = new LinearLayout(getApplicationContext());
            parent.setOrientation(LinearLayout.VERTICAL);

            for (int index = 0; index < itemCount; index++) {
                // Get the required view
//                MyAdapter.MyViewHolder vh = mAdapter.createViewHolder(parent, mAdapter.getItemViewType(index));
//                mAdapter.bindViewHolder(vh, index);
//                View item = vh.itemView;
//
                View item = LayoutInflater.from(parent.getContext())
                        .inflate(R.layout.activity_using_history, parent, false);

//                View item = findViewById(R.id.topRelativeLayout);

                // Measure View to A4 width and as tall as it needs
                item.measure(View.MeasureSpec.makeMeasureSpec(A4Short, View.MeasureSpec.AT_MOST),
                        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
                // Check combined height does not go off the page
                if ( combinedHeight + item.getMeasuredHeight() > A4Long) {
                    // End page and start next
                    // Layout the LinearLayout
                    parent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                            LinearLayout.LayoutParams.WRAP_CONTENT));
                    parent.measure(View.MeasureSpec.makeMeasureSpec(A4Short, View.MeasureSpec.AT_MOST),
                            View.MeasureSpec.makeMeasureSpec(A4Long, View.MeasureSpec.AT_MOST));
                    parent.layout(0, 0, parent.getMeasuredWidth(), parent.getMeasuredHeight());
                    Canvas pageCanvas = page.getCanvas();
                    // Draw current page
                    parent.draw(pageCanvas);
                    // End page and create next
                    document.finishPage(page);
                    // create new page
                    pageNumber += 1;
                    pageBuilder = new PdfDocument.PageInfo.Builder(A4Short, A4Long, pageNumber);
                    pageInfo = pageBuilder.create();
                    page = document.startPage(pageInfo);
                    // Clean up parent to re-use
                    parent.removeAllViews();
                    // Reset combinedHeight
                    combinedHeight = 0;

                }

                combinedHeight += item.getMeasuredHeight();
                parent.addView(item);
            }
            // Finish last page
            // Layout the LinearLayout
            parent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
                    LinearLayout.LayoutParams.WRAP_CONTENT));
            parent.measure(View.MeasureSpec.makeMeasureSpec(A4Short, View.MeasureSpec.AT_MOST),
                    View.MeasureSpec.makeMeasureSpec(A4Long, View.MeasureSpec.AT_MOST));
            parent.layout(0, 0, parent.getMeasuredWidth(), parent.getMeasuredHeight());
            Canvas pageCanvas = page.getCanvas();
            // Draw current page
            parent.draw(pageCanvas);
            // End page
            document.finishPage(page);

            // Write document to cachefile
            // Create a dated filename
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH-mm-ss", Locale.ROOT);
            fileNameBase = "Daily_Budget_" + df.format(Calendar.getInstance().getTime());
            cacheFile = new File(getCacheDir(), fileNameBase + ".pdf");

            // Create the pdf file in cache directory
            try {
                if (!cacheFile.exists()) {
                    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(cacheFile));
                    document.writeTo(bos);
                    bos.flush();
                    bos.close();
                } else {
                    throw new RuntimeException("Cache file exists when should not");
                }
            } catch (Exception e) {
                // Handle Error
            }

            // Clean up
            document.close();


            // Open PDF
            // Get the URI of the cache file from the FileProvider
            //Caused by: java.lang.IllegalArgumentException: Couldn't find meta-data for provider with authority ddolcat.daily.budget.provider
            Uri uri = FileProvider.getUriForFile(this, getPackageName() + ".provider", cacheFile);
            if (uri != null) {
                // Create an intent to open the PDF in a third party app
                Intent pdfViewIntent = new Intent(Intent.ACTION_VIEW);
                pdfViewIntent.setDataAndType(uri,"application/pdf");
                pdfViewIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                startActivity(Intent.createChooser(pdfViewIntent, "Choose PDF viewer"));
            }

        }
    }

Couldn’t find meta-data for provider with authority xxx provider 해결방법

AndroidMenifest.xml파일을 열고 <application> 태그 아래에 다음 태그를 작성해준다.

 <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
 </provider>

res/xml/ 폴더에는 provider_paths.xml 파일이 존재해야한다. 파일명은 자유롭게 변경할 수 있다. 폴더 아래에 생성한 파일명으로 일치시키면 된다.

provider_paths.xml

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

<cache-path
    name="cache-files"
    path="/" />


<external-path 
            name="my_images" 
            path="Android/data/본인패키지이름/files/Pictures" />  //본인패키지이름으로 수정필요
</path>

 

[참고자료]

https://stackoverflow.com/questions/56598480/couldnt-find-meta-data-for-provider-with-authority

error: Content is protected !!