<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Iurii Dorofeev</title>
    <description>The latest articles on DEV Community by Iurii Dorofeev (@otopba).</description>
    <link>https://dev.to/otopba</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F451352%2Faa7052d6-d3d9-4c34-ab86-3857b4ddd268.jpeg</url>
      <title>DEV Community: Iurii Dorofeev</title>
      <link>https://dev.to/otopba</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/otopba"/>
    <language>en</language>
    <item>
      <title>Flutter Plugin For Importing Stickers Into Telegram</title>
      <dc:creator>Iurii Dorofeev</dc:creator>
      <pubDate>Wed, 30 Jun 2021 08:55:47 +0000</pubDate>
      <link>https://dev.to/otopba/flutter-plugin-for-importing-stickers-into-telegram-43a9</link>
      <guid>https://dev.to/otopba/flutter-plugin-for-importing-stickers-into-telegram-43a9</guid>
      <description>&lt;p&gt;Telegram recently has announced a &lt;a href="https://t.me/contest/262"&gt;new contest&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Given&lt;/strong&gt;: a sticker import mechanism for Android and iOS apps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Task&lt;/strong&gt;: write an Android or iOS app that uses this mechanism.&lt;/p&gt;

&lt;p&gt;The timing is very limited, the deadline is the 4th of July. Objectively, I don't have time to write an app in such a short time. I decided to help the Flutter developers in this contest and write a plugin to work with the native SDK. The article will dwell on that.&lt;/p&gt;

&lt;p&gt;Let's see what kind of import mechanism Telegram offers us.&lt;/p&gt;

&lt;h2&gt;
  
  
  Android
&lt;/h2&gt;

&lt;p&gt;The official repository is &lt;a href="https://github.com/DrKLO/TelegramStickersImport"&gt;here&lt;/a&gt;. There is no SDK. To import stickers, you just need to send Intent with a set of parameters. What could be easier?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Intent&lt;/span&gt; &lt;span class="n"&gt;intent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Intent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;CREATE_STICKER_PACK_ACTION&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putExtra&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;EXTRA_STREAM&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stickers&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putExtra&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;CREATE_STICKER_PACK_IMPORTER_EXTRA&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;getPackageName&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;putExtra&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;CREATE_STICKER_PACK_EMOJIS_EXTRA&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;emojis&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"image/*"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difficulty is that you need to give permission to a third-party application so it can get access to any of your files (we are not considering the raw directory case). You can read more about file sharing between applications in &lt;a href="https://developer.android.com/training/secure-file-sharing/setup-sharing"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Use &lt;a href="https://developer.android.com/reference/androidx/core/content/FileProvider"&gt;FileProvider&lt;/a&gt; to allow access to your files. Basically, we describe which directories we want to give access to, and also describe the name that will hide the real path to the files.&lt;/p&gt;

&lt;p&gt;For simplicity, I've prepared one folder in the directory with the cache. In case if you want to use some other folder, you will need to configure the manifest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;...
&lt;span class="nt"&gt;&amp;lt;provider&lt;/span&gt;
    &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"androidx.core.content.FileProvider"&lt;/span&gt;
    &lt;span class="na"&gt;android:authorities=&lt;/span&gt;&lt;span class="s"&gt;"${applicationId}.provider"&lt;/span&gt;
    &lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
    &lt;span class="na"&gt;android:grantUriPermissions=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta-data&lt;/span&gt;
        &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.support.FILE_PROVIDER_PATHS"&lt;/span&gt;
        &lt;span class="na"&gt;android:resource=&lt;/span&gt;&lt;span class="s"&gt;"@xml/filepaths"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/provider&amp;gt;&lt;/span&gt;
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and add an xml file describing the available paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;paths&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;cache-path&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"telegram_stickers_import/"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"telegram_stickers_import"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/paths&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When used in this way, the path:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/data/user/0/com.otopba.telegram_stickers_import_example/cache/telegram_stickers_import/sticker1.webp&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Turns into:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;content://com.otopba.telegram_stickers_import_example.provider/telegram_stickers_import/sticker1.webp&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  iOS
&lt;/h2&gt;

&lt;p&gt;The official repository is &lt;a href="https://github.com/TelegramMessenger/TelegramStickersImport"&gt;here&lt;/a&gt;. Telegram provides SDK for iOS and has even made data validation with human-readable errors.&lt;/p&gt;

&lt;p&gt;You need to add a few lines to &lt;code&gt;Info.plist&lt;/code&gt; to make it work:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;key&amp;gt;&lt;/span&gt;LSApplicationQueriesSchemes&lt;span class="nt"&gt;&amp;lt;/key&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;array&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;string&amp;gt;&lt;/span&gt;tg&lt;span class="nt"&gt;&amp;lt;/string&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/array&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to use the plugin
&lt;/h2&gt;

&lt;p&gt;As expected, the plugin is as simple as possible: one method where you need to pass your stickerset for import:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TelegramStickersImport&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;/// Folder inside cache directory for store your stickers&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;androidImportFolderName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"telegram_stickers_import"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="n"&gt;MethodChannel&lt;/span&gt; &lt;span class="n"&gt;_channel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MethodChannel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;'telegram_stickers_import'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="o"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;/// Method for import sticker set&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Future&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;?&amp;gt;&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StickerSet&lt;/span&gt; &lt;span class="n"&gt;stickerSet&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;async&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_channel&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invokeMethod&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'import'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stickerSet&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toMap&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The nuance is in reading the sticker files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;to run the Android app, you will need to copy your stickers files to the &lt;code&gt;cache/telegram_stickers_import&lt;/code&gt; folder (or one that you set up by yourself);&lt;/li&gt;
&lt;li&gt;for the iOS application, you will need to read the contents of the stickers into the &lt;code&gt;Uint8List&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight dart"&gt;&lt;code&gt;&lt;span class="n"&gt;StickerData&lt;/span&gt;&lt;span class="o"&gt;({&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;/// Android factory&lt;/span&gt;
&lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;StickerData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;android&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;StickerData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;path:&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;/// iOS factory&lt;/span&gt;
&lt;span class="kd"&gt;factory&lt;/span&gt; &lt;span class="n"&gt;StickerData&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;iOS&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Uint8List&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;StickerData&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;bytes:&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;It's strange that Telegram made an SDK only for iOS, and Android developers, as always, should do their rain dance. &lt;/p&gt;

&lt;p&gt;I will be glad if you use &lt;a href="https://github.com/otopba/telegram_stickers_import"&gt;my plugin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm looking forward to the Pull Requests.&lt;/p&gt;

&lt;p&gt;Ciao!&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>telegram</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
