Search code examples
androidxmlandroid-vectordrawable

Is it possible to create a VectorDrawable from File System (*.xml File)


I am trying to use VectorDrawables in my Android App.
I want to load an xml File from the File System and get an Instance of android.graphics.Drawable to display it in an ImageView. If i add the xml File to the Resources directory it works. But when i try to load it from the filesystem i always get a NullPointer.

I am currently trying to load the File via Drawable.createFromPath(*Path to File*) or VectorDrawable.createFromPath(*Path to File*), but i keep getting a NullPointer. The File exists and is a valid xml File (see below).

In adb log i always get :

SkImageDecoder::Factory returned null

When i use mContext.getFilesDir() the Path looks something like

/data/data/*packagename*/files/*filename*.xml

I also tried some public Folders like "Downloads". When i check the File with the File.io Api it exists(), canRead() and canWrite()

Update This ist the XML Code taken from the android Dev Pages

 <vector xmlns:android="http://schemas.android.com/apk/res/android"
 android:height="64dp"
 android:width="64dp"
 android:viewportHeight="600"
 android:viewportWidth="600" >
 <group
     android:name="rotationGroup"
     android:pivotX="300.0"
     android:pivotY="300.0"
     android:rotation="45.0" >
     <path
         android:name="v"
         android:fillColor="#000000"
         android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
 </group>


Solution

  • Unfortunately, no. Not unless you somehow compile the XML source file in the way that resources are compiled. VectorDrawable currently assumes a compiled image source.

    Otherwise you could probably have written something like this:

    VectorDrawable d = new VectorDrawable();
    try( InputStream in = new FileInputStream( *Path to File* ); )
    {
        XmlPullParser p = Xml.newPullParser();
        p.setInput( in, /*encoding, self detect*/null );
        d.inflate( getResources(), p, Xml.asAttributeSet(p) ); // FAILS
    }
    

    Currently that fails (API level 23, Marshmallow 6.0) because the inflate call attempts to cast the attribute set to an XmlBlock.Parser, which throws a ClassCastException. The cause is documented in the source; it will “only work with compiled XML files”, such as resources packaged by the aapt tool.