android/
android.rs

1// examples/android.rs
2// Example: Send notifications to Growl for Android with retry
3//
4// Run with: cargo run --example android
5
6use gntp::{GntpClient, NotificationType, Resource, IconMode, NotifyOptions};
7use std::env;
8
9fn main() -> Result<(), Box<dyn std::error::Error>> {
10    println!("=== Growl for Android Example ===\n");
11    
12    // Get Android device IP from environment
13    let android_host = env::var("ANDROID_HOST")
14        .unwrap_or_else(|_| {
15            println!("⚠ ANDROID_HOST not set, using default");
16            println!("  Set with: set ANDROID_HOST=192.168.1.100\n");
17            "192.168.1.100".to_string()
18        });
19    
20    println!("Target Android device: {}", android_host);
21    
22    // Create client optimized for Android
23    let mut client = GntpClient::new("Android Example")
24        .with_host(&android_host)
25        .with_port(23053)
26        .with_icon_mode(IconMode::DataUrl) // Best for Android
27        .with_debug(false);
28    
29    // Try to load icon (optional)
30    let icon = match Resource::from_file("icon.png") {
31        Ok(icon) => {
32            println!("✓ Icon loaded: icon.png");
33            Some(icon)
34        }
35        Err(_) => {
36            println!("ℹ No icon found (optional)");
37            None
38        }
39    };
40    
41    // Define notification type with icon
42    let mut notification = NotificationType::new("android")
43        .with_display_name("Android Notification");
44    
45    if let Some(icon) = icon {
46        notification = notification.with_icon(icon);
47        println!("✓ Icon attached to notification");
48    }
49    
50    println!();
51    
52    // Register with retry (Android may need retry due to network)
53    println!("Registering with Growl for Android...");
54    let mut register_ok = false;
55    
56    for attempt in 1..=3 {
57        match client.register(vec![notification.clone()]) {
58            Ok(_) => {
59                println!("✓ Registered successfully{}\n", 
60                    if attempt > 1 { format!(" (attempt {})", attempt) } else { String::new() });
61                register_ok = true;
62                break;
63            }
64            Err(e) => {
65                if attempt < 3 {
66                    println!("⚠ Attempt {} failed, retrying... ({})", attempt, e);
67                    std::thread::sleep(std::time::Duration::from_secs(2));
68                } else {
69                    eprintln!("❌ Registration failed after 3 attempts: {}", e);
70                    eprintln!("\nTroubleshooting:");
71                    eprintln!("  1. Is Growl for Android running?");
72                    eprintln!("  2. Is {} the correct IP address?", android_host);
73                    eprintln!("  3. Are both devices on the same network?");
74                    eprintln!("  4. Check Android firewall settings");
75                    return Err(e.into());
76                }
77            }
78        }
79    }
80    
81    if !register_ok {
82        return Err("Registration failed".into());
83    }
84    
85    // Send notification with options
86    println!("Sending notification...");
87    let options = NotifyOptions::new()
88        .with_sticky(false) // Don't make it sticky on mobile
89        .with_priority(1);  // High priority
90    
91    match client.notify_with_options(
92        "android",
93        "Hello Android!",
94        "This notification was sent from Rust",
95        options
96    ) {
97        Ok(_) => {
98            println!("✓ Notification sent\n");
99            println!("✅ Check your Android device for the notification!");
100        }
101        Err(e) => {
102            eprintln!("❌ Failed to send: {}", e);
103            return Err(e.into());
104        }
105    }
106    
107    Ok(())
108}