ফাইলপ্রভাইডার ক্র্যাশ - একটি শূন্য স্ট্রিং-এ XMLResourceParser কে আহ্বান করার চেষ্টা করছে n


139

এটি আমার প্রকাশের একটি অংশ:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.asd"
    android:versionCode="118"
    android:versionName="118" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />


    <application
        android:name="com.example.asd.AsdApplication"
        android:allowBackup="true"
        android:allowTaskReparenting="true"
        android:theme="@style/AsdTheme" >
        ...

        <provider
            android:name="com.example.asd.database.hq.ContentProviderDB"
            android:authorities="ourContentProviderAuthorities" >
        </provider>
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.example.asd.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>

       ...
    </application>

</manifest>

এটি কাঁচা / এক্সএমএল / ফাইলপথ.এক্সএমএল ফাইলপথ ফাইল file

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

আমি ইন্টারনেট থেকে একটি ভিডিও ডাউনলোড করি এবং এটিকে অভ্যন্তরীণ স্টোরেজে সংরক্ষণ করি:

public static boolean saveInputStreamToInternalStorageFile(Context context, String filename, byte[] dataToWrite, Context ctx) {
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(context.getFilesDir() + File.separator + filename);

        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(dataToWrite);
        oos.close();
        return true;
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    }
}

আমি এটি এর মতো ব্যবহার করার চেষ্টা করি:

private void playVideoFromDeviceWithWorkaround(String fileName) {

    File newFile = new File(getFilesDir(), fileName);
    Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.asd", newFile);

    try {
        vvVideoFullscreen.setVideoURI(contentUri);
        showMediaControls = true;
        playVideo();
    } catch (Exception e) {
        playVideoFromNetwork();
    }

}

এই লাইনে:

Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.asd", newFile); 

আমি নিম্নলিখিত ত্রুটি পেয়েছি:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:560)
at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:534)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:376)

"এটি ফাইলপথ ফাইল" - আপনার প্রকল্পে ঠিক এই ফাইলটি কোথায়?
কমন্সওয়্যার

1
কাঁচা / এক্সএমএল / ফাইলপথ.এক্সএমএল
জে কে

2
কর্তৃপক্ষগুলিতে আমার কাছে প্রোপ্রাইডার রয়েছে, অ্যাপ্লিকেশন প্যাকেজটিতে সংযুক্ত আছে, তবে getUriforFile কল করার সময় আমি অ্যাপেনড করি না pro সম্ভবত এটি এখনই চলছে, আমি এখনই পরীক্ষা করছি
জে কে

4
হ্যাঁ সমস্যাটি ছিল
জে কে

উত্তর:


264

সমস্যাটি হ'ল ম্যানিফেস্টে আমার এই লাইনটি ছিল:

android:authorities="com.example.asd.fileprovider"

এবং getUriForFile কল করার সময় আমি যাচ্ছিলাম:

Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.asd", newFile); 

তাই থেকে পরিবর্তিত "com.example.asd"করা "com.example.asd.fileprovider"এবং এটা কাজ


1
ধন্যবাদ আমার জন্য কাজ। প্রথমে আমি এইভাবে করছিলাম। অ্যান্ড্রয়েড কর্তৃপক্ষ = "$ {applicationId} .fileprovider এখন আমি আমার প্রকৃত প্যাকেজের নাম com.memecreator.fileprovider তা পরিবর্তিত
Rayyan

2
@ রায়ানের সাথে সম্মত হন, android:authorities="${applicationId}"সর্বদা ব্যবহারের জন্য সেরা ; কোড কখনই ভুল হবে না।
Sud007

আমার জন্য কাজ করেছেন। ধন্যবাদ
ল্যান্ড্রিকেপেলা

2
এই সমাধানটি আমার পক্ষে কার্যকর হয়নি ... আমি সঠিক কিনা তা পরীক্ষা করার পরেও নাল পয়েন্টার ব্যতিক্রম পাচ্ছি।
ওয়েসলি

