Android Question Sticker4W Lib: Problem creating sticker pack from External Storage

Ferdari

Active Member
Licensed User
Longtime User
Hi everyone, im using the @DonManfred Sticker4W library for creating sticker packs, but it only works with Assets files, is there a way to use or create on-the-fly a sticker pack from the External or Internal storage?

On the official Stickers GitHub they say it is the way:
Expose files that are stored internally as stickers through ContentProvider

If you would like to expose files saved internally or externally and serve these files as sticker. It is possible, but please follow the guidelines in 'Sticker art and app requirements' to make sure the files meets these requirements. As to how to do that, you can take a look at the following code snippet to get an understanding of how that can be done.

B4X:
private AssetFileDescriptor fetchFile(@NonNull Uri uri, @NonNull AssetManager am, @NonNull String fileName, @NonNull String identifier) throws IOException {

    final File cacheFile = getContext().getExternalCacheDir();

    final File file = new File(cacheFile, fileName);

    try (final InputStream open = am.open(identifier + "/" + fileName);

         final FileOutputStream fileOutputStream = new FileOutputStream(file)) {

         byte[] buffer = new byte[1024];

        int read;

        while ((read = in.read(buffer)) != -1) {

            out.write(buffer, 0, read);

        }

    }

    //The code above is basically copying the assets to storage, and servering the file off of the storage.

    //If you have the files already downloaded/fetched, you could simply replace above part, and initialize the file parameter with your own file which points to the desired file.

    //The key here is you can use ParcelFileDescriptor to create an AssetFileDescriptor.

    return new AssetFileDescriptor(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY), 0, AssetFileDescriptor.UNKNOWN_LENGTH);

}

Is there a way to implement this?

A practical use could be: Download an sticker pack and install from the app, or create and encode images saving it to External and then installing the Pack from the app.

Help would be very appreciated.
 

DonManfred

Expert
Licensed User
Longtime User
is there a way to use or create on-the-fly a sticker pack from the External or Internal storage?
No
The Provider is in the lib and it is using the files from assets.
 
Upvote 0

Ferdari

Active Member
Licensed User
Longtime User
o_O oh that was confusing, i see in some posts they created a second Provider to serve packs from storage, is it possible?

stickers from firebase
This post says how to create sticker packs dynamically:
dynamic-whatsapp-stickers-part-1-android-2ac00dc57111

I was programing the system but then found your Lib has no way to read sticker pack data or json file from other source rather than assets folder.

Are you planning to update your lib or can you guide me on how to create packs dynamically?

Thanks Don
 
Last edited:
Upvote 0

asales

Expert
Licensed User
Longtime User
Are you planning to update your lib or can you guide me on how to create packs dynamically?
I use this lib too and I'm very interested in this feature. If is not possible to made an upgrade, maybe @DonManfred could create/wrapper another library and I will to donate again.
 
Upvote 0

Ferdari

Active Member
Licensed User
Longtime User
@asales well, we need to look for other solutions, i was thinking on updating the JSON(append more packs) but the Assets folder is Read-Only, will be a challenge for us.
 
Upvote 0

Ferdari

Active Member
Licensed User
Longtime User
Edit the json and update your files. Then upload a new apk which then contains the new Sticker.
i already do that, but the process between updates are very long, not instantly, and not dynamic, maybe if you added a way to read a JSON file outside the assets. would be the way.
 
Upvote 0

Ferdari

Active Member
Licensed User
Longtime User
Oh that was sad 😢, i hope you can fix it soon, have you tried creating a second Provider?, some say they using a second provider for cloud stickers.

 
Upvote 0

Ferdari

Active Member
Licensed User
Longtime User
Upvote 0

Ferdari

Active Member
Licensed User
Longtime User
There is no complete code! Maybe i did not see it? I already read that tutorials.
On Whatsap official stickers github, they say they way to use external files as stickers:
https://github.com/WhatsApp/sticker...nternally-as-stickers-through-contentprovider

I readed carefully every article and i understood that the external file should be pointed on the:
AssetFileDescriptor fetchFile(...)
The external image file URI on fetchFile
Java:
//The key here is you can use ParcelFileDescriptor to create an AssetFileDescriptor.
new AssetFileDescriptor(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY), 0, AssetFileDescriptor.UNKNOWN_LENGTH);

But first i see they creating the virtual sticker pack dynamically in this classes:
2 classes

Im not sure but i think you need to add a way to fill that information
StickerPack:
class StickerPack implements Parcelable {
    String identifier;
    String name;
    String publisher;
    String trayImageFile;
    final String publisherEmail;
    final String publisherWebsite;
    final String privacyPolicyWebsite;
    final String licenseAgreementWebsite;

    String iosAppStoreLink;
    private List<Sticker> stickers;
    private long totalSize;
    String androidPlayStoreLink;
    private boolean isWhitelisted;

    StickerPack(String identifier, String name, String publisher, String trayImageFile, String publisherEmail, String publisherWebsite, String privacyPolicyWebsite, String licenseAgreementWebsite) {
        this.identifier = identifier;
        this.name = name;
        this.publisher = publisher;
        this.trayImageFile = trayImageFile;
        this.publisherEmail = publisherEmail;
        this.publisherWebsite = publisherWebsite;
        this.privacyPolicyWebsite = privacyPolicyWebsite;
        this.licenseAgreementWebsite = licenseAgreementWebsite;
       }
    }
 
Upvote 0

Ferdari

Active Member
Licensed User
Longtime User
Reading more i got this on:
StickerContentProvider.java

Line 54
B4X:
private static final String CONTENT_FILE_NAME = "contents.json";

You should change to the desired file, string, json map, etc.

Then it are read on line 148:
Java:
    private synchronized void readContentFile(@NonNull Context context) {
        try (InputStream contentsInputStream = context.getAssets().open(CONTENT_FILE_NAME)) {
            stickerPackList = ContentFileParser.parseStickerPacks(contentsInputStream);
        } catch (IOException | IllegalStateException e) {
            throw new RuntimeException(CONTENT_FILE_NAME + " file has some issues: " + e.getMessage(), e);
        }
    }

Then parsed on class:
ContentFileParser.java
 
Upvote 0
Top