Skip to content

Commit 657a0f3

Browse files
committed
Add video sharing support
1 parent ea5be3d commit 657a0f3

6 files changed

Lines changed: 268 additions & 134 deletions

File tree

LICENSE

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,7 @@
1-
TODO: place your license here and we'll include it in the module distribution
1+
Copyright (c) 2025 Douglas Alves
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4+
5+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 117 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
11
# Ti.Android.Share
22

3-
A native Android module for Titanium SDK that provides seamless image and text sharing using Android's FileProvider API.
3+
A native Android module for Titanium SDK that provides seamless image, video and text sharing using Android's FileProvider API.
44

55
![Titanium](https://img.shields.io/badge/Titanium-13.0+-red.svg) ![Platform](https://img.shields.io/badge/platform-Android-lightgrey.svg) ![License](https://img.shields.io/badge/license-MIT-blue.svg) ![Maintained](https://img.shields.io/badge/Maintained-Yes-green.svg)
66

77
## Overview
88

9-
This module solves a critical limitation in Titanium SDK when sharing images on Android 7.0+ (API 24+). Modern Android versions require the use of `content://` URIs through FileProvider instead of `file://` URIs for security reasons. While Titanium SDK provides intent-based sharing capabilities, it lacks native FileProvider support, making image sharing problematic with apps like WhatsApp, Telegram, and email clients.
9+
This module solves a limitation in Titanium SDK when sharing images and videos on Android 7.0+ (API 24+). Modern Android versions require the use of `content://` URIs through FileProvider instead of `file://` URIs for security reasons. While Titanium SDK provides intent-based sharing capabilities, it lacks native FileProvider support, making media sharing problematic with apps like WhatsApp, Telegram, and email clients.
1010

11-
`ti.android.share` bridges this gap by providing a simple JavaScript API that handles all the complexity of FileProvider configuration, URI generation, and secure file sharing.
11+
`ti.android.share` bridges this gap by providing a simple JavaScript API that handles all the complexity of FileProvider configuration, URI generation, and secure file sharing for both images and videos.
1212

1313
## Features
1414

15-
- Share images from URLs, Resources, Blobs, or file paths
16-
- Automatic image download from remote URLs
17-
- Automatic FileProvider URI generation
18-
- Support for text and image combination sharing
19-
- Optional callback to handle share results (success, cancelled, or error)
20-
- Works with WhatsApp, Telegram, Email, and all Android share targets
21-
- Compatible with Titanium SDK 13.x and modern Android versions
15+
- Share text, images and videos from URLs, Resources, Blobs, or file paths
16+
- Automatic media type detection (image vs video)
17+
- Automatic media download from remote URLs
18+
- Support for popular video formats: MP4, MOV, AVI, 3GP, MKV, WEBM, FLV, M4V
19+
- Automatic FileProvider URI generation
20+
- Support for text and media combination sharing
21+
- File size validation and warnings (100MB limit for downloads)
22+
- Optional callback to handle share results (success, cancelled, or error)
23+
- Works with WhatsApp, Telegram, Email, and all Android share targets
24+
- Compatible with Titanium SDK 13.x and modern Android versions
2225

2326
## Requirements
2427

@@ -59,48 +62,72 @@ The module will use `com.yourcompany.yourapp.fileprovider` as the FileProvider a
5962
```javascript
6063
const ShareModule = require('ti.android.share');
6164

65+
// Share media
6266
ShareModule.share({
6367
message: "Check out this amazing content!",
6468
subject: "Sharing from my app",
6569
image: "/images/photo.jpg"
6670
});
67-
```
68-
69-
### Share image from Resources
7071

71-
```javascript
72+
// Share video
7273
ShareModule.share({
73-
message: "Look at this picture!",
74-
image: "/images/my-image.png"
74+
message: "Watch this!",
75+
subject: "Cool video",
76+
media: "/videos/demo.mp4"
7577
});
7678
```
7779

7880
### Share image from Blob
7981

8082
```javascript
83+
// Share image blob
8184
const imageView = Ti.UI.createImageView({
82-
image: 'https://example.com/image.jpg'
85+
media: 'https://example.com/image.jpg'
8386
});
8487

85-
// After image loads
8688
imageView.addEventListener('load', function() {
8789
ShareModule.share({
8890
message: "Sharing dynamically loaded image",
89-
image: imageView.toBlob()
91+
media: imageView.toBlob()
9092
});
9193
});
9294
```
9395

94-
### Share image from URL
96+
### Share video from File System
97+
```javascript
98+
// Share video file
99+
const videoFile = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, 'video.mp4');
100+
ShareModule.share({
101+
message: "My video",
102+
media: videoFile.read()
103+
});
104+
```
105+
106+
### Share media from URL
95107

96-
The module will automatically download the image in the background before sharing. If the download fails, it will share text only (or notify via callback if provided).
108+
The module will automatically download the media in the background before sharing. If the download fails, it will share text only (or notify via callback if provided).
97109

98110
```javascript
111+
// Share image from url
99112
ShareModule.share({
100113
message: "Check out this amazing photo!",
101114
subject: "Photo from the web",
102115
image: "https://www.example.com/photos/sunset.jpg"
103116
});
117+
118+
// Share video from url
119+
ShareModule.share({
120+
message: "Watch this awesome video!",
121+
subject: "Video to share",
122+
media: "https://www.example.com/videos/demo.mp4",
123+
callback: function(e) {
124+
if (e.success) {
125+
Ti.API.info("Video shared successfully!");
126+
} else {
127+
Ti.API.error("Share failed: " + e.message);
128+
}
129+
}
130+
});
104131
```
105132

106133
### Share text only
@@ -144,13 +171,16 @@ Opens the Android share dialog with the specified content.
144171
- `options` (Object): Configuration object with the following properties:
145172
- `message` (String, optional): Text content to share
146173
- `subject` (String, optional): Subject line for sharing (used by email apps)
147-
- `image` (String|TiBlob, optional): Image to share. Can be:
148-
- **URL** (e.g., `"https://example.com/photo.jpg"`) - Will be downloaded automatically
149-
- Path to resource file (e.g., `/images/photo.jpg`)
150-
- Path from applicationDataDirectory
151-
- TiBlob object (from `imageView.toBlob()`, camera, etc.)
174+
- `media` (String|TiBlob, optional): Media file to share (images or videos). Can be: - **URL** (e.g., `"https://example.com/video.mp4"`) - Will be downloaded automatically - Path to resource file (e.g., `/videos/demo.mp4` or `/images/photo.jpg`) - Path from applicationDataDirectory - TiBlob object (from file read, camera, video recorder, etc.)
175+
- `image` (String|TiBlob, optional): **Deprecated** - Use `media` instead. Still supported for backward compatibility
152176
- `callback` (Function, optional): Callback function to receive share result
153177

178+
**Supported Media Formats:**
179+
- **Images**: JPG, JPEG, PNG, GIF, WEBP
180+
- **Videos**: MP4, MOV, AVI, 3GP, MKV, WEBM, FLV, M4V
181+
182+
The module automatically detects the media type based on file extension.
183+
154184
**Callback object properties:**
155185

156186
- `success` (Boolean): `true` if share completed successfully, `false` if cancelled or failed
@@ -161,58 +191,82 @@ Opens the Android share dialog with the specified content.
161191

162192
**Returns:** void
163193

164-
**Example:**
165-
166-
```javascript
167-
ShareModule.share({
168-
message: "Hello World",
169-
subject: "Greeting",
170-
image: myImageBlob,
171-
callback: function(e) {
172-
console.log("Success: " + e.success);
173-
console.log("Message: " + e.message);
174-
}
175-
});
176-
```
177-
178194
## How it works
179195

180196
The module handles the following automatically:
181197

182-
1. **URL Detection**: Automatically detects if the image parameter is a URL (starts with `http://` or `https://`)
198+
1. **Media Type Detection**: Automatically detects whether the file is an image or video based on file extension
199+
- Images: JPG, PNG, GIF, WEBP
200+
- Videos: MP4, MOV, AVI, 3GP, MKV, WEBM, FLV, M4V
201+
202+
2. **URL Detection**: Automatically detects if the media parameter is a URL (starts with `http://` or `https://`)
183203

184-
2. **Image Download**: For URL images:
185-
- Downloads the image asynchronously in the background
186-
- Uses a 15-second timeout for connection and read operations
204+
3. **Media Download**: For URL media:
205+
- Downloads the file asynchronously in the background
206+
- Uses a 15-second timeout for images, 30-second timeout for videos
207+
- Validates file size (100MB limit for downloads)
187208
- Saves to the cache directory
188209
- If download fails, shares text only or notifies via callback
189210

190-
3. **Resource location**: For local files, attempts to find images in multiple locations:
211+
4. **Resource location**: For local files, attempts to find media in multiple locations:
191212
- Application resources (`/app/_app_/Resources/`)
192213
- Android assets
193214
- Application data directory
194215
- Cache directory
195216

196-
4. **File preparation**: For resource files and Blobs:
217+
5. **File preparation**: For resource files and Blobs:
197218
- Copies the file to the cache directory
219+
- Preserves original file extension
198220
- Ensures the file is accessible by the FileProvider
199221

200-
5. **URI generation**: Creates a secure `content://` URI using Android's FileProvider
222+
6. **URI generation**: Creates a secure `content://` URI using Android's FileProvider
201223

202-
6. **Permission granting**: Adds `FLAG_GRANT_READ_URI_PERMISSION` so receiving apps can access the file
224+
7. **Permission granting**: Adds `FLAG_GRANT_READ_URI_PERMISSION` so receiving apps can access the file
203225

204-
7. **Intent creation**: Builds a proper `ACTION_SEND` intent with all necessary flags
226+
8. **Intent creation**: Builds a proper `ACTION_SEND` intent with correct MIME type (`image/*` or `video/*`)
205227

206-
8. **Result handling**: When a callback is provided, uses `startActivityForResult` to capture the share outcome and notify your application
228+
9. **Result handling**: When a callback is provided, uses `startActivityForResult` to capture the share outcome and notify your application
207229

208230
## Troubleshooting
209231

210-
### URL image download issues
232+
### Video sharing issues
211233

212-
If images from URLs fail to download:
234+
**File size limitations:**
235+
236+
Different apps have different size limits for videos:
237+
- **WhatsApp**: ~16MB (approximately 2 minutes)
238+
- **Telegram**: 2GB (best for large videos)
239+
- **Email**: 10-25MB (depends on email provider)
240+
- **Instagram**: 60 seconds maximum duration
241+
- **Facebook**: 4GB / 240 minutes
242+
243+
**Recommendations:**
244+
- Keep videos under 16MB for maximum compatibility
245+
- Use Telegram for large video files
246+
- The module logs warnings when files exceed 100MB
247+
- Consider compressing videos before sharing
248+
249+
**Common issues:**
250+
- "File too large" error: Reduce video resolution or duration
251+
- "Format not supported": Ensure video is in MP4, MOV, or 3GP format
252+
- Download timeout: Videos larger than 50MB may timeout (30-second limit)
253+
254+
### URL media download issues
255+
256+
If media from URLs fails to download:
213257

214258
- Ensure the URL is publicly accessible (not behind authentication)
215-
- Check that the URL points directly to an image file (ends in .jpg, .png, etc.)
259+
- Check that the URL points directly to a media file (ends in .jpg, .mp4, etc.)
260+
- Verify your app has INTERNET permission in `tiapp.xml`:
261+
262+
```xml
263+
<uses-permission android:name="android.permission.INTERNET"/>
264+
```
265+
266+
- The module uses a 15-second timeout for images and 30-second timeout for videos
267+
- Files larger than 100MB will be rejected during download
268+
- Check `adb logcat` for HTTP response codes and error messages
269+
- If using HTTPS, ensure the server has valid SSL certificates
216270

217271
### Callback not firing
218272

@@ -223,32 +277,26 @@ The callback relies on Android's activity result system. Note that:
223277
- Some apps may not properly report back to the activity result system
224278
- The callback indicates the share was initiated, not necessarily that the recipient app completed the action
225279

226-
### Image not found error
280+
### Media not found error
227281

228-
If you see logs indicating the image wasn't found, verify:
282+
If you see logs indicating the media wasn't found, verify:
229283

230-
- The image path is correct (use `/images/photo.jpg`, not `images/photo.jpg`)
231-
- The image exists in your `Resources` folder or specified directory
284+
- The media path is correct (use `/images/photo.jpg` or `/videos/demo.mp4`, not `images/photo.jpg`)
285+
- The file exists in your `Resources` folder or specified directory
232286
- Check the `adb logcat` output for detailed path information
287+
- For videos, ensure the file extension is included (.mp4, .mov, etc.)
233288

234-
### WhatsApp/Telegram not showing image
289+
### WhatsApp/Telegram not showing media
235290

236291
Ensure:
237292

238-
- The image file is a valid JPEG or PNG
239-
- The file size is reasonable (< 5MB recommended)
293+
- The file is a valid image (JPEG, PNG) or video (MP4, MOV, 3GP)
294+
- File size is within app limits (WhatsApp: ~16MB for videos, Telegram: 2GB)
240295
- Your app has necessary permissions in `tiapp.xml`:
241296

242297
```xml
243-
<!-- Necessária APENAS se você ler imagens de locais externos ao cache -->
244-
<!-- Only needed if you read images from external sources or cache -->
245-
<!-- Android 6 to 12 -->
246-
<uses-permission
247-
android:name="android.permission.READ_EXTERNAL_STORAGE"
248-
android:maxSdkVersion="32"/>
249-
250-
<!-- Android 13+ (replaced READ_EXTERNAL_STORAGE) -->
251-
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
298+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
299+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
252300
```
253301

254302
## Contributing
-106 KB
Binary file not shown.
108 KB
Binary file not shown.

android/manifest

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
# this is your module manifest and used by Titanium
33
# during compilation, packaging, distribution, etc.
44
#
5-
version: 1.0.2
5+
version: 1.0.3
66
apiversion: 4
77
architectures: arm64-v8a armeabi-v7a x86 x86_64
88
description: ti.android.share
9-
author: Your Name
9+
author: Douglas Alves
1010
license: Specify your license
11-
copyright: Copyright (c) 2025 by Your Company
11+
copyright: Copyright (c) 2025 by Douglas Alves
1212

1313
# these should not be edited
1414
name: ti.android.share

0 commit comments

Comments
 (0)