forked from xsawyerx/perl-android-scripts
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added 'gps_send_message.pl' and 'sms_search.pl' to the examples direc…
…tory for future reference. It should be noted that 'sms_search.pl' is currently broken while utf8.pm is missing. This is a known issue and is being discussed here: http://code.google.com/p/android-scripting/issues/detail?id=108
- Loading branch information
Showing
2 changed files
with
304 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,210 @@ | ||
#!/data/data/com.google.ase/perl/perl | ||
# | ||
# Copyright 2010 Alex Elder (http://www.alexelder.co.uk) | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
# use this file except in compliance with the License. You may obtain a copy of | ||
# the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
# License for the specific language governing permissions and limitations under | ||
# the License. | ||
# | ||
# A simple Perl script designed to run under the Android Scripting Environment: | ||
# http://code.google.com/p/android-scripting. Designed to dispatch a text | ||
# message when the phone's position matches the position entered by the user. | ||
# For best results, start this program as a service. | ||
# | ||
# Text messages support 'tags' which are substituted for values before the | ||
# message is sent. Currently supported tags are: | ||
# | ||
# admin_area | ||
# country_code | ||
# country_name | ||
# feature_name | ||
# locality | ||
# postal_code | ||
# thoroughfare | ||
# sub_admin_area | ||
# map_link | ||
# | ||
# All tags must start and end with a '%' (percentage) sign. For example, | ||
# if you would like to send a message as soon as you entered Cheshire to a | ||
# chosen contact, and within that message you'd like to embed your current | ||
# county and a Google Maps link, you could enter something similar to: | ||
# | ||
# "Hi, I'm just entering %admin_area% now; link: %map_link%. See you soon!" | ||
# | ||
# The tags in the above example would be substituted for their actual values: | ||
# | ||
# "Hi, I'm just entering Cheshire now; link: | ||
# http://maps.google.com/maps?q=53.800651,-4.064941. See you soon!" | ||
# | ||
use strict; | ||
use warnings; | ||
|
||
use Android; | ||
use Carp; | ||
|
||
use constant { | ||
LOOP_DELAY => 180, # seconds to sleep between checking GPS position | ||
MAX_ATTEMPTS => 250, # number of match-loop iterations before giving up | ||
SPEAK_ON_SEND => 1, # speak using TTS when the message is sent | ||
MAP_LINK => 'http://maps.google.com/maps?q=%s,%s', # map link (message 'tag') | ||
}; | ||
|
||
my $droid = Android->new(); | ||
|
||
$droid->makeToast('Select a contact'); | ||
|
||
my $contact; | ||
|
||
# Select a contact | ||
$contact = $droid->pickPhone(); | ||
|
||
if ( ! defined $contact->{result} ) { | ||
|
||
$droid->makeToast('Please select a contact'); | ||
$contact = $droid->pickPhone(); | ||
|
||
exit if defined $contact->{error}; | ||
} | ||
|
||
$contact = $contact->{result}; | ||
|
||
# Enter a message for the chosen contact | ||
my $message_to_contact = $droid->getInput('Message', 'Message to selected contact'); | ||
|
||
if ( defined $message_to_contact->{error} || ! defined $message_to_contact->{result} ) { | ||
|
||
$droid->makeToast('No message entered. Please enter a message.'); | ||
$message_to_contact = $droid->getInput('Message', 'Message to be sent to contact upon arrival'); | ||
|
||
exit if defined $message_to_contact->{error} || ! defined $message_to_contact->{result}; | ||
} | ||
|
||
$message_to_contact = $message_to_contact->{result}; | ||
|
||
# Message authors can embed 'tags' that are substituted before a message is sent | ||
# to the chosen contact. The tag start and end markers are '%' and '%' | ||
# respectively. | ||
my @gps_keys = qw/ | ||
admin_area | ||
country_code | ||
country_name | ||
feature_name | ||
locality | ||
postal_code | ||
thoroughfare | ||
sub_admin_area | ||
/; | ||
|
||
# Create a dialog and present it to the user. They need to select which area | ||
# they'd like their location matched against. This is a potential 'non-slick' as | ||
# it'd be much nicer to use a Maps instance and geocode a screen tap, rather | ||
# than asking for someone to enter text. However, seems the Map application | ||
# starts itself in a new task when launched, making is *very* hard to get the | ||
# return value. For more information, please read: http://bit.ly/a7krNU. | ||
|
||
# Create a UI component and force the user to select a GPS zone to match on: | ||
$droid->dialogCreateAlert('Match location using...'); | ||
$droid->dialogSetItems(\@gps_keys); | ||
$droid->dialogShow(); | ||
|
||
my $match_key = $droid->dialogGetResponse(); | ||
|
||
exit if ! defined $match_key->{result}->{item}; | ||
|
||
if ( $match_key->{result}->{item} >= 0 && $match_key->{result}->{item} <= scalar @gps_keys ) { | ||
$match_key = $gps_keys[$match_key->{result}->{item}]; | ||
} | ||
else { | ||
# use the first element in the allowed tags list as the default matching method | ||
$match_key = $gps_keys[0]; | ||
} | ||
|
||
# Add the 'map_link' here, rather than above because the map link isn't a GPS | ||
# result - however it is a valid substitution tag, used for inserting a Google | ||
# Maps URI. | ||
push @gps_keys, 'map_link'; | ||
|
||
# Enter destination | ||
my $destination = $droid->getInput('Destination', 'Please enter your destination'); | ||
|
||
if ( defined $destination->{error} || ! defined $destination->{result} ) { | ||
|
||
$droid->makeToast('No destination entered. Please enter a destination.'); | ||
$destination = $droid->getInput('Destination', 'Please enter your destination'); | ||
|
||
exit if defined $destination->{error} || ! defined $destination->{result}; | ||
} | ||
|
||
$destination = $destination->{result}; | ||
|
||
# When using the selected text input, the input keyboard will often suggest a | ||
# word and add a space after the selected word, so remove any trailing whitespace | ||
# here for convenience. | ||
$destination =~ s/\s+$//; | ||
|
||
# Keep a count of how many times the script's looped around while attempting to | ||
# find a match. | ||
my $attempts = 0; | ||
|
||
my ($location, $longitude, $latitude, $geocode); | ||
|
||
$droid->startLocating(); | ||
|
||
# give the GPS sensor a chance to wake up | ||
sleep 15; | ||
|
||
CHECK_LOCATION: | ||
while ( $attempts++ <= MAX_ATTEMPTS ) { | ||
|
||
$location = $droid->readLocation() || $droid->getLastKnownLocation(); | ||
|
||
if ( defined $location->{error} ) { | ||
|
||
print STDERR "location error: $location->{error}\n"; | ||
next CHECK_LOCATION; | ||
} | ||
|
||
$longitude = $location->{result}->{network}->{longitude}; | ||
$latitude = $location->{result}->{network}->{latitude}; | ||
|
||
$geocode = $droid->geocode($latitude, $longitude); | ||
|
||
if ( defined $geocode->{error} ) { | ||
|
||
print STDERR "geocode error: $geocode->{error}\n"; | ||
next CHECK_LOCATION; | ||
} | ||
|
||
foreach my $address ( @{ $geocode->{result} } ) { | ||
|
||
if ( $address->{$match_key} =~ /$destination/i ) { | ||
|
||
# add a maps link to the address hash | ||
my $map_link = sprintf(MAP_LINK, $latitude, $longitude); | ||
$address->{map_link} = $map_link; | ||
|
||
# replace special tags in the input messages | ||
$message_to_contact =~ s/%*$_*%/$address->{$_}/g for @gps_keys; | ||
|
||
print "successfully matched $address->{$match_key} against $destination\n"; | ||
print "sending: '$message_to_contact' to contact $contact\n"; | ||
|
||
$droid->smsSend($contact, $message_to_contact); | ||
$droid->speak("Message sent to contact after $attempts attempts.") if SPEAK_ON_SEND == 1; | ||
|
||
last CHECK_LOCATION; | ||
} | ||
} | ||
|
||
sleep LOOP_DELAY; | ||
} | ||
|
||
exit; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#!/data/data/com.google.ase/perl/perl | ||
# | ||
# Copyright 2010 Alex Elder (http://www.alexelder.co.uk) | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
# use this file except in compliance with the License. You may obtain a copy of | ||
# the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
# License for the specific language governing permissions and limitations under | ||
# the License. | ||
# | ||
# A simplistic example, demonstrating how to implement a simple search tool | ||
# using ASE and Perl. | ||
# | ||
use strict; | ||
use warnings; | ||
|
||
use Android; | ||
use Carp; | ||
use Data::Dumper; | ||
|
||
use constant { | ||
INPUT_TITLE => 'Search String', | ||
INPUT_MESSAGE => 'Enter a search string or Perl regex:', | ||
}; | ||
|
||
my $droid = Android->new(); | ||
my $messages = $droid->smsGetMessages(0, 'inbox', ['body', 'thread_id']); | ||
|
||
croak "Unable to retreive SMS messages" if defined $messages->{error}; | ||
|
||
my $search_string = $droid->getInput(INPUT_TITLE, INPUT_MESSAGE); | ||
|
||
if ( defined $search_string->{error} ) { | ||
|
||
$droid->makeToast('No search string entered; try again...'); | ||
$search_string = $droid->getInput(INPUT_TITLE, INPUT_MESSAGE); | ||
|
||
exit if defined $search_string->{error}; | ||
} | ||
|
||
$search_string = qr/$search_string->{result}/; | ||
|
||
my @matches; | ||
|
||
foreach my $message ( @{ $messages->{result} } ) { | ||
|
||
if ( $message->{body} =~ $search_string ) { | ||
|
||
push @matches, $message; | ||
} | ||
} | ||
|
||
if ( ! @matches ) { | ||
|
||
$droid->makeToast("No matches found for '$search_string'"); | ||
exit; | ||
} | ||
else { | ||
|
||
$droid->makeToast("Found " . scalar @matches . " matches!"); | ||
} | ||
|
||
# Extract just the body part from each message and display it on the UI using | ||
# the index within @matches as the return ID from the UI component: | ||
$droid->dialogCreateAlert('Search Results'); | ||
$droid->dialogSetItems([ map { $_->{body} } @matches ] ); | ||
$droid->dialogShow(); | ||
|
||
my $selected_search_result = $droid->dialogGetResponse(); | ||
|
||
if ( defined $selected_search_result->{error} ) { | ||
|
||
$droid->makeToast('Invalid choice; exiting'); | ||
$droid->exit(); | ||
} | ||
else { | ||
$selected_search_result = $selected_search_result->{result}->{item}; | ||
} | ||
|
||
my $sms_thread_id = $matches[$selected_search_result]->{thread_id}; | ||
|
||
# FIXME: This needs addressing. Currently, the below URI will navigate to the | ||
# correct message thread, however it will not navigate to the correct message | ||
# *within* the given thread. I'm not too sure how to do this, and it doesn't | ||
# seem to be too well documented. | ||
$droid->startActivity('android.intent.action.VIEW', "sms://view/conversations/$sms_thread_id"); | ||
|
||
$droid->exit(); |