44

আপনি একই ডিভাইস (মনে একাধিক রূপগুলো চালাতে পারছে না একটি অতিরিক্ত সুবিধার সঙ্গে প্যাকেজের নাম hardcoding ছাড়া এটা করতে পারেন releaseএবং debugসঙ্গে applicationIdSuffixদেখতে এই বিষয়গুলো ):

ভিত্তিক FileProvider.java:560

final ProviderInfo info = context.getPackageManager()
        .resolveContentProvider(authority, PackageManager.GET_META_DATA);
final XmlResourceParser in = info.loadXmlMetaData( //560
        context.getPackageManager(), META_DATA_FILE_PROVIDER_PATHS);

আপনি ভুল ব্যবহার করছিলেন authorityএবং এটি ContentProvider( info == null) খুঁজে পেল না ।

আপনার ম্যানিফেস্টটি এতে পরিবর্তন করুন ( ${applicationId}ম্যানিফেস্ট মার্জার দ্বারা প্রতিস্থাপন করা হবে)

android:authorities="${applicationId}.share"

এবং

Uri uri = FileProvider.getUriForFile(context, context.getPackageName() + ".share", result);

.shareপ্রত্যয় ঐচ্ছিক, যদি আপনি একটি বাস্তব আছে ContentProviderযা কর্তৃপক্ষ হিসাবে প্যাকেজের নাম আছে উত্তম।


আমার জন্য কাজ করেছেন ... আমি শেষ দুটি লাইন এবং এর কাজটি পুরোপুরি ব্যবহার
করেছি..ধন্যবাদ

24

আমার ক্ষেত্রে, আমি ত্রুটি পেয়েছি কারণ

BuildConfig.APPLICATION_ID

থেকে আমদানি করা হচ্ছে

import android.support.v4.BuildConfig;

সুতরাং এটির স্ট্রিংটি "android.support.v4"আমার প্রকল্প প্যাকেজের নামের পরিবর্তে ছিল । আমদানি ফাইলটি আপনার import project.Buildconfigএবং অন্যটি থেকে নয় তা দেখুন। উদাহরণ:

import com.example.yourProjectName.BuildConfig;

পরিশেষে, <provider>ম্যানিফেস্টে ট্যাগ করে আমাকে android:authorities="${applicationId}"সর্বদা আমার প্রকল্পের প্যাকেজের নাম কর্তৃপক্ষ হিসাবে পেতে হবে

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

    </application>

</manifest>

1
অ্যান্ড্রয়েড কী: সংস্থান = "@ xML / ruta_fileprovider"
অনন্ত প্রসাদ

1
@ অ্যান্টনাপ্রসাদ <? এক্সএমএল সংস্করণ = "1.0" এনকোডিং = "ইউটিএফ -8"?> <প্যাথস> <বাহ্যিক-পথের নাম = "বহিরাগত_ফায়ালস" পথ = "" " /> <ফাইল-পথের নাম = "ফাইলগুলি" পথ = "।" /> <ক্যাশে-পথের নাম = "ক্যাশে" পথ = "।" /> </paths>
প্রিন্স

5

প্রথমে নিশ্চিত হয়ে নিন যে আপনি সরবরাহকারী android:authoritiesআপনার অন্যান্য সরবরাহকারীদের সাথে দ্বন্দ্ব করছেন না। এছাড়াও এর নামের শেষ অংশের জন্য আপনি যে কোনও নাম চয়ন করতে পারেন: "সরবরাহকারী", "ফাইলপ্রোভাডার" ইত্যাদি but তবে একাধিক android:authoritiesতালিকাভুক্ত থাকা অবস্থায় অ্যাপ ক্র্যাশ হয় , অন্যদিকে ডকুমেন্টেশন বলে যে এটি একাধিক মান তালিকাভুক্ত করার অনুমতি দেয়।

