Skip to content Skip to sidebar Skip to footer

In Android 7, Contentresolver's Method-openassetfiledescriptor(vcarduri, "r") Returns Assetfiledescriptor Having Declaredlength As -1

In Android 7, getContentResolver().openAssetFileDescriptor(vCardUri, 'r') returns AssetFileDescriptor having declaredLength as -1 returned by getDeclaredLength(). Trying to export

Solution 1:

With the help of @pskink, I found the following solve my problem.

StringlookupKey= cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
        UrivCardUri= Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
        AssetFileDescriptor assetFileDescriptor;
        FileInputStream inputStream;
        try {
            assetFileDescriptor = getActivity().getContentResolver().openAssetFileDescriptor(vCardUri, "r");
            if (assetFileDescriptor != null) {
                inputStream = assetFileDescriptor.createInputStream();
                return readAsByteArray(inputStream);
            }
        } catch (FileNotFoundException e) {
            Log.e(TAG, "Vcard for the contact " + lookupKey + " not found", e);
        } catch (IOException e) {
            Log.e(TAG, "Problem creating stream from the assetFileDescriptor.", e);
        }

where the readAsByteArray() is written using the code from Mihai Snippet.

Thank you @pskink

Solution 2:

In your code you are you are using the openAssestFileDescriptor instead use the openFileDescriptor because openAssestFileDescriptor is use to read a file in your asset folder not the file Uri

package com.daffo.stackoverflowtest;

    import android.Manifest;
    import android.content.pm.PackageManager;
    import android.content.res.AssetFileDescriptor;
    import android.content.res.AssetManager;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Build;
    import android.os.Environment;
    import android.os.ParcelFileDescriptor;
    import android.provider.ContactsContract;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.Toast;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.nio.channels.FileChannel;
    import java.util.ArrayList;
    import java.util.List;

publicclassMainActivityextendsAppCompatActivity {
    Cursor cursor;
    ArrayList<String> vCard;
    String vfile;
    privatestaticfinalintPERMISSIONS_REQUEST_READ_CONTACTS=100;

/**
 * Called when the activity is first created.
 */@OverridepublicvoidonCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    vfile = "Contacts" + "_" + System.currentTimeMillis() + ".vcf";
    /**This Function For Vcard And here i take one Array List in Which i store every Vcard String of Every Conatact
     * Here i take one Cursor and this cursor is not null and its count>0 than i repeat one loop up to cursor.getcount() means Up to number of phone contacts.
     * And in Every Loop i can make vcard string and store in Array list which i declared as a Global.
     * And in Every Loop i move cursor next and print log in logcat.
     * */
    addContactPermissions();

}

/**
 * Show the contacts in the ListView.
 */privatevoidaddContactPermissions() {
    // Check the SDK version and whether the permission is already granted or not.if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && (checkSelfPermission(Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED || checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
        requestPermissions(newString[]{Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSIONS_REQUEST_READ_CONTACTS);
        //After this point you wait for callback in onRequestPermissionsResult(int, String[], int[]) overriden method
    } else {
        // Android version is lesser than 6.0 or the permission is already granted.
        getVcardString();
    }
}

@OverridepublicvoidonRequestPermissionsResult(int requestCode, String[] permissions,
                                       int[] grantResults) {
    if (requestCode == PERMISSIONS_REQUEST_READ_CONTACTS) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Permission is granted
            getVcardString();
        } else {
            Toast.makeText(this, "Until you grant the permission, we canot display the names", Toast.LENGTH_SHORT).show();
        }
    }
}

privatevoidgetVcardString() {
    // TODO Auto-generated method stub
    vCard = newArrayList<String>();
    cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
    if (cursor != null && cursor.getCount() > 0) {
        cursor.moveToFirst();
        for (inti=0; i < cursor.getCount(); i++) {

            get(cursor);
            if (vCard.size() > 0) {
                Log.d("TAG", "Contact " + (i + 1) + "VcF String is" + vCard.get(i));
            }
            cursor.moveToNext();
        }

    } else {
        Log.d("TAG", "No Contacts in Your Phone");
    }

}

publicvoidget(Cursor cursor) {


    //cursor.moveToFirst();StringlookupKey= cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
    Uriuri= Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
    ParcelFileDescriptor fd;
    try {

        fd = this.getContentResolver().openFileDescriptor(uri, "r");
        // Your Complex Code and you used function without loop so how can you get all Contacts Vcard.??/* FileInputStream fis = fd.createInputStream();
        byte[] buf = new byte[(int) fd.getDeclaredLength()];
        fis.read(buf);
        String VCard = new String(buf);
        String path = Environment.getExternalStorageDirectory().toString() + File.separator + vfile;
        FileOutputStream out = new FileOutputStream(path);
        out.write(VCard.toString().getBytes());
        Log.d("Vcard",  VCard);*/FileInputStreamfis=newFileInputStream(fd.getFileDescriptor());
        byte[] buf = newbyte[fis.available()];
        fis.read(buf);
        Stringvcardstring=newString(buf);
        vCard.add(vcardstring);

        Stringstorage_path= Environment.getExternalStorageDirectory().toString() + File.separator + vfile;
        FileOutputStreammFileOutputStream=newFileOutputStream(storage_path, false);
        mFileOutputStream.write(vcardstring.toString().getBytes());
    } catch (Exception e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
}
}

Solution 3:

In Android Nougat :

byte[] b = newbyte[(int)fd.getDeclaredLength()];

fd.getDeclaredLength() return -1.

Check my answer here link.

Solution 4:

replace this

AssetFileDescriptorassetFileDescriptor= activity.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStreamfis= assetFileDescriptor.createInputStream();
byte[] buf = newbyte[(int) assetFileDescriptor.getDeclaredLength()];

with this

AssetFileDescriptorassetFileDescriptor= activity.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStreamfis= assetFileDescriptor.createInputStream();
byte[] buf = newbyte[fis.available()];

Post a Comment for "In Android 7, Contentresolver's Method-openassetfiledescriptor(vcarduri, "r") Returns Assetfiledescriptor Having Declaredlength As -1"