file://টার্গেটএসডিপি ভার্সন> = 24 (অ্যান্ড্রয়েড এন 7.0) এ স্কেন্টটি এখন ইন্টেন্টের সাথে সংযুক্ত হওয়ার অনুমতি নেই, কেবল content://সর্বদা সমস্ত ডিভাইসের (অ্যান্ড্রয়েড 5, 6 এবং 7) এর জন্য পাস করা হয়। তবে আমরা মুখোমুখি হয়েছি যে শাওমি এই গুগল কনভেনশনটি ভেঙে পাঠায়file:// , তাই data.getData().getAuthority()খালি স্ট্রিং দেয়।

final String uriScheme = currentUri.getScheme();
if ("content".equals(uriScheme)) {
    // getting full file path (works with some providers, i.e. Gallery)
    path = FileUtils.getPath(getContext(), currentUri);
    if (path != null) {
         currentFile = new File(path);
    }
} else if ("file".equals(uriScheme)) {
    // in a rare case we received file:// in currentUri, we need to:
    // 1. create new File variable from currentUri that looks like "file:///storage/emulated/0/download/50044382b.jpg"
    // 2. generate a proper content:// Uri for it
    currentFile = new File(currentUri.getPath());
    String authority = data.getData().getAuthority();
    if (authority != null && !authority.isEmpty()) {
        currentUri = FileProvider.getUriForFile(getActivity(), authority, currentFile);
    }
} else {
    // throw exception
}

এছাড়াও, FileProvider.getUriForFile()ক্র্যাশ java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/Android/data/com.example/files/attachments/image.jpgহওয়ার ফলে বাগটি অ্যান্ড্রয়েড সমর্থন লাইব্রেরি v24.2.0 এ স্থির করা হয়েছিল। সমস্যাটি ছিল ফাইলপ্রভাইডার.জাভা বাহ্যিক-পথ ফোল্ডারগুলি দেখেনি।


1

যদি আপনি রানটাইম ব্যবহার করে আপনার সত্যতা তৈরি করে থাকেন BuildConfig তৈরি তবে নিশ্চিত হয়ে নিন যে আপনি আপনার প্যাকেজের নাম সহ পুরো শ্রেণির নাম ব্যবহার করেছেন।

খারাপ:

final String AUTHORITY = BuildConfig.APPLICATION_ID + ".provider";

ভাল:

final String AUTHORITY = com.mycompany.myapp.BuildConfig.APPLICATION_ID + ".provider";


0

নিম্নলিখিত আমার জন্য কাজ করে।

mUri = FileProvider.getUriForFile(this,
                    BuildConfig.APPLICATION_ID + ".provider",
                    fileObject);

0

সমস্যাটি সমাধান করার জন্য আমি এখানে যা করেছি। আমি অ্যান্ড্রয়েডে পুরোপুরি যোগ্য নাম দিয়েছি: নাম। এটি অ্যান্ড্রয়েড 6,7,8 এ কাজ করে

    <provider android:authorities="${applicationId}.opener.provider" 
        android:exported="false" android:grantUriPermissions="true" 
        android:name="io.github.pwlin.cordova.plugins.fileopener2.FileProvider">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/provider_paths" />
    </provider>

আপনি কি দয়া করে অভ্যন্তরীণ ডিরেক্টরি থেকে ফাইল সরবরাহকারীর ব্যবহার করে শেয়ার ফাইলের জন্য আপনার কোডটি ভাগ করতে পারেন?
বিশাল পাটোলিয়া ツ

0

শিরমার চেষ্টা করা উছিত:

  Context context = PostAdapter.this.activity;
                    StringBuilder stringBuilder2 = new StringBuilder();
                    stringBuilder2.append(PostAdapter.this.activity.getPackageName());
                    stringBuilder2.append(".provider");
                    Uri uri;
                    uri = FileProvider.getUriForFile(context,stringBuilder2.toString(), newFile);

0

এটি আপনার করা দরকার:

Uri fileURI = FileProvider.getUriForFile(getActivity(), getActivity().getPackageName() + ".fileprovider", file);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.