r49 - in branches: . widget widget/res/values widget/res/values-fr widget/res/xml widget/src/org/chorem/android/saymytexts
Author: kmorin Date: 2014-05-08 22:47:27 +0200 (Thu, 08 May 2014) New Revision: 49 Url: http://forge.chorem.org/projects/say-my-texts/repository/revisions/49 Log: branche to create the widget later Added: branches/widget/ branches/widget/AndroidManifest.xml branches/widget/pom.xml branches/widget/res/values-fr/arrays.xml branches/widget/res/values-fr/strings.xml branches/widget/res/values/arrays.xml branches/widget/res/values/preference_keys.xml branches/widget/res/values/strings.xml branches/widget/res/xml/preferences.xml branches/widget/src/org/chorem/android/saymytexts/DictateSmsBroadcastReceiver.java branches/widget/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java branches/widget/src/org/chorem/android/saymytexts/SayMyTextService.java branches/widget/src/org/chorem/android/saymytexts/SayMyTextsWidgetProvider.java branches/widget/src/org/chorem/android/saymytexts/SayNextActionBroadcastReceiver.java branches/widget/src/org/chorem/android/saymytexts/SettingsActivity.java Removed: branches/widget/AndroidManifest.xml branches/widget/pom.xml branches/widget/res/values-fr/strings.xml branches/widget/res/values/preference_keys.xml branches/widget/res/values/strings.xml branches/widget/res/xml/preferences.xml branches/widget/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java branches/widget/src/org/chorem/android/saymytexts/SayMyTextService.java branches/widget/src/org/chorem/android/saymytexts/SayMyTextsWidgetProvider.java branches/widget/src/org/chorem/android/saymytexts/SettingsActivity.java Deleted: branches/widget/AndroidManifest.xml =================================================================== --- trunk/AndroidManifest.xml 2014-04-02 11:59:25 UTC (rev 40) +++ branches/widget/AndroidManifest.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -1,67 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.chorem.android.saymytexts" - android:versionCode="3" - android:versionName="1.2" - android:description="@string/app_description" - android:installLocation="auto"> - - <uses-sdk android:minSdkVersion="15" - android:targetSdkVersion="17"/> - - <uses-permission android:name="android.permission.RECEIVE_SMS" /> - <uses-permission android:name="android.permission.SEND_SMS"/> - <uses-permission android:name="android.permission.READ_PHONE_STATE" /> - <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> - <uses-permission android:name="android.permission.READ_CONTACTS" /> - <uses-permission android:name="android.permission.BLUETOOTH" /> - <uses-permission android:name="android.permission.RECORD_AUDIO" /> - <uses-permission android:name="android.permission.CALL_PHONE" /> - - <uses-feature android:name="android.hardware.telephony" android:required="true"/> - - <supports-screens android:smallScreens="true"/> - - <application android:name=".SayMyTextsApplication" - android:label="@string/app_name" - android:icon="@drawable/logo" - android:description="@string/app_description"> - - <activity android:name=".SettingsActivity" - android:label="@string/app_name" - android:launchMode="singleTop"> - <intent-filter> - <action android:name="android.intent.action.MAIN"/> - <category android:name="android.intent.category.LAUNCHER"/> - </intent-filter> - </activity> - - <service android:name=".SayMyTextService"/> - - <receiver android:name=".NewTextBroadcastReceiver" - android:enabled="true"> - <intent-filter> - <action android:name="android.provider.Telephony.SMS_RECEIVED" /> - <action android:name="android.bluetooth.device.action.ACL_CONNECTED" /> - <action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" /> - <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" /> - </intent-filter> - </receiver> - - <!-- Crash report dialog--> - <activity android:name="org.acra.CrashReportDialog" - android:theme="@android:style/Theme.Holo.Dialog" - android:launchMode="singleInstance" - android:excludeFromRecents="true" - android:finishOnTaskLaunch="true" /> - - <receiver android:name=".SayMyTextsWidgetProvider" > - <intent-filter> - <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> - </intent-filter> - <meta-data android:name="android.appwidget.provider" - android:resource="@xml/say_my_texts_widget_info" /> - </receiver> - - </application> -</manifest> Copied: branches/widget/AndroidManifest.xml (from rev 48, trunk/AndroidManifest.xml) =================================================================== --- branches/widget/AndroidManifest.xml (rev 0) +++ branches/widget/AndroidManifest.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.chorem.android.saymytexts" + android:versionCode="3" + android:versionName="1.2" + android:description="@string/app_description" + android:installLocation="auto"> + + <uses-sdk android:minSdkVersion="15" + android:targetSdkVersion="17"/> + + <uses-permission android:name="android.permission.RECEIVE_SMS" /> + <uses-permission android:name="android.permission.SEND_SMS"/> + <uses-permission android:name="android.permission.READ_PHONE_STATE" /> + <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> + <uses-permission android:name="android.permission.READ_CONTACTS" /> + <uses-permission android:name="android.permission.BLUETOOTH" /> + <uses-permission android:name="android.permission.RECORD_AUDIO" /> + <uses-permission android:name="android.permission.CALL_PHONE" /> + + <uses-feature android:name="android.hardware.telephony" android:required="true"/> + + <supports-screens android:smallScreens="true"/> + + <application android:name=".SayMyTextsApplication" + android:label="@string/app_name" + android:icon="@drawable/logo" + android:description="@string/app_description"> + + <activity android:name=".SettingsActivity" + android:label="@string/app_name" + android:launchMode="singleTop" + android:configChanges="orientation|screenSize|keyboardHidden"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + + <service android:name=".SayMyTextService"/> + + <receiver android:name=".NewTextBroadcastReceiver" + android:enabled="true"> + <intent-filter> + <action android:name="android.provider.Telephony.SMS_RECEIVED" /> + <action android:name="android.bluetooth.device.action.ACL_CONNECTED" /> + <action android:name="android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED" /> + <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" /> + </intent-filter> + </receiver> + + <!-- Crash report dialog--> + <activity android:name="org.acra.CrashReportDialog" + android:theme="@android:style/Theme.Holo.Dialog" + android:launchMode="singleInstance" + android:excludeFromRecents="true" + android:finishOnTaskLaunch="true" + android:configChanges="orientation|screenSize|keyboardHidden"/> + + <receiver android:name=".SayMyTextsWidgetProvider" > + <intent-filter> + <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> + </intent-filter> + <meta-data android:name="android.appwidget.provider" + android:resource="@xml/say_my_texts_widget_info" /> + </receiver> + + </application> +</manifest> Deleted: branches/widget/pom.xml =================================================================== --- trunk/pom.xml 2014-04-02 11:59:25 UTC (rev 40) +++ branches/widget/pom.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -1,419 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - #%L - WLO - %% - Copyright (C) 2013 - 2014 Ifremer - %% - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as - published by the Free Software Foundation, either version 3 of the - License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public - License along with this program. If not, see - <http://www.gnu.org/licenses/gpl-3.0.html>. - #L% - --> - -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> - <modelVersion>4.0.0</modelVersion> - - <parent> - <groupId>org.nuiton</groupId> - <artifactId>mavenpom4redmine</artifactId> - <version>5.0.1</version> - </parent> - - <groupId>org.chorem.android</groupId> - <artifactId>saymytexts</artifactId> - <version>1.2-SNAPSHOT</version> - <packaging>apk</packaging> - - <name>Say My Texts</name> - <description> - Android application which reads out loud the new SMS when the headset is plugged. Very useful when your are riding a bike or running. - </description> - <url>https://forge.chorem.org/projects/say-my-texts</url> - <inceptionYear>2014</inceptionYear> - <licenses> - <license> - <name>General Public License (GPL)</name> - <url>http://www.gnu.org/licenses/gpl.txt</url> - <distribution>repo</distribution> - </license> - </licenses> - - <developers> - <developer> - <id>morin</id> - <name>Kevin Morin</name> - <email>morin at codelutin dot com</email> - <organization>CodeLutin</organization> - <organizationUrl>http://www.codelutin.com</organizationUrl> - <roles> - <role>developer</role> - </roles> - <timezone>Europe/Paris</timezone> - </developer> - </developers> - - <scm> - <url>https://svn.chorem.org/say-my-texts</url> - <connection> - scm:svn:https://svn.chorem.org/say-my-texts/trunk - </connection> - <developerConnection> - scm:svn:https://svn.chorem.org/say-my-texts/trunk - </developerConnection> - </scm> - <distributionManagement> - <site> - <id>doc.${platform}</id> - <url>${our.site.repository}/${projectId}</url> - </site> - </distributionManagement> - - <properties> - - <!-- Java version --> - <javaVersion>1.7</javaVersion> - <signatureArtifactId>java17</signatureArtifactId> - <signatureVersion>1.0</signatureVersion> - - <platform>chorem.org</platform> - <projectId>say-my-texts</projectId> - <maven.test.skip>true</maven.test.skip> - <!-- locales for the site generation, by default only french --> - <locales>en,fr</locales> - - <!-- do not relatize links in generated site --> - <relativizeDecorationLinks>false</relativizeDecorationLinks> - - <!-- license header configuration --> - <license.organizationName>Code Lutin</license.organizationName> - <license.licenseName>gpl_v3</license.licenseName> - - <!-- Post Release configuration --> - <skipPostRelease>false</skipPostRelease> - - <sdkVersion>19.0.1</sdkVersion> - - </properties> - - <repositories> - <repository> - <id>saymytexts-public-group</id> - <url>https://nexus.nuiton.org/nexus/content/groups/say-my-texts-group/</url> - <snapshots> - <enabled>true</enabled> - <checksumPolicy>fail</checksumPolicy> - </snapshots> - <releases> - <enabled>true</enabled> - <checksumPolicy>fail</checksumPolicy> - </releases> - </repository> - </repositories> - - <pluginRepositories> - <pluginRepository> - <id>saymytexts-public-group</id> - <url>https://nexus.nuiton.org/nexus/content/groups/say-my-texts-group/</url> - <snapshots> - <enabled>true</enabled> - <checksumPolicy>fail</checksumPolicy> - </snapshots> - <releases> - <enabled>true</enabled> - <checksumPolicy>fail</checksumPolicy> - </releases> - </pluginRepository> - </pluginRepositories> - - <dependencies> - - <dependency> - <groupId>com.google.android</groupId> - <artifactId>android</artifactId> - <version>4.1.1.4</version> - <scope>provided</scope> - </dependency> - - <dependency> - <groupId>com.google.android</groupId> - <artifactId>android-test</artifactId> - <version>4.1.1.4</version> - <scope>test</scope> - </dependency> - - <dependency> - <groupId>ch.acra</groupId> - <artifactId>acra</artifactId> - <version>4.5.0</version> - </dependency> - - </dependencies> - - <build> - <sourceDirectory>src</sourceDirectory> - <resources> - <resource> - <directory>res</directory> - <filtering>false</filtering> - </resource> - </resources> - <plugins> - - <plugin> - <groupId>com.jayway.maven.plugins.android.generation2</groupId> - <artifactId>android-maven-plugin</artifactId> - <version>3.8.2</version> - <executions> - <execution> - <id>alignApk</id> - <phase>install</phase> - <goals> - <goal>zipalign</goal> - </goals> - </execution> - </executions> - <configuration> - <sdk> - <platform>16</platform> - </sdk> - <extractDuplicates>true</extractDuplicates> - <device>usb</device> - <zipalign> - <verbose>true</verbose> - <skip>false</skip> - <inputApk> - ${project.build.directory}/${project.artifactId}-${project.version}.apk - </inputApk> - <outputApk> - ${project.build.directory}/${project.artifactId}-${project.version}.apk - </outputApk> - </zipalign> - </configuration> - <extensions>true</extensions> - </plugin> - - <!-- plugin site --> - <plugin> - <artifactId>maven-site-plugin</artifactId> - <dependencies> - <dependency> - <groupId>org.nuiton.jrst</groupId> - <artifactId>doxia-module-jrst</artifactId> - <version>${jrstPluginVersion}</version> - </dependency> - </dependencies> - </plugin> - - </plugins> - </build> - - <reporting> - <excludeDefaults>true</excludeDefaults> - </reporting> - - <profiles> - - <profile> - <id>sign</id> - <activation> - <property> - <name>performRelease</name> - <value>true</value> - </property> - </activation> - <build> - <plugins> - <plugin> - <groupId>org.nuiton</groupId> - <artifactId>helper-maven-plugin</artifactId> - <executions> - <execution> - <id>get-keystore</id> - <goals> - <goal>share-server-secret</goal> - </goals> - <phase>prepare-package</phase> - <configuration> - <serverId>codelutin-keystore</serverId> - <privateKeyOut>jarsigner.keystore</privateKeyOut> - <passwordOut>jarsigner.storepass</passwordOut> - <usernameOut>jarsigner.alias</usernameOut> - <passphraseOut>jarsigner.keypass</passphraseOut> - </configuration> - </execution> - </executions> - </plugin> - - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-jarsigner-plugin</artifactId> - <executions> - <execution> - <id>signing</id> - <goals> - <goal>sign</goal> - </goals> - <phase>package</phase> - <inherited>true</inherited> - <configuration> - <includes> - <include>target/*.apk</include> - </includes> - <arguments> - <argument>-sigalg</argument><argument>MD5withRSA</argument> - <argument>-digestalg</argument><argument>SHA1</argument> - </arguments> - </configuration> - </execution> - </executions> - </plugin> - <plugin> - <groupId>com.jayway.maven.plugins.android.generation2</groupId> - <artifactId>android-maven-plugin</artifactId> - <inherited>true</inherited> - <configuration> - <sign> - <debug>false</debug> - </sign> - </configuration> - </plugin> - </plugins> - </build> - </profile> - - <profile> - <id>license-profile</id> - <activation> - <property> - <name>performRelease</name> - <value>true</value> - </property> - </activation> - - <build> - <defaultGoal>generate-resources</defaultGoal> - <plugins> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>license-maven-plugin</artifactId> - <executions> - <execution> - <id>update-file-header-on-pom</id> - <goals> - <goal>update-file-header</goal> - </goals> - <phase>generate-resources</phase> - <configuration> - <roots> - <root>${project.basedir}</root> - </roots> - <includes> - <include>pom.xml</include> - </includes> - <addSvnKeyWords>false</addSvnKeyWords> - <verbose>false</verbose> - </configuration> - </execution> - </executions> - </plugin> - </plugins> - </build> - </profile> - - <profile> - <id>reporting</id> - <activation> - <property> - <name>performRelease</name> - <value>true</value> - </property> - </activation> - - <reporting> - <plugins> - - <plugin> - <artifactId>maven-project-info-reports-plugin</artifactId> - <version>${projectInfoReportsPluginVersion}</version> - <reportSets> - <reportSet> - <reports> - <report>project-team</report> - <report>mailing-list</report> - <report>cim</report> - <report>issue-tracking</report> - <report>license</report> - <report>scm</report> - <report>dependencies</report> - <report>dependency-convergence</report> - <report>dependency-info</report> - <report>plugin-management</report> - <report>plugins</report> - <report>dependency-management</report> - <report>summary</report> - </reports> - </reportSet> - </reportSets> - </plugin> - - </plugins> - </reporting> - - </profile> - - <!-- This profile update license stuff with new goal update-file-header --> - <profile> - <id>update-file-header</id> - <activation> - <property> - <name>performRelease</name> - <value>true</value> - </property> - </activation> - - <properties> - <license.descriptor>src/license/project.xml</license.descriptor> - </properties> - <build> - <defaultGoal>process-resources</defaultGoal> - <plugins> - <plugin> - <groupId>org.codehaus.mojo</groupId> - <artifactId>license-maven-plugin</artifactId> - <executions> - <execution> - <id>update-file-header</id> - <goals> - <goal>update-file-header</goal> - </goals> - <configuration> - <addSvnKeyWords>true</addSvnKeyWords> - <excludes> - <exclude>**/i18n/*.properties</exclude> - <exclude>**/THIRD-PARTY.properties</exclude> - <!-- since sh scripts must begins by the line #!/bin/sh, - can not use the mojo for the mojo --> - <exclude>**/*.sh</exclude> - </excludes> - </configuration> - <phase>process-resources</phase> - </execution> - </executions> - </plugin> - </plugins> - </build> - </profile> - - </profiles> -</project> Copied: branches/widget/pom.xml (from rev 43, trunk/pom.xml) =================================================================== --- branches/widget/pom.xml (rev 0) +++ branches/widget/pom.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,425 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + WLO + %% + Copyright (C) 2013 - 2014 Ifremer + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public + License along with this program. If not, see + <http://www.gnu.org/licenses/gpl-3.0.html>. + #L% + --> + +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.nuiton</groupId> + <artifactId>mavenpom4redmine</artifactId> + <version>5.0.5</version> + </parent> + + <groupId>org.chorem.android</groupId> + <artifactId>saymytexts</artifactId> + <version>1.2-SNAPSHOT</version> + <packaging>apk</packaging> + + <name>Say My Texts</name> + <description> + Android application which reads out loud the new SMS when the headset is plugged. Very useful when your are riding a bike or running. + </description> + <url>https://forge.chorem.org/projects/say-my-texts</url> + <inceptionYear>2014</inceptionYear> + <licenses> + <license> + <name>General Public License (GPL)</name> + <url>http://www.gnu.org/licenses/gpl.txt</url> + <distribution>repo</distribution> + </license> + </licenses> + + <developers> + <developer> + <id>morin</id> + <name>Kevin Morin</name> + <email>morin at codelutin dot com</email> + <organization>CodeLutin</organization> + <organizationUrl>http://www.codelutin.com</organizationUrl> + <roles> + <role>developer</role> + </roles> + <timezone>Europe/Paris</timezone> + </developer> + </developers> + + <scm> + <url>https://svn.chorem.org/say-my-texts</url> + <connection> + scm:svn:https://svn.chorem.org/say-my-texts/trunk + </connection> + <developerConnection> + scm:svn:https://svn.chorem.org/say-my-texts/trunk + </developerConnection> + </scm> + <distributionManagement> + <site> + <id>doc.${platform}</id> + <url>${our.site.repository}/${projectId}</url> + </site> + </distributionManagement> + + <properties> + + <!-- Java version --> + <javaVersion>1.7</javaVersion> + <signatureArtifactId>java17</signatureArtifactId> + <signatureVersion>1.0</signatureVersion> + + <platform>chorem.org</platform> + <projectId>say-my-texts</projectId> + <maven.test.skip>true</maven.test.skip> + <!-- locales for the site generation, by default only french --> + <locales>en,fr</locales> + + <!-- do not relatize links in generated site --> + <relativizeDecorationLinks>false</relativizeDecorationLinks> + + <!-- license header configuration --> + <license.organizationName>Code Lutin</license.organizationName> + <license.licenseName>gpl_v3</license.licenseName> + + <!-- Post Release configuration --> + <skipPostRelease>false</skipPostRelease> + + <sdkVersion>19.0.1</sdkVersion> + + </properties> + + <repositories> + <repository> + <id>saymytexts-public-group</id> + <url>https://nexus.nuiton.org/nexus/content/groups/say-my-texts-group/</url> + <snapshots> + <enabled>true</enabled> + <checksumPolicy>fail</checksumPolicy> + </snapshots> + <releases> + <enabled>true</enabled> + <checksumPolicy>fail</checksumPolicy> + </releases> + </repository> + </repositories> + + <pluginRepositories> + <pluginRepository> + <id>saymytexts-public-group</id> + <url>https://nexus.nuiton.org/nexus/content/groups/say-my-texts-group/</url> + <snapshots> + <enabled>true</enabled> + <checksumPolicy>fail</checksumPolicy> + </snapshots> + <releases> + <enabled>true</enabled> + <checksumPolicy>fail</checksumPolicy> + </releases> + </pluginRepository> + </pluginRepositories> + + <dependencies> + + <dependency> + <groupId>com.google.android</groupId> + <artifactId>android</artifactId> + <version>4.1.1.4</version> + <scope>provided</scope> + </dependency> + + <dependency> + <groupId>com.google.android</groupId> + <artifactId>android-test</artifactId> + <version>4.1.1.4</version> + <scope>test</scope> + </dependency> + + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + <version>${guavaVersion}</version> + </dependency> + + <dependency> + <groupId>ch.acra</groupId> + <artifactId>acra</artifactId> + <version>4.5.0</version> + </dependency> + + </dependencies> + + <build> + <sourceDirectory>src</sourceDirectory> + <resources> + <resource> + <directory>res</directory> + <filtering>false</filtering> + </resource> + </resources> + <plugins> + + <plugin> + <groupId>com.jayway.maven.plugins.android.generation2</groupId> + <artifactId>android-maven-plugin</artifactId> + <version>3.8.2</version> + <executions> + <execution> + <id>alignApk</id> + <phase>install</phase> + <goals> + <goal>zipalign</goal> + </goals> + </execution> + </executions> + <configuration> + <sdk> + <platform>16</platform> + </sdk> + <extractDuplicates>true</extractDuplicates> + <device>usb</device> + <zipalign> + <verbose>true</verbose> + <skip>false</skip> + <inputApk> + ${project.build.directory}/${project.artifactId}-${project.version}.apk + </inputApk> + <outputApk> + ${project.build.directory}/${project.artifactId}-${project.version}.apk + </outputApk> + </zipalign> + </configuration> + <extensions>true</extensions> + </plugin> + + <!-- plugin site --> + <plugin> + <artifactId>maven-site-plugin</artifactId> + <dependencies> + <dependency> + <groupId>org.nuiton.jrst</groupId> + <artifactId>doxia-module-jrst</artifactId> + <version>${jrstPluginVersion}</version> + </dependency> + </dependencies> + </plugin> + + </plugins> + </build> + + <reporting> + <excludeDefaults>true</excludeDefaults> + </reporting> + + <profiles> + + <profile> + <id>sign</id> + <activation> + <property> + <name>performRelease</name> + <value>true</value> + </property> + </activation> + <build> + <plugins> + <plugin> + <groupId>org.nuiton</groupId> + <artifactId>helper-maven-plugin</artifactId> + <executions> + <execution> + <id>get-keystore</id> + <goals> + <goal>share-server-secret</goal> + </goals> + <phase>prepare-package</phase> + <configuration> + <serverId>codelutin-keystore</serverId> + <privateKeyOut>jarsigner.keystore</privateKeyOut> + <passwordOut>jarsigner.storepass</passwordOut> + <usernameOut>jarsigner.alias</usernameOut> + <passphraseOut>jarsigner.keypass</passphraseOut> + </configuration> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jarsigner-plugin</artifactId> + <executions> + <execution> + <id>signing</id> + <goals> + <goal>sign</goal> + </goals> + <phase>package</phase> + <inherited>true</inherited> + <configuration> + <includes> + <include>target/*.apk</include> + </includes> + <arguments> + <argument>-sigalg</argument><argument>MD5withRSA</argument> + <argument>-digestalg</argument><argument>SHA1</argument> + </arguments> + </configuration> + </execution> + </executions> + </plugin> + <plugin> + <groupId>com.jayway.maven.plugins.android.generation2</groupId> + <artifactId>android-maven-plugin</artifactId> + <inherited>true</inherited> + <configuration> + <sign> + <debug>false</debug> + </sign> + </configuration> + </plugin> + </plugins> + </build> + </profile> + + <profile> + <id>license-profile</id> + <activation> + <property> + <name>performRelease</name> + <value>true</value> + </property> + </activation> + + <build> + <defaultGoal>generate-resources</defaultGoal> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>license-maven-plugin</artifactId> + <executions> + <execution> + <id>update-file-header-on-pom</id> + <goals> + <goal>update-file-header</goal> + </goals> + <phase>generate-resources</phase> + <configuration> + <roots> + <root>${project.basedir}</root> + </roots> + <includes> + <include>pom.xml</include> + </includes> + <addSvnKeyWords>false</addSvnKeyWords> + <verbose>false</verbose> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + + <profile> + <id>reporting</id> + <activation> + <property> + <name>performRelease</name> + <value>true</value> + </property> + </activation> + + <reporting> + <plugins> + + <plugin> + <artifactId>maven-project-info-reports-plugin</artifactId> + <version>${projectInfoReportsPluginVersion}</version> + <reportSets> + <reportSet> + <reports> + <report>project-team</report> + <report>mailing-list</report> + <report>cim</report> + <report>issue-tracking</report> + <report>license</report> + <report>scm</report> + <report>dependencies</report> + <report>dependency-convergence</report> + <report>dependency-info</report> + <report>plugin-management</report> + <report>plugins</report> + <report>dependency-management</report> + <report>summary</report> + </reports> + </reportSet> + </reportSets> + </plugin> + + </plugins> + </reporting> + + </profile> + + <!-- This profile update license stuff with new goal update-file-header --> + <profile> + <id>update-file-header</id> + <activation> + <property> + <name>performRelease</name> + <value>true</value> + </property> + </activation> + + <properties> + <license.descriptor>src/license/project.xml</license.descriptor> + </properties> + <build> + <defaultGoal>process-resources</defaultGoal> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>license-maven-plugin</artifactId> + <executions> + <execution> + <id>update-file-header</id> + <goals> + <goal>update-file-header</goal> + </goals> + <configuration> + <addSvnKeyWords>true</addSvnKeyWords> + <excludes> + <exclude>**/i18n/*.properties</exclude> + <exclude>**/THIRD-PARTY.properties</exclude> + <!-- since sh scripts must begins by the line #!/bin/sh, + can not use the mojo for the mojo --> + <exclude>**/*.sh</exclude> + </excludes> + </configuration> + <phase>process-resources</phase> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + + </profiles> +</project> Copied: branches/widget/res/values/arrays.xml (from rev 46, trunk/res/values/arrays.xml) =================================================================== --- branches/widget/res/values/arrays.xml (rev 0) +++ branches/widget/res/values/arrays.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string-array name="preferences_reading_profile_values"> + <item>always</item> + <item>anyDeviceConnected</item> + <item>wiredDeviceConnected</item> + <item>never</item> + </string-array> + + <string-array name="preferences_reading_profile_entries"> + <item>Always</item> + <item>When a headset, headphone or bluetooth device is connected</item> + <item>When a headset, headphone is connected</item> + <item>Never</item> + </string-array> + +</resources> \ No newline at end of file Deleted: branches/widget/res/values/preference_keys.xml =================================================================== --- trunk/res/values/preference_keys.xml 2014-04-02 11:59:25 UTC (rev 40) +++ branches/widget/res/values/preference_keys.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -1,9 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="preference_enable_reading_key">enable_reading</string> - <string name="preference_enable_heisendroid_mode_key">enable_heisendroid_mode</string> - <string name="preference_test_sms_key">test_sms</string> - <string name="preference_version_key">version</string> - <string name="preference_documentation_key">documentation</string> - <string name="preference_issue_tracker_key">issue_tracker</string> -</resources> \ No newline at end of file Copied: branches/widget/res/values/preference_keys.xml (from rev 47, trunk/res/values/preference_keys.xml) =================================================================== --- branches/widget/res/values/preference_keys.xml (rev 0) +++ branches/widget/res/values/preference_keys.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="preference_reading_profile_key">reading_profile</string> + <string name="preference_enable_interaction_key">enable_interaction</string> + <string name="preference_enable_heisendroid_mode_key">enable_heisendroid_mode</string> + <string name="preference_voice_recognizer_max_attempt_number_key">preference_voice_recognizer_max_attempt_number</string> + <string name="preference_test_sms_key">test_sms</string> + <string name="preference_version_key">version</string> + <string name="preference_documentation_key">documentation</string> + <string name="preference_issue_tracker_key">issue_tracker</string> +</resources> \ No newline at end of file Deleted: branches/widget/res/values/strings.xml =================================================================== --- trunk/res/values/strings.xml 2014-04-02 11:59:25 UTC (rev 40) +++ branches/widget/res/values/strings.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -1,40 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="app_name">Say My Texts</string> - <string name="app_description">Android application which reads out loud the new SMS when the headset is plugged.</string> - - <string name="sms_received">New message from %1$s: %2$s</string> - - <!-- Preferences --> - <string name="preferences_settings_label">Settings</string> - <string name="preference_enable_reading_label">SMS reading</string> - <string name="preference_enable_heisendroid_mode_label">Heisendroid mode</string> - <string name="preference_test_sms_label">Test by sending an SMS to myself</string> - <string name="test_sms_content">Heisendroïd</string> - - <string name="preferences_about_label">About</string> - <string name="preference_version_label">Version</string> - <string name="preference_documentation_label">Documentation</string> - <string name="preference_documentation_url">https://doc.chorem.org/say-my-texts/index.html</string> - <string name="preference_issue_tracker_label">Bug report</string> - <string name="preference_issue_tracker_url">http://forge.chorem.org/projects/say-my-texts/issues</string> - - <!--ACRA--> - <string name="crash_toast_text">Ooooops ! the application crashed, but a report has been sent to my developer to help fix the issue !</string> - <string name="crash_dialog_title">say My Texts has crashed</string> - <string name="crash_dialog_text">An unexpected error occurred forcing the - application to stop. Please help us fix this by sending us error data, - all you have to do is click OK.</string> - <string name="crash_dialog_comment_prompt">You might add your comments about the problem below:</string> - <string name="crash_dialog_ok_toast">Thank you !</string> - - <!-- actions --> - <string name="call_action">call</string> - <string name="answer_action">answer</string> - <string name="quit_action">quit</string> - - <string name="confirm_action">confirm</string> - <string name="modifiy_action">modify</string> - <string name="cancel_action">cancel</string> - -</resources> Copied: branches/widget/res/values/strings.xml (from rev 47, trunk/res/values/strings.xml) =================================================================== --- branches/widget/res/values/strings.xml (rev 0) +++ branches/widget/res/values/strings.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">Say My Texts</string> + <string name="app_description">Android application which reads out loud the new SMS when the headset is plugged.</string> + + <string name="sms_received">New message from %1$s: %2$s.</string> + + <!-- Preferences --> + <string name="preferences_settings_label">Settings</string> + <string name="preference_reading_profile_label">SMS reading</string> + <string name="preference_enable_interaction_label">Interaction (call or answer)</string> + <string name="preference_voice_recognizer_max_attempt_number_label">Maximum attempt number</string> + <string name="preference_enable_heisendroid_mode_label">Heisendroid mode</string> + <string name="preference_test_sms_label">Test by sending an SMS to myself</string> + <string name="test_sms_content">Heisendroïd</string> + + <string name="preferences_about_label">About</string> + <string name="preference_version_label">Version</string> + <string name="preference_documentation_label">Documentation</string> + <string name="preference_documentation_url">https://doc.chorem.org/say-my-texts/index.html</string> + <string name="preference_issue_tracker_label">Bug report</string> + <string name="preference_issue_tracker_url">http://forge.chorem.org/projects/say-my-texts/issues</string> + + <!--ACRA--> + <string name="crash_toast_text">Ooooops ! the application crashed, but a report has been sent to my developer to help fix the issue !</string> + <string name="crash_dialog_title">say My Texts has crashed</string> + <string name="crash_dialog_text">An unexpected error occurred forcing the + application to stop. Please help us fix this by sending us error data, + all you have to do is click OK.</string> + <string name="crash_dialog_comment_prompt">You might add your comments about the problem below:</string> + <string name="crash_dialog_ok_toast">Thank you !</string> + + <!-- actions --> + <string name="ask_next_action">What would you like to do? Call, answer or nothing?</string> + <string name="dictate_sms">Dictate your answer</string> + <string name="send_sms_confirmation">You dictated: %s. Would you like to confirm, modify ou cancel?</string> + + <string name="call_action">call</string> + <string name="answer_action">answer</string> + <string name="quit_action">nothing</string> + + <string name="confirm_action">confirm</string> + <string name="modifiy_action">modify</string> + <string name="cancel_action">cancel</string> + <string name="voice_not_recognized">I did not understand.</string> + +</resources> Copied: branches/widget/res/values-fr/arrays.xml (from rev 46, trunk/res/values-fr/arrays.xml) =================================================================== --- branches/widget/res/values-fr/arrays.xml (rev 0) +++ branches/widget/res/values-fr/arrays.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string-array name="preferences_reading_profile_entries"> + <item>Toujours</item> + <item>Quand un casque ou un appareil bluetooth est connecté</item> + <item>Quand un casque est connecté</item> + <item>Jamais</item> + </string-array> + +</resources> \ No newline at end of file Deleted: branches/widget/res/values-fr/strings.xml =================================================================== --- trunk/res/values-fr/strings.xml 2014-04-02 11:59:25 UTC (rev 40) +++ branches/widget/res/values-fr/strings.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -1,39 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="app_name">Say My Texts</string> - <string name="app_description">Application Android qui lit à voix haute the SMS reçus quand un casque est branché.</string> - - <string name="sms_received">Nouveau message de %1$s : %2$s</string> - - <!-- Preferences --> - <string name="preferences_settings_label">Paramètres</string> - <string name="preference_enable_reading_label">Lecture des SMS</string> - <string name="preference_enable_heisendroid_mode_label">Mode Heisendroid</string> - <string name="preference_test_sms_label">Tester en m\'envoyant un SMS</string> - <string name="test_sms_content">Heisendroïd</string> - - <string name="preferences_about_label">À propos</string> - <string name="preference_version_label">Version</string> - <string name="preference_documentation_label">Documentation</string> - <string name="preference_documentation_url">https://doc.chorem.org/say-my-texts/fr/index.html</string> - <string name="preference_issue_tracker_label">Rapporter un bug</string> - <string name="preference_issue_tracker_url">http://forge.chorem.org/projects/say-my-texts/issues</string> - - <!--ACRA--> - <string name="crash_toast_text">Erreur innatendue, préparation du rapport de bug</string> - <string name="crash_dialog_title">Say My Texts a planté</string> - <string name="crash_dialog_text">Une erreur inattendue s\'est produite et a forcé l\'application à s\'arrêter. - Si vous voulez nous aider à corriger ce bug, merci de nous envoyer les données par mail en appuyant sur OK.</string> - <string name="crash_dialog_comment_prompt">Vous pouvez ajouter un commentaire ci-dessous:</string> - <string name="crash_dialog_ok_toast">Merci !</string> - - <!-- actions --> - <string name="call_action">appeler</string> - <string name="answer_action">répondre</string> - <string name="quit_action">quitter</string> - - <string name="confirm_action">confirmer</string> - <string name="modifiy_action">corriger</string> - <string name="cancel_action">annuler</string> - -</resources> Copied: branches/widget/res/values-fr/strings.xml (from rev 47, trunk/res/values-fr/strings.xml) =================================================================== --- branches/widget/res/values-fr/strings.xml (rev 0) +++ branches/widget/res/values-fr/strings.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">Say My Texts</string> + <string name="app_description">Application Android qui lit à voix haute the SMS reçus quand un casque est branché.</string> + + <string name="sms_received">Nouveau message de %1$s : %2$s.</string> + + <!-- Preferences --> + <string name="preferences_settings_label">Paramètres</string> + <string name="preference_reading_profile_label">Lecture des SMS</string> + <string name="preference_enable_interaction_label">Intéraction (appel ou réponse)</string> + <string name="preference_voice_recognizer_max_attempt_number_label">Nombre maximum d\'essais</string> + <string name="preference_enable_heisendroid_mode_label">Mode Heisendroid</string> + <string name="preference_test_sms_label">Tester en m\'envoyant un SMS</string> + <string name="test_sms_content">Heisendroïd</string> + + <string name="preferences_about_label">À propos</string> + <string name="preference_version_label">Version</string> + <string name="preference_documentation_label">Documentation</string> + <string name="preference_documentation_url">https://doc.chorem.org/say-my-texts/fr/index.html</string> + <string name="preference_issue_tracker_label">Rapporter un bug</string> + <string name="preference_issue_tracker_url">http://forge.chorem.org/projects/say-my-texts/issues</string> + + <!--ACRA--> + <string name="crash_toast_text">Erreur innatendue, préparation du rapport de bug</string> + <string name="crash_dialog_title">Say My Texts a planté</string> + <string name="crash_dialog_text">Une erreur inattendue s\'est produite et a forcé l\'application à s\'arrêter. + Si vous voulez nous aider à corriger ce bug, merci de nous envoyer les données par mail en appuyant sur OK.</string> + <string name="crash_dialog_comment_prompt">Vous pouvez ajouter un commentaire ci-dessous:</string> + <string name="crash_dialog_ok_toast">Merci !</string> + + <!-- actions --> + <string name="ask_next_action">Que voulez-vous faire ? Appeler, répondre ou rien ?</string> + <string name="dictate_sms">Dictez votre réponse</string> + <string name="send_sms_confirmation">Vous avez dicté : %s. Voulez-vous confirmer, corriger ou annuler ?</string> + + <string name="call_action">appeler</string> + <string name="answer_action">répondre</string> + <string name="quit_action">rien</string> + + <string name="confirm_action">confirmer</string> + <string name="modifiy_action">corriger</string> + <string name="cancel_action">annuler</string> + + <string name="voice_not_recognized">Je n\'ai pas compris.</string> + +</resources> Deleted: branches/widget/res/xml/preferences.xml =================================================================== --- trunk/res/xml/preferences.xml 2014-04-02 11:59:25 UTC (rev 40) +++ branches/widget/res/xml/preferences.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -1,37 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> - - <PreferenceCategory android:title="@string/preferences_settings_label"> - - <SwitchPreference android:key="@string/preference_enable_reading_key" - android:title="@string/preference_enable_reading_label" - android:defaultValue="true" /> - - <SwitchPreference android:key="@string/preference_enable_heisendroid_mode_key" - android:title="@string/preference_enable_heisendroid_mode_label" - android:defaultValue="false" /> - - <Preference android:key="@string/preference_test_sms_key" - android:title="@string/preference_test_sms_label" - android:persistent="false"/> - - </PreferenceCategory> - - <PreferenceCategory android:title="@string/preferences_about_label" - android:persistent="false"> - - <Preference android:key="@string/preference_version_key" - android:title="@string/preference_version_label"/> - - <Preference android:key="@string/preference_documentation_key" - android:title="@string/preference_documentation_label" - android:summary="@string/preference_documentation_url"/> - - <Preference android:key="@string/preference_issue_tracker_key" - android:title="@string/preference_issue_tracker_label" - android:summary="@string/preference_issue_tracker_url"/> - - </PreferenceCategory> - -</PreferenceScreen> \ No newline at end of file Copied: branches/widget/res/xml/preferences.xml (from rev 47, trunk/res/xml/preferences.xml) =================================================================== --- branches/widget/res/xml/preferences.xml (rev 0) +++ branches/widget/res/xml/preferences.xml 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> + +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + + <PreferenceCategory android:title="@string/preferences_settings_label"> + + <ListPreference android:key="@string/preference_reading_profile_key" + android:title="@string/preference_reading_profile_label" + android:entries="@array/preferences_reading_profile_entries" + android:entryValues="@array/preferences_reading_profile_values" + android:defaultValue="anyDeviceConnected"/> + + <SwitchPreference android:key="@string/preference_enable_interaction_key" + android:title="@string/preference_enable_interaction_label" + android:defaultValue="true" /> + + <EditTextPreference android:key="@string/preference_voice_recognizer_max_attempt_number_key" + android:title="@string/preference_voice_recognizer_max_attempt_number_label" + android:defaultValue="3" + android:numeric="integer"/> + + <SwitchPreference android:key="@string/preference_enable_heisendroid_mode_key" + android:title="@string/preference_enable_heisendroid_mode_label" + android:defaultValue="false"/> + + <Preference android:key="@string/preference_test_sms_key" + android:title="@string/preference_test_sms_label" + android:persistent="false"/> + + </PreferenceCategory> + + <PreferenceCategory android:title="@string/preferences_about_label" + android:persistent="false"> + + <Preference android:key="@string/preference_version_key" + android:title="@string/preference_version_label"/> + + <Preference android:key="@string/preference_documentation_key" + android:title="@string/preference_documentation_label" + android:summary="@string/preference_documentation_url"/> + + <Preference android:key="@string/preference_issue_tracker_key" + android:title="@string/preference_issue_tracker_label" + android:summary="@string/preference_issue_tracker_url"/> + + </PreferenceCategory> + +</PreferenceScreen> \ No newline at end of file Copied: branches/widget/src/org/chorem/android/saymytexts/DictateSmsBroadcastReceiver.java (from rev 44, trunk/src/org/chorem/android/saymytexts/DictateSmsBroadcastReceiver.java) =================================================================== --- branches/widget/src/org/chorem/android/saymytexts/DictateSmsBroadcastReceiver.java (rev 0) +++ branches/widget/src/org/chorem/android/saymytexts/DictateSmsBroadcastReceiver.java 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,113 @@ +package org.chorem.android.saymytexts; + +import android.app.PendingIntent; +import android.content.ActivityNotFoundException; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.media.ToneGenerator; +import android.net.Uri; +import android.os.Bundle; +import android.speech.RecognitionListener; +import android.speech.RecognizerIntent; +import android.speech.SpeechRecognizer; +import android.telephony.SmsManager; +import android.util.Log; + +import java.util.List; + +/** + * @author Kevin Morin (Code Lutin) + * @since x.x + */ +public class DictateSmsBroadcastReceiver extends BroadcastReceiver { + + private static final String TAG = "DictateSmsBroadcastReceiver"; + + public static final String ACTION_DICTATE_SMS = "org.chorem.android.saymytexts.DICTATE_SMS"; + + public static final String INTENT_EXTRA_SMS = "sms"; + public static final String INTENT_EXTRA_ATTEMPT_NUMBER = "attemptNumber"; + + @Override + public void onReceive(final Context context, final Intent intent) { + Log.d(TAG, "next action ?"); + final SMS sms = (SMS) intent.getSerializableExtra(INTENT_EXTRA_SMS); + + if (sms != null) { + SpeechRecognizer speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context); + speechRecognizer.setRecognitionListener(new RecognitionListener() { + + private ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, ToneGenerator.MAX_VOLUME); + + @Override + public void onReadyForSpeech(Bundle params) { + } + + @Override + public void onBeginningOfSpeech() { + } + + @Override + public void onRmsChanged(float rmsdB) { + } + + @Override + public void onBufferReceived(byte[] buffer) {} + + @Override + public void onEndOfSpeech() {} + + @Override + public void onError(int error) { + Log.d(TAG, "onError " + error); + tg.startTone(ToneGenerator.TONE_PROP_NACK); + reaskToDictate(context, intent, sms); + } + + @Override + public void onResults(Bundle data) { + List<String> results = data.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); + + Log.d(TAG, "results " + results); + if (results != null) { + String text = results.get(0); + Intent serviceIntent = new Intent(context, SayMyTextService.class); + serviceIntent.setAction(SayMyTextService.ACTION_CONFIRM_SMS_SENDING); + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS, sms); + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_DICTATED_MESSAGE, text); + context.startService(serviceIntent); + + } else { + tg.startTone(ToneGenerator.TONE_PROP_NACK); + reaskToDictate(context, intent, sms); + } + } + + @Override + public void onPartialResults(Bundle partialResults) {} + + @Override + public void onEvent(int eventType, Bundle params) {} + }); + + Intent recognizeIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); + // Specify free form input + recognizeIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, + RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); + + speechRecognizer.startListening(recognizeIntent); + } + } + + protected void reaskToDictate(Context context, Intent intent, SMS sms) { + int attemptNumber = intent.getIntExtra(INTENT_EXTRA_ATTEMPT_NUMBER, 1); + + Intent serviceIntent = new Intent(context, SayMyTextService.class); + serviceIntent.setAction(SayMyTextService.ACTION_DICTATE_SMS); + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS, sms); + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_ATTEMPT_NUMBER, attemptNumber); + context.startService(serviceIntent); + } +} Deleted: branches/widget/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java =================================================================== --- trunk/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java 2014-04-02 11:59:25 UTC (rev 40) +++ branches/widget/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java 2014-05-08 20:47:27 UTC (rev 49) @@ -1,129 +0,0 @@ -package org.chorem.android.saymytexts; - -/* - * #%L - * Say My Texts - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2014 Code Lutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import android.bluetooth.BluetoothClass; -import android.bluetooth.BluetoothDevice; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.database.Cursor; -import android.net.Uri; -import android.os.Bundle; -import android.provider.BaseColumns; -import android.provider.ContactsContract; -import android.telephony.SmsMessage; -import android.util.Log; - -/** - * Receives the SMSs and if the headset is plugged, start the service to say it out loud. - * - * @author Kevin Morin (Code Lutin) - * @since 1.0 - */ -public class NewTextBroadcastReceiver extends BroadcastReceiver { - - private static final String TAG = "NewTextBroadcastReceiver"; - - @Override - public void onReceive(Context context, Intent intent) { - Intent serviceIntent = new Intent(context, SayMyTextService.class); -Log.d(TAG, "received"); - String action = intent.getAction(); - if ("android.provider.Telephony.SMS_RECEIVED".equals(action)) { - - // get the SMS message passed in - Bundle bundle = intent.getExtras(); - if (bundle != null) { - SmsMessage[] msgs = null; - String messageReceived = ""; - - // retrieve the SMS message received - Object[] pdus = (Object[]) bundle.get("pdus"); - msgs = new SmsMessage[pdus.length]; - for (int i = 0; i < msgs.length; i++) { - msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); - messageReceived += msgs[i].getDisplayMessageBody() + " "; - } - - // Get the Sender Phone Number - String senderPhoneNumber = msgs[0].getDisplayOriginatingAddress(); - String senderName = getContactDisplayNameByNumber(context, senderPhoneNumber); - SMS sms = new SMS(senderPhoneNumber, senderName, messageReceived); - - Log.d(TAG,messageReceived); - // start the service to say it out loud - serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS, sms); - context.startService(serviceIntent); - } - - } else { - BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); - - if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) { - int majorDeviceClass = device.getBluetoothClass().getMajorDeviceClass(); - if (majorDeviceClass == BluetoothClass.Device.Major.AUDIO_VIDEO) { - serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_BT_DEVICE, device); - serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_ADD_BT_DEVICE, true); - context.startService(serviceIntent); - } - - } else { - serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_BT_DEVICE, device); - serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_ADD_BT_DEVICE, false); - context.startService(serviceIntent); - } - } - } - - /** - * Finds the contact name in the contact book - * @param number the number of the contact - * @return the name if the contact is known, the number otherwise - */ - protected String getContactDisplayNameByNumber(Context context, String number) { - Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); - String name = number; - - ContentResolver contentResolver = context.getContentResolver(); - Cursor contactLookup = contentResolver.query(uri, - new String[] { BaseColumns._ID, ContactsContract.PhoneLookup.DISPLAY_NAME }, - null, null, null); - - try { - if (contactLookup != null && contactLookup.getCount() > 0) { - contactLookup.moveToNext(); - name = contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)); - } - } finally { - if (contactLookup != null) { - contactLookup.close(); - } - } - - return name; - } -} Copied: branches/widget/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java (from rev 42, trunk/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java) =================================================================== --- branches/widget/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java (rev 0) +++ branches/widget/src/org/chorem/android/saymytexts/NewTextBroadcastReceiver.java 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,130 @@ +package org.chorem.android.saymytexts; + +/* + * #%L + * Say My Texts + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import android.bluetooth.BluetoothClass; +import android.bluetooth.BluetoothDevice; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Bundle; +import android.provider.BaseColumns; +import android.provider.ContactsContract; +import android.telephony.SmsMessage; +import android.util.Log; + +/** + * Receives the SMSs and if the headset is plugged, start the service to say it out loud. + * + * @author Kevin Morin (Code Lutin) + * @since 1.0 + */ +public class NewTextBroadcastReceiver extends BroadcastReceiver { + + private static final String TAG = "NewTextBroadcastReceiver"; + + @Override + public void onReceive(Context context, Intent intent) { + Intent serviceIntent = new Intent(context, SayMyTextService.class); + String action = intent.getAction(); + if ("android.provider.Telephony.SMS_RECEIVED".equals(action)) { + + // get the SMS message passed in + Bundle bundle = intent.getExtras(); + if (bundle != null) { + SmsMessage[] msgs = null; + String messageReceived = ""; + + // retrieve the SMS message received + Object[] pdus = (Object[]) bundle.get("pdus"); + msgs = new SmsMessage[pdus.length]; + for (int i = 0; i < msgs.length; i++) { + msgs[i] = SmsMessage.createFromPdu((byte[]) pdus[i]); + messageReceived += msgs[i].getDisplayMessageBody() + " "; + } + + // Get the Sender Phone Number + String senderPhoneNumber = msgs[0].getDisplayOriginatingAddress(); + String senderName = getContactDisplayNameByNumber(context, senderPhoneNumber); + SMS sms = new SMS(senderPhoneNumber, senderName, messageReceived); + + Log.d(TAG,messageReceived); + // start the service to say it out loud + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS, sms); + serviceIntent.setAction(SayMyTextService.ACTION_READ_SMS); + context.startService(serviceIntent); + } + + } else { + BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); + serviceIntent.setAction(SayMyTextService.ACTION_MANAGE_BT_DEVICE); + + if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) { + int majorDeviceClass = device.getBluetoothClass().getMajorDeviceClass(); + if (majorDeviceClass == BluetoothClass.Device.Major.AUDIO_VIDEO) { + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_BT_DEVICE, device); + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_ADD_BT_DEVICE, true); + context.startService(serviceIntent); + } + + } else { + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_BT_DEVICE, device); + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_ADD_BT_DEVICE, false); + context.startService(serviceIntent); + } + } + } + + /** + * Finds the contact name in the contact book + * @param number the number of the contact + * @return the name if the contact is known, the number otherwise + */ + protected String getContactDisplayNameByNumber(Context context, String number) { + Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number)); + String name = number; + + ContentResolver contentResolver = context.getContentResolver(); + Cursor contactLookup = contentResolver.query(uri, + new String[] { BaseColumns._ID, ContactsContract.PhoneLookup.DISPLAY_NAME }, + null, null, null); + + try { + if (contactLookup != null && contactLookup.getCount() > 0) { + contactLookup.moveToNext(); + name = contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)); + } + } finally { + if (contactLookup != null) { + contactLookup.close(); + } + } + + return name; + } +} Deleted: branches/widget/src/org/chorem/android/saymytexts/SayMyTextService.java =================================================================== --- trunk/src/org/chorem/android/saymytexts/SayMyTextService.java 2014-04-02 11:59:25 UTC (rev 40) +++ branches/widget/src/org/chorem/android/saymytexts/SayMyTextService.java 2014-05-08 20:47:27 UTC (rev 49) @@ -1,388 +0,0 @@ -package org.chorem.android.saymytexts; - -/* - * #%L - * Say My Texts - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2014 Code Lutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import android.app.PendingIntent; -import android.app.Service; -import android.bluetooth.BluetoothDevice; -import android.content.ActivityNotFoundException; -import android.content.BroadcastReceiver; -import android.content.ContentResolver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.database.Cursor; -import android.media.AudioManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.IBinder; -import android.preference.PreferenceManager; -import android.provider.BaseColumns; -import android.provider.ContactsContract; -import android.speech.RecognitionListener; -import android.speech.RecognizerIntent; -import android.speech.SpeechRecognizer; -import android.speech.tts.TextToSpeech; -import android.speech.tts.UtteranceProgressListener; -import android.telephony.PhoneStateListener; -import android.telephony.TelephonyManager; -import android.util.Log; -import android.widget.Toast; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -/** - * Service which say out loud the text passed in the intent - * - * @author Kevin Morin (Code Lutin) - * @since 1.0 - */ -public class SayMyTextService extends Service implements TextToSpeech.OnInitListener { - - private static final String TAG = "SayMyTextService"; - - /** SMS to read */ - public static final String INTENT_EXTRA_SMS = "sms"; - /** Bluetooth device which has just connected or disconnected */ - public static final String INTENT_EXTRA_BT_DEVICE = "btDevice"; - /** If true, the device has just connected, else disconnected */ - public static final String INTENT_EXTRA_ADD_BT_DEVICE = "addBtDevice"; - - /** utterance id when the bluetooth device is connected */ - protected static final String BT_UTTERANCE_ID = "btUtteranceId"; - protected static final String OTHER_UTTERANCE_ID = "otherUtteranceId"; - - protected AudioManager audioManager; - - /** null if the texttospeech is not initialized */ - protected Boolean canSpeak = null; - - protected TextToSpeech textToSpeech; - - protected SpeechRecognizer speechRecognizer; - - /** texts to read, received before the textospeech is ready or while a call is in progress */ - protected List<SMS> awaitingTexts = new ArrayList<>(); - - /** bluetooth devices which are currently connected */ - protected Map<BluetoothDevice, Integer> bluetoothDevices = new HashMap<>(); - - /** - * Listener to clal state change - */ - protected final PhoneStateListener callStateListener = new PhoneStateListener() { - @Override - public void onCallStateChanged(int state, String incomingNumber) { - super.onCallStateChanged(state, incomingNumber); - if (canSpeak != null) { - setCanSpeak(state == TelephonyManager.CALL_STATE_IDLE); - } - } - }; - - @Override - public void onCreate() { - super.onCreate(); - - textToSpeech = new TextToSpeech(this, this); - speechRecognizer = SpeechRecognizer.createSpeechRecognizer(SayMyTextService.this); - - audioManager = (AudioManager) getSystemService(AUDIO_SERVICE); - - TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); - tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE); - } - - @Override - public void onDestroy() { - super.onDestroy(); - TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); - tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE); - textToSpeech.shutdown(); - } - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - int result = super.onStartCommand(intent, flags, startId); - - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - String readingEnabledKey = getString(R.string.preference_enable_reading_key); - boolean readingEnabled = sharedPref.getBoolean(readingEnabledKey, true); - - if (intent != null) { - BluetoothDevice device = intent.getParcelableExtra(INTENT_EXTRA_BT_DEVICE); - // if a device is passed to the service - // add or remove the device from the connected devices - if (device != null) { - boolean addBtDevice = intent.getBooleanExtra(INTENT_EXTRA_ADD_BT_DEVICE, false); - if (addBtDevice) { - bluetoothDevices.put(device, device.getBluetoothClass().getDeviceClass()); - } else { - bluetoothDevices.remove(device); - } - - - // else if the user enabled the reading and - // if the headset is plugged, or if there is a bluetooth device connected - } else if (readingEnabled && (audioManager.isWiredHeadsetOn() || !bluetoothDevices.isEmpty())) { - - SMS sms = (SMS) intent.getSerializableExtra(INTENT_EXTRA_SMS); - if (canSpeak != null && canSpeak) { - requestReading(sms); - } else { - awaitingTexts.add(sms); - } - } - - result = START_STICKY; - } - - return result; - } - - @Override - public void onInit(int status) { - if (status == TextToSpeech.SUCCESS) { - // init texttospeech - textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() { - @Override - public void onStart(String utteranceId) { - } - - @Override - public void onError(String utteranceId) { - Log.e(TAG, "Error speaking: " + utteranceId); - } - - @Override - public void onDone(String utteranceId) { - if (BT_UTTERANCE_ID.equals(utteranceId)) { - // when the text has been read by the bluetooth device, stop the connection - audioManager.stopBluetoothSco(); - audioManager.setMode(AudioManager.MODE_NORMAL); - } - waiting = false; - } - }); - - TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); - setCanSpeak(tm.getCallState() == TelephonyManager.CALL_STATE_IDLE); - - } else { - setCanSpeak(null); - textToSpeech = new TextToSpeech(this, this); - } - } - - /** - * Sets if the texts can be read - * - * @param canSpeak null if the texttospeech is not ready, - * false if a call is in progress - * true otherwise - */ - protected void setCanSpeak(Boolean canSpeak) { - this.canSpeak = canSpeak; - if (canSpeak != null && canSpeak) { - requestReading(awaitingTexts); - awaitingTexts.clear(); - } - } - - /** - * Requests the reading of one text through the wired headset or bluetooth device - * @param sms the text to read - */ - protected void requestReading(SMS sms) { - requestReading(Collections.singletonList(sms)); - } - - /** - * Requests the reading of a list of texts through the wired headset or bluetooth device - * @param smsList the texts to read - */ - protected void requestReading(List<SMS> smsList) { - if (bluetoothDevices.isEmpty()) { - readText(smsList, false); - } else { - requestReadingOverBt(smsList); - } - } - - /** - * Starts the connection with the bluetooth device and requests the reading - * @param smsList the texts to read - */ - protected void requestReadingOverBt(final List<SMS> smsList) { - registerReceiver(new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - int state = intent.getExtras().getInt(AudioManager.EXTRA_SCO_AUDIO_STATE); - if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) { - context.unregisterReceiver(this); - readText(smsList, true); - } - } - }, new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)); - audioManager.setMode(AudioManager.MODE_IN_CALL); - audioManager.startBluetoothSco(); - } - - /** - * Reads the texts out loud - * @param smsList the texts to read - * @param btConnected if true, adds the utterance id for the bluetooth device - */ - protected void readText(List<SMS> smsList, boolean btConnected) { - HashMap<String, String> params = new HashMap<>(); - params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_VOICE_CALL)); - params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, btConnected ? BT_UTTERANCE_ID : OTHER_UTTERANCE_ID); - - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); - String heisendroidModeEnabledKey = getString(R.string.preference_enable_heisendroid_mode_key); - boolean heisendroidModeEnabled = sharedPref.getBoolean(heisendroidModeEnabledKey, true); - - for (SMS sms : smsList) { - waiting = true; - if (heisendroidModeEnabled) { - textToSpeech.setLanguage(Locale.US); - textToSpeech.setSpeechRate(0.3f); - textToSpeech.setPitch(0.1f); - textToSpeech.speak("Say my text.", TextToSpeech.QUEUE_ADD, params); - } - - textToSpeech.setLanguage(Locale.getDefault()); - textToSpeech.setSpeechRate(1f); - textToSpeech.setPitch(1f); - String text = getString(R.string.sms_received, sms.getSenderName(), sms.getMessage()); - textToSpeech.speak(text, TextToSpeech.QUEUE_ADD, params); - - if (heisendroidModeEnabled) { - textToSpeech.setLanguage(Locale.US); - textToSpeech.setSpeechRate(0.3f); - textToSpeech.setPitch(0.1f); - textToSpeech.speak("You're goddamn right.", TextToSpeech.QUEUE_ADD, params); - } - - while (waiting) { - } - waiting = true; - recognizeVoice(sms); - while (waiting) { - } - } - } - - protected void recognizeVoice(final SMS sms) { - Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); - // Specify free form input - intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, - RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); - - speechRecognizer.setRecognitionListener(new RecognitionListener() { - @Override - public void onReadyForSpeech(Bundle params) { - } - - @Override - public void onBeginningOfSpeech() { - } - - @Override - public void onRmsChanged(float rmsdB) { - } - - @Override - public void onBufferReceived(byte[] buffer) { - } - - @Override - public void onEndOfSpeech() { - } - - @Override - public void onError(int error) { - Log.d(TAG, "onError " + error); - waiting = false; - } - - @Override - public void onResults(Bundle data) { - List<String> results = data.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); - - Log.d(TAG, "results " + results); - if (results != null) { - - if (results.contains(getString(R.string.call_action))) { - try { - Intent callIntent = new Intent(Intent.ACTION_CALL); - callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - callIntent.setData(Uri.parse("tel:" + sms.getSenderNumber())); - startActivity(callIntent); - - } catch (ActivityNotFoundException activityException) { - Log.e("Calling a Phone Number", "Call failed", activityException); - } - - } else if (results.contains(getString(R.string.answer_action))) { - //TODO ask the user to dictate the message - } else if (results.contains(getString(R.string.quit_action))) { - // do nothing - } else { - //TODO add a counter to ask only twice (or 3 times, or it should be configurable) - recognizeVoice(sms); - } - } - - waiting = false; - } - - @Override - public void onPartialResults(Bundle partialResults) { - } - - @Override - public void onEvent(int eventType, Bundle params) { - } - }); - - speechRecognizer.startListening(intent); - } - - boolean waiting = false; - -} Copied: branches/widget/src/org/chorem/android/saymytexts/SayMyTextService.java (from rev 48, trunk/src/org/chorem/android/saymytexts/SayMyTextService.java) =================================================================== --- branches/widget/src/org/chorem/android/saymytexts/SayMyTextService.java (rev 0) +++ branches/widget/src/org/chorem/android/saymytexts/SayMyTextService.java 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,590 @@ +package org.chorem.android.saymytexts; + +/* + * #%L + * Say My Texts + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import android.app.Service; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHeadset; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.media.AudioManager; +import android.os.IBinder; +import android.preference.PreferenceManager; +import android.speech.tts.TextToSpeech; +import android.speech.tts.UtteranceProgressListener; +import android.telephony.PhoneStateListener; +import android.telephony.TelephonyManager; +import android.util.Log; +import com.google.common.base.Function; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; + +/** + * Service which say out loud the text passed in the intent + * + * @author Kevin Morin (Code Lutin) + * @since 1.0 + */ +public class SayMyTextService extends Service implements TextToSpeech.OnInitListener, SharedPreferences.OnSharedPreferenceChangeListener { + + private static final String TAG = "SayMyTextService"; + + public static final String ACTION_READ_SMS = "org.chorem.android.saymytexts.READ_SMS"; + public static final String ACTION_READ_NEXT_SMS = "org.chorem.android.saymytexts.READ_NEXT_SMS"; + public static final String ACTION_MANAGE_BT_DEVICE = "org.chorem.android.saymytexts.ADD_BT_DEVICE"; + public static final String ACTION_REASK_ACTION = "org.chorem.android.saymytexts.REASK_ACTION"; + public static final String ACTION_DICTATE_SMS = "org.chorem.android.saymytexts.DICTATE_SMS"; + public static final String ACTION_CONFIRM_SMS_SENDING = "org.chorem.android.saymytexts.CONFIRM_SMS_SENDING"; + + /** SMS to read */ + public static final String INTENT_EXTRA_SMS = "sms"; + /** Bluetooth device which has just connected or disconnected */ + public static final String INTENT_EXTRA_BT_DEVICE = "btDevice"; + /** If true, the device has just connected, else disconnected */ + public static final String INTENT_EXTRA_ADD_BT_DEVICE = "addBtDevice"; + /** Bluetooth device which has just connected or disconnected */ + public static final String INTENT_EXTRA_DICTATED_MESSAGE = "dictatedMessage"; + /** Attempt number: if set, it means that the user said something not understandable, so ask again */ + public static final String INTENT_EXTRA_ATTEMPT_NUMBER = "attemptNumber"; + + /** utterance id when the bluetooth device is connected */ + protected static final String BT_UTTERANCE_ID = "btUtteranceId"; + protected static final String BT_ASK_NEXT_ACTION_UTTERANCE_ID = "btAskNextActionUtteranceId"; + protected static final String ASK_NEXT_ACTION_UTTERANCE_ID = "askNextActionUtteranceId"; + protected static final String OTHER_UTTERANCE_ID = "oherUtteranceId"; + + protected int maxAttemptNumber; + + protected String readingProfile; + + protected boolean heisendroidModeEnabled; + + protected boolean interactionEnabled; + + protected AudioManager audioManager; + + /** null if the texttospeech is not initialized */ + protected Boolean canSpeak = null; + + // true if music was playing when the first message in queue arrived + protected boolean musicWasActive; + + // true if the speaker was on when the first message in queue arrived + protected boolean speakerWasOn; + + protected TextToSpeech textToSpeech; + + /** texts to read, received before the textospeech is ready or while a call is in progress */ + protected List<SMS> awaitingTexts = new ArrayList<>(); + + /** bluetooth devices which are currently connected */ + protected Map<BluetoothDevice, Integer> bluetoothDevices = new HashMap<>(); + + /** + * Listener to call state change + */ + protected final PhoneStateListener callStateListener = new PhoneStateListener() { + @Override + public void onCallStateChanged(int state, String incomingNumber) { + super.onCallStateChanged(state, incomingNumber); + if (canSpeak != null) { + setCanSpeak(state == TelephonyManager.CALL_STATE_IDLE); + } + } + }; + + BluetoothHeadset mBluetoothHeadset; + + @Override + public void onCreate() { + super.onCreate(); + + textToSpeech = new TextToSpeech(this, this); + + audioManager = (AudioManager) getSystemService(AUDIO_SERVICE); + + TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); + tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE); + + IntentFilter intentFilter = new IntentFilter(SayNextActionBroadcastReceiver.ACTION_SAY_NEXT_ACTION); + registerReceiver(new SayNextActionBroadcastReceiver(), intentFilter); + + intentFilter = new IntentFilter(DictateSmsBroadcastReceiver.ACTION_DICTATE_SMS); + registerReceiver(new DictateSmsBroadcastReceiver(), intentFilter); + + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this); + String key = getString(R.string.preference_voice_recognizer_max_attempt_number_key); + String maxAttemptValue = sharedPref.getString(key, null); + try { + maxAttemptNumber = Integer.parseInt(maxAttemptValue); + } catch (NumberFormatException e) { + maxAttemptNumber = 3; + } + + String[] readingProfileValues = getResources().getStringArray(R.array.preferences_reading_profile_values); + String readingProfileKey = getString(R.string.preference_reading_profile_key); + readingProfile = sharedPref.getString(readingProfileKey, readingProfileValues[0]); + + String heisendroidModeEnabledKey = getString(R.string.preference_enable_heisendroid_mode_key); + heisendroidModeEnabled = sharedPref.getBoolean(heisendroidModeEnabledKey, true); + + String interactionPrefKey = getString(R.string.preference_enable_interaction_key); + interactionEnabled = sharedPref.getBoolean(interactionPrefKey, true); + + sharedPref.registerOnSharedPreferenceChangeListener(this); + +//// Get the default adapter +// final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); +// +//// Define Service Listener of BluetoothProfile +// BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() { +// public void onServiceConnected(int profile, BluetoothProfile proxy) { +// if (profile == BluetoothProfile.HEADSET) { +// mBluetoothHeadset = (BluetoothHeadset) proxy; +// List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices(); +// for ( final BluetoothDevice dev : devices ) { +// if (mBluetoothHeadset.isAudioConnected(dev)) { +// bluetoothDevices.put(dev, dev.getBluetoothClass().getDeviceClass()); +// } +// } +// mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset); +// } +// } +// public void onServiceDisconnected(int profile) { +// if (profile == BluetoothProfile.HEADSET) { +// mBluetoothHeadset = null; +// } +// } +// }; +// +//// Establish connection to the proxy. +// mBluetoothAdapter.getProfileProxy(this, mProfileListener, BluetoothProfile.HEADSET); + + } + + @Override + public void onDestroy() { + super.onDestroy(); + TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); + tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE); + textToSpeech.shutdown(); + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + int result = super.onStartCommand(intent, flags, startId); + + if (intent != null) { + String action = intent.getAction(); + Log.d(TAG, "action " + action); + + final SMS sms = (SMS) intent.getSerializableExtra(INTENT_EXTRA_SMS); + int attemptNumber = intent.getIntExtra(INTENT_EXTRA_ATTEMPT_NUMBER, 0); + + switch (action) { + case ACTION_MANAGE_BT_DEVICE: + BluetoothDevice device = intent.getParcelableExtra(INTENT_EXTRA_BT_DEVICE); + // if a device is passed to the service + // add or remove the device from the connected devices + if (device != null) { + boolean addBtDevice = intent.getBooleanExtra(INTENT_EXTRA_ADD_BT_DEVICE, false); + if (addBtDevice) { + bluetoothDevices.put(device, device.getBluetoothClass().getDeviceClass()); + } else { + bluetoothDevices.remove(device); + } + } + break; + + case ACTION_REASK_ACTION: + askForActionAfterReading(sms, !bluetoothDevices.isEmpty(), ++attemptNumber); + break; + + case ACTION_DICTATE_SMS: + dictateSMS(sms, attemptNumber + 1); + break; + + case ACTION_CONFIRM_SMS_SENDING: + // if a message has just been dictated + final String dictatedMessage = intent.getStringExtra(INTENT_EXTRA_DICTATED_MESSAGE); + askSendingConfirmation(dictatedMessage, sms, ++attemptNumber); + break; + + case ACTION_READ_NEXT_SMS: + setCanSpeak(true); + break; + + default: + boolean readingEnabled; + String[] readingProfileValues = getResources().getStringArray(R.array.preferences_reading_profile_values); + if (readingProfileValues[0].equals(readingProfile)) { + readingEnabled = true; + + } else if (readingProfileValues[1].equals(readingProfile)) { + readingEnabled = audioManager.isWiredHeadsetOn() || !bluetoothDevices.isEmpty(); + + } else if (readingProfileValues[2].equals(readingProfile)) { + readingEnabled = audioManager.isWiredHeadsetOn(); + + } else { + readingEnabled = false; + } + + if (readingEnabled) { + if (!Boolean.FALSE.equals(canSpeak)) { + musicWasActive = audioManager.isMusicActive(); + speakerWasOn = audioManager.isSpeakerphoneOn(); + + if (musicWasActive) { + audioManager.setStreamMute(AudioManager.STREAM_MUSIC, musicWasActive); + } + + if (readingProfileValues[0].equals(readingProfile) + && !audioManager.isWiredHeadsetOn() && bluetoothDevices.isEmpty()) { + audioManager.setMode(AudioManager.MODE_IN_CALL); + audioManager.setSpeakerphoneOn(true); + } + } + + if (Boolean.TRUE.equals(canSpeak)) { + requestReading(sms); + + } else { + awaitingTexts.add(sms); + } + } + } + + result = START_STICKY; + } + + return result; + } + + @Override + public void onInit(int status) { + if (status == TextToSpeech.SUCCESS) { + TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); + setCanSpeak(tm.getCallState() == TelephonyManager.CALL_STATE_IDLE); + + } else { + setCanSpeak(null); + textToSpeech = new TextToSpeech(this, this); + } + } + + /** + * Sets if the texts can be read + * + * @param canSpeak null if the texttospeech is not ready, + * false if a call is in progress + * true otherwise + */ + protected void setCanSpeak(Boolean canSpeak) { + this.canSpeak = canSpeak; + if (Boolean.TRUE.equals(canSpeak)) { + if (!awaitingTexts.isEmpty()) { + SMS sms = awaitingTexts.remove(0); + requestReading(sms); + + } else { + if (!bluetoothDevices.isEmpty()) { + audioManager.stopBluetoothSco(); + } + if (musicWasActive) { + audioManager.setStreamMute(AudioManager.STREAM_MUSIC, false); + } + audioManager.setSpeakerphoneOn(speakerWasOn); + audioManager.setMode(AudioManager.MODE_NORMAL); + } + } + } + + /** + * Requests the reading of one text through the wired headset or bluetooth device + * @param sms the text to read + */ + protected void requestReading(final SMS sms) { + if (bluetoothDevices.isEmpty()) { + readText(sms, false); + } else { + requestBluetoothSpeakingActivation(new Function<Void, Void>() { + @Override + public Void apply(Void input) { + readText(sms, true); + return null; + } + }); + } + } + + /** + * Starts the connection with the bluetooth device and requests the reading + * @param callback the function called when the bluetooth is ready + */ + protected void requestBluetoothSpeakingActivation(final Function<Void, Void> callback) { + registerReceiver(new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + int state = intent.getExtras().getInt(AudioManager.EXTRA_SCO_AUDIO_STATE); + if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) { + context.unregisterReceiver(this); + callback.apply(null); + } + } + }, new IntentFilter(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)); + audioManager.setMode(AudioManager.MODE_IN_CALL); + audioManager.startBluetoothSco(); + } + + /** + * Reads the texts out loud + * @param sms the text to read + * @param btConnected if true, adds the utterance id for the bluetooth device + */ + protected void readText(final SMS sms, boolean btConnected) { + // disable the reading of the nexts sms while reading the current one + setCanSpeak(false); + + textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() { + @Override + public void onStart(String utteranceId) { + } + + @Override + public void onError(String utteranceId) { + Log.e(TAG, "Error speaking: " + utteranceId); + } + + @Override + public void onDone(String utteranceId) { + Log.d(TAG, "done"); + setCanSpeak(true); + } + }); + + HashMap<String, String> params = new HashMap<>(); + params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_VOICE_CALL)); + + if (heisendroidModeEnabled) { + textToSpeech.setLanguage(Locale.US); + textToSpeech.setSpeechRate(0.3f); + textToSpeech.setPitch(0.1f); + textToSpeech.speak("Say my text.", TextToSpeech.QUEUE_ADD, params); + } + + if (!interactionEnabled && !heisendroidModeEnabled) { + params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, OTHER_UTTERANCE_ID); + } + textToSpeech.setLanguage(Locale.getDefault()); + textToSpeech.setSpeechRate(1f); + textToSpeech.setPitch(1f); + String text = getString(R.string.sms_received, sms.getSenderName(), sms.getMessage()); + textToSpeech.speak(text, TextToSpeech.QUEUE_ADD, params); + + if (heisendroidModeEnabled) { + if (interactionEnabled) { + params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, OTHER_UTTERANCE_ID); + } + textToSpeech.setLanguage(Locale.US); + textToSpeech.setSpeechRate(0.3f); + textToSpeech.setPitch(0.1f); + textToSpeech.speak("You're goddamn right.", TextToSpeech.QUEUE_ADD, params); + } + + if (interactionEnabled) { + askForActionAfterReading(sms, btConnected, 1); + } + } + + protected void askForActionAfterReading(final SMS sms, boolean btConnected, final int attemptNumber) { + textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() { + @Override + public void onStart(String utteranceId) { + } + + @Override + public void onError(String utteranceId) { + Log.e(TAG, "Error speaking: " + utteranceId); + } + + @Override + public void onDone(String utteranceId) { + if (ASK_NEXT_ACTION_UTTERANCE_ID.equals(utteranceId) || + BT_ASK_NEXT_ACTION_UTTERANCE_ID.equals(utteranceId)) { + Intent sayaction = new Intent(SayNextActionBroadcastReceiver.ACTION_SAY_NEXT_ACTION); + sayaction.putExtra(SayNextActionBroadcastReceiver.INTENT_EXTRA_SMS, sms); + sayaction.putExtra(SayNextActionBroadcastReceiver.INTENT_EXTRA_ATTEMPT_NUMBER, attemptNumber); + sayaction.putExtra(SayNextActionBroadcastReceiver.INTENT_EXTRA_FALLBACK_ACTION, ACTION_REASK_ACTION); + + sendBroadcast(sayaction); + } + } + }); + + HashMap<String, String> params = new HashMap<>(); + params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_VOICE_CALL)); + + textToSpeech.setLanguage(Locale.getDefault()); + textToSpeech.setSpeechRate(1f); + textToSpeech.setPitch(1f); + + if (attemptNumber > 1) { + textToSpeech.speak(getString(R.string.voice_not_recognized), TextToSpeech.QUEUE_ADD, params); + } + + if (attemptNumber <= maxAttemptNumber) { + params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, + btConnected ? BT_ASK_NEXT_ACTION_UTTERANCE_ID : ASK_NEXT_ACTION_UTTERANCE_ID); + textToSpeech.speak(getString(R.string.ask_next_action), TextToSpeech.QUEUE_ADD, params); + + } else { + setCanSpeak(true); + } + } + + protected void dictateSMS(final SMS sms, final int attemptNumber) { + Log.d(TAG, "dictateSMS " ); + textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() { + @Override + public void onStart(String utteranceId) { + } + + @Override + public void onError(String utteranceId) { + Log.e(TAG, "Error speaking: " + utteranceId); + } + + @Override + public void onDone(String utteranceId) { + Intent dictateAction = new Intent(DictateSmsBroadcastReceiver.ACTION_DICTATE_SMS); + dictateAction.putExtra(DictateSmsBroadcastReceiver.INTENT_EXTRA_SMS, sms); + dictateAction.putExtra(DictateSmsBroadcastReceiver.INTENT_EXTRA_ATTEMPT_NUMBER, attemptNumber); + sendBroadcast(dictateAction); + + } + }); + + HashMap<String, String> params = new HashMap<>(); + params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_VOICE_CALL)); + + if (attemptNumber > 1) { + textToSpeech.speak(getString(R.string.voice_not_recognized), TextToSpeech.QUEUE_ADD, params); + } + + if (attemptNumber <= maxAttemptNumber) { + params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, OTHER_UTTERANCE_ID); + textToSpeech.setLanguage(Locale.getDefault()); + textToSpeech.setSpeechRate(1f); + textToSpeech.setPitch(1f); + textToSpeech.speak(getString(R.string.dictate_sms), TextToSpeech.QUEUE_ADD, params); + + } else { + setCanSpeak(true); + } + + } + + protected void askSendingConfirmation(final String message, final SMS originSms, final int attemptNumber) { + Log.d(TAG, "askSendingConfirmation " + message); + textToSpeech.setOnUtteranceProgressListener(new UtteranceProgressListener() { + @Override + public void onStart(String utteranceId) { + } + + @Override + public void onError(String utteranceId) { + Log.e(TAG, "Error speaking: " + utteranceId); + } + + @Override + public void onDone(String utteranceId) { + Intent sayaction = new Intent(SayNextActionBroadcastReceiver.ACTION_SAY_NEXT_ACTION); + sayaction.putExtra(SayNextActionBroadcastReceiver.INTENT_EXTRA_SMS, originSms); + sayaction.putExtra(SayNextActionBroadcastReceiver.INTENT_EXTRA_MESSAGE, message); + sayaction.putExtra(SayNextActionBroadcastReceiver.INTENT_EXTRA_ATTEMPT_NUMBER, attemptNumber); + sayaction.putExtra(SayNextActionBroadcastReceiver.INTENT_EXTRA_FALLBACK_ACTION, ACTION_CONFIRM_SMS_SENDING); + sendBroadcast(sayaction); + + } + }); + + HashMap<String, String> params = new HashMap<>(); + params.put(TextToSpeech.Engine.KEY_PARAM_STREAM, String.valueOf(AudioManager.STREAM_VOICE_CALL)); + + textToSpeech.setLanguage(Locale.getDefault()); + textToSpeech.setSpeechRate(1f); + textToSpeech.setPitch(1f); + + if (attemptNumber > 1) { + textToSpeech.speak(getString(R.string.voice_not_recognized), TextToSpeech.QUEUE_ADD, params); + } + + if (attemptNumber <= maxAttemptNumber) { + params.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, OTHER_UTTERANCE_ID); + String text = getString(R.string.send_sms_confirmation, message); + textToSpeech.speak(text, TextToSpeech.QUEUE_ADD, params); + + } else { + setCanSpeak(true); + } + + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (key.equals(getString(R.string.preference_voice_recognizer_max_attempt_number_key))) { + String maxAttemptValue = sharedPreferences.getString(key, null); + try { + maxAttemptNumber = Integer.parseInt(maxAttemptValue); + } catch (NumberFormatException e) { + maxAttemptNumber = 3; + } + + } else if (key.equals(getString(R.string.preference_reading_profile_key))) { + String[] readingProfileValues = + getResources().getStringArray(R.array.preferences_reading_profile_values); + readingProfile = sharedPreferences.getString(key, readingProfileValues[0]); + + } else if (key.equals(getString(R.string.preference_enable_heisendroid_mode_key))) { + heisendroidModeEnabled = sharedPreferences.getBoolean(key, true); + + } else if (key.equals(getString(R.string.preference_enable_interaction_key))) { + interactionEnabled = sharedPreferences.getBoolean(key, true); + } + } +} Deleted: branches/widget/src/org/chorem/android/saymytexts/SayMyTextsWidgetProvider.java =================================================================== --- trunk/src/org/chorem/android/saymytexts/SayMyTextsWidgetProvider.java 2014-04-02 11:59:25 UTC (rev 40) +++ branches/widget/src/org/chorem/android/saymytexts/SayMyTextsWidgetProvider.java 2014-05-08 20:47:27 UTC (rev 49) @@ -1,109 +0,0 @@ -package org.chorem.android.saymytexts; - -/* - * #%L - * Say My Texts - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2014 Code Lutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import android.app.PendingIntent; -import android.appwidget.AppWidgetManager; -import android.appwidget.AppWidgetProvider; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.preference.PreferenceManager; -import android.util.Log; -import android.widget.RemoteViews; - -/** - * @author Kevin Morin (Code Lutin) - * @since x.x - */ -public class SayMyTextsWidgetProvider extends AppWidgetProvider { - - private static final String TAG = "SayMyTextsWidgetProvider"; - - protected static final String CLICK_ACTION = "org.chorem.android.saymytexts.action.APPWIDGET_CLICKED"; - - @Override - public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, int[] appWidgetIds) { - final int N = appWidgetIds.length; - - // Perform this loop procedure for each App Widget that belongs to this provider - for (int i = 0; i < N; i++) { - final int appWidgetId = appWidgetIds[i]; - - // Create an Intent to call this onReceive method - Intent intent = new Intent(context, getClass()); - intent.setAction(CLICK_ACTION); - PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); - - // Get the layout for the App Widget and attach an on-click listener - // to the button - RemoteViews views = updateButtonState(context); - views.setOnClickPendingIntent(R.id.say_my_texts_widget, pendingIntent); - - PreferenceManager.getDefaultSharedPreferences(context) - .registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() { - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - String enableReadingKey = context.getString(R.string.preference_enable_reading_key); - if (key.equals(enableReadingKey)) { - RemoteViews views = updateButtonState(context); - appWidgetManager.updateAppWidget(appWidgetId, views); - } - } - }); - - // Tell the AppWidgetManager to perform an update on the current app widget - appWidgetManager.updateAppWidget(appWidgetId, views); - } - } - - @Override - public void onReceive(Context context, Intent intent) { - super.onReceive(context, intent); - Log.d(TAG, "on receive " + intent.getAction()); - if (CLICK_ACTION.equals(intent.getAction())) { - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); - String key = context.getString(R.string.preference_enable_reading_key); - boolean enabled = sharedPref.getBoolean(key, true); - Log.d(TAG, "enabled " + enabled); - sharedPref.edit().putBoolean(key, !enabled).commit(); - } - } - - protected RemoteViews updateButtonState(Context context) { - SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); - String key = context.getString(R.string.preference_enable_reading_key); - - boolean enabled = sharedPreferences.getBoolean(key, true); - int drawableId = enabled ? - android.R.drawable.button_onoff_indicator_on : - android.R.drawable.button_onoff_indicator_off; - - RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.say_my_texts_widget); - views.setImageViewResource(R.id.say_my_texts_widget_onoff_icon, drawableId); - - return views; - } -} Copied: branches/widget/src/org/chorem/android/saymytexts/SayMyTextsWidgetProvider.java (from rev 46, trunk/src/org/chorem/android/saymytexts/SayMyTextsWidgetProvider.java) =================================================================== --- branches/widget/src/org/chorem/android/saymytexts/SayMyTextsWidgetProvider.java (rev 0) +++ branches/widget/src/org/chorem/android/saymytexts/SayMyTextsWidgetProvider.java 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,111 @@ +package org.chorem.android.saymytexts; + +/* + * #%L + * Say My Texts + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; +import android.widget.RemoteViews; + +/** + * @author Kevin Morin (Code Lutin) + * @since x.x + */ +public class SayMyTextsWidgetProvider extends AppWidgetProvider { + + private static final String TAG = "SayMyTextsWidgetProvider"; + + protected static final String CLICK_ACTION = "org.chorem.android.saymytexts.action.APPWIDGET_CLICKED"; + + @Override + public void onUpdate(final Context context, final AppWidgetManager appWidgetManager, int[] appWidgetIds) { + final int N = appWidgetIds.length; + + // Perform this loop procedure for each App Widget that belongs to this provider + for (int i = 0; i < N; i++) { + final int appWidgetId = appWidgetIds[i]; + + // Create an Intent to call this onReceive method + Intent intent = new Intent(context, getClass()); + intent.setAction(CLICK_ACTION); + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0); + + // Get the layout for the App Widget and attach an on-click listener + // to the button + RemoteViews views = updateButtonState(context); + views.setOnClickPendingIntent(R.id.say_my_texts_widget, pendingIntent); + + //TODO + PreferenceManager.getDefaultSharedPreferences(context) + .registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { +// String enableReadingKey = context.getString(R.string.preference_enable_reading_key); +// if (key.equals(enableReadingKey)) { +// RemoteViews views = updateButtonState(context); +// appWidgetManager.updateAppWidget(appWidgetId, views); +// } + } + }); + + // Tell the AppWidgetManager to perform an update on the current app widget + appWidgetManager.updateAppWidget(appWidgetId, views); + } + } + + @Override + public void onReceive(Context context, Intent intent) { + super.onReceive(context, intent); + Log.d(TAG, "on receive " + intent.getAction()); + if (CLICK_ACTION.equals(intent.getAction())) { + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(context); +// String key = context.getString(R.string.preference_enable_reading_key); +// boolean enabled = sharedPref.getBoolean(key, true); +// Log.d(TAG, "enabled " + enabled); +// sharedPref.edit().putBoolean(key, !enabled).commit(); + } + } + + protected RemoteViews updateButtonState(Context context) { + SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); +// String key = context.getString(R.string.preference_enable_reading_key); +// +// boolean enabled = sharedPreferences.getBoolean(key, true); +// int drawableId = enabled ? +// android.R.drawable.button_onoff_indicator_on : +// android.R.drawable.button_onoff_indicator_off; +// +// RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.say_my_texts_widget); +// views.setImageViewResource(R.id.say_my_texts_widget_onoff_icon, drawableId); + +// return views; + return null; + } +} Copied: branches/widget/src/org/chorem/android/saymytexts/SayNextActionBroadcastReceiver.java (from rev 44, trunk/src/org/chorem/android/saymytexts/SayNextActionBroadcastReceiver.java) =================================================================== --- branches/widget/src/org/chorem/android/saymytexts/SayNextActionBroadcastReceiver.java (rev 0) +++ branches/widget/src/org/chorem/android/saymytexts/SayNextActionBroadcastReceiver.java 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,161 @@ +package org.chorem.android.saymytexts; + +import android.content.ActivityNotFoundException; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.media.ToneGenerator; +import android.net.Uri; +import android.os.Bundle; +import android.speech.RecognitionListener; +import android.speech.RecognizerIntent; +import android.speech.SpeechRecognizer; +import android.telephony.SmsManager; +import android.util.Log; + +import java.util.List; + +/** + * @author Kevin Morin (Code Lutin) + * @since x.x + */ +public class SayNextActionBroadcastReceiver extends BroadcastReceiver { + + private static final String TAG = "SayNextActionBroadcastReceiver"; + + public static final String ACTION_SAY_NEXT_ACTION = "org.chorem.android.saymytexts.SAY_NEXT_ACTION"; + + public static final String INTENT_EXTRA_SMS = "sms"; + public static final String INTENT_EXTRA_MESSAGE = "message"; + public static final String INTENT_EXTRA_ATTEMPT_NUMBER = "attemptNumber"; + public static final String INTENT_EXTRA_FALLBACK_ACTION = "fallbackAction"; + + @Override + public void onReceive(final Context context, final Intent intent) { + Log.d(TAG, "next action ?"); + final SMS sms = (SMS) intent.getSerializableExtra(INTENT_EXTRA_SMS); + + if (sms != null) { + SpeechRecognizer speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context); + speechRecognizer.setRecognitionListener(new RecognitionListener() { + + private ToneGenerator tg = new ToneGenerator(AudioManager.STREAM_VOICE_CALL, ToneGenerator.MAX_VOLUME); + + @Override + public void onReadyForSpeech(Bundle params) { + } + + @Override + public void onBeginningOfSpeech() { + } + + @Override + public void onRmsChanged(float rmsdB) { + } + + @Override + public void onBufferReceived(byte[] buffer) {} + + @Override + public void onEndOfSpeech() {} + + @Override + public void onError(int error) { + Log.d(TAG, "onError " + error); + tg.startTone(ToneGenerator.TONE_PROP_NACK); + reaskAction(context, intent, sms); + } + + @Override + public void onResults(Bundle data) { + List<String> results = data.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); + + Log.d(TAG, "results " + results); + if (results != null) { + + if (results.contains(context.getString(R.string.call_action))) { + try { + Intent callIntent = new Intent(Intent.ACTION_CALL); + callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + callIntent.setData(Uri.parse("tel:" + sms.getSenderNumber())); + context.startActivity(callIntent); + + } catch (ActivityNotFoundException activityException) { + Log.e(TAG, "Calling a Phone Number failed", activityException); + tg.startTone(ToneGenerator.TONE_PROP_NACK); + readNext(context); + } + + } else if (results.contains(context.getString(R.string.answer_action)) + || results.contains(context.getString(R.string.modifiy_action))) { + Log.d(TAG, "Répondre ou corriger"); + + Intent serviceIntent = new Intent(context, SayMyTextService.class); + serviceIntent.setAction(SayMyTextService.ACTION_DICTATE_SMS); + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS, sms); + context.startService(serviceIntent); + + } else if (results.contains(context.getString(R.string.confirm_action))) { + String message = intent.getStringExtra(INTENT_EXTRA_MESSAGE); + SmsManager smsManager = SmsManager.getDefault(); + smsManager.sendTextMessage(sms.getSenderNumber(), null, message, null, null); + + tg.startTone(ToneGenerator.TONE_PROP_ACK); + + readNext(context); + + } else if (results.contains(context.getString(R.string.quit_action)) + || results.contains(context.getString(R.string.cancel_action))) { + // do nothing + Log.d(TAG, "Quitter"); + tg.startTone(ToneGenerator.TONE_PROP_ACK); + + readNext(context); + + } else { + tg.startTone(ToneGenerator.TONE_PROP_NACK); + reaskAction(context, intent, sms); + } + + } else { + tg.startTone(ToneGenerator.TONE_PROP_NACK); + reaskAction(context, intent, sms); + } + } + + @Override + public void onPartialResults(Bundle partialResults) {} + + @Override + public void onEvent(int eventType, Bundle params) {} + }); + + Intent recognizeIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); + // Specify free form input + recognizeIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, + RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); + + speechRecognizer.startListening(recognizeIntent); + } + } + + protected void reaskAction(Context context, Intent intent, SMS sms) { + int attemptNumber = intent.getIntExtra(INTENT_EXTRA_ATTEMPT_NUMBER, 1); + String fallbackAction = intent.getStringExtra(INTENT_EXTRA_FALLBACK_ACTION); + String dictatedMessage = intent.getStringExtra(INTENT_EXTRA_MESSAGE); + + Intent serviceIntent = new Intent(context, SayMyTextService.class); + serviceIntent.setAction(fallbackAction); + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_SMS, sms); + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_ATTEMPT_NUMBER, attemptNumber); + serviceIntent.putExtra(SayMyTextService.INTENT_EXTRA_DICTATED_MESSAGE, dictatedMessage); + context.startService(serviceIntent); + } + + protected void readNext(Context context) { + Intent serviceIntent = new Intent(context, SayMyTextService.class); + serviceIntent.setAction(SayMyTextService.ACTION_READ_NEXT_SMS); + context.startService(serviceIntent); + } +} Deleted: branches/widget/src/org/chorem/android/saymytexts/SettingsActivity.java =================================================================== --- trunk/src/org/chorem/android/saymytexts/SettingsActivity.java 2014-04-02 11:59:25 UTC (rev 40) +++ branches/widget/src/org/chorem/android/saymytexts/SettingsActivity.java 2014-05-08 20:47:27 UTC (rev 49) @@ -1,169 +0,0 @@ -package org.chorem.android.saymytexts; - -/* - * #%L - * Say My Texts - * $Id:$ - * $HeadURL:$ - * %% - * Copyright (C) 2014 Code Lutin - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program. If not, see - * <http://www.gnu.org/licenses/gpl-3.0.html>. - * #L% - */ - -import android.app.Activity; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.content.pm.PackageManager; -import android.database.Cursor; -import android.media.AudioManager; -import android.net.Uri; -import android.os.Bundle; -import android.preference.Preference; -import android.preference.PreferenceFragment; -import android.preference.PreferenceManager; -import android.preference.SwitchPreference; -import android.speech.RecognitionListener; -import android.speech.RecognizerIntent; -import android.speech.SpeechRecognizer; -import android.speech.tts.TextToSpeech; -import android.telephony.SmsManager; -import android.telephony.TelephonyManager; -import android.util.Log; -import android.widget.Toast; - -import java.util.ArrayList; -import java.util.Locale; - -/** - * Activity to set settings - * - * @author Kevin Morin (Code Lutin) - * @since 1.0 - */ -public class SettingsActivity extends Activity { - - private static final String TAG = "SettingsActivity"; - - protected static final int CHECK_TTS_REQUEST_CODE = 42; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - getFragmentManager().beginTransaction() - .replace(android.R.id.content, new SettingsFragment()) - .commit(); - - Intent checkIntent = new Intent(); - checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA); - startActivityForResult(checkIntent, CHECK_TTS_REQUEST_CODE); - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - if (requestCode == CHECK_TTS_REQUEST_CODE) { - - if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL) { - Intent installIntent = new Intent(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); - startActivity(installIntent); - } - - } else { - super.onActivityResult(requestCode, resultCode, data); - } - } - - public static class SettingsFragment extends PreferenceFragment { - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - // Load the preferences from an XML resource - addPreferencesFromResource(R.xml.preferences); - - Preference testPreference = findPreference(getString(R.string.preference_test_sms_key)); - testPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - sendSMS(); - return true; - } - }); - - try { - Context context = getActivity(); - String currentVersion = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName; - Preference versionPreference = findPreference(getString(R.string.preference_version_key)); - versionPreference.setSummary(currentVersion); - - } catch (PackageManager.NameNotFoundException e) { - Log.e(TAG, "error while getting the version"); - } - - addWebsitePreferenceClickListener(R.string.preference_documentation_key); - addWebsitePreferenceClickListener(R.string.preference_issue_tracker_key); - - } - - @Override - public void onResume() { - super.onResume(); - - SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity()); - - String key = getString(R.string.preference_enable_reading_key); - SwitchPreference enableReadingPref = (SwitchPreference) getPreferenceScreen().findPreference(key); - boolean enabled = sharedPref.getBoolean(key, enableReadingPref.isChecked()); - enableReadingPref.setChecked(enabled); - - key = getString(R.string.preference_enable_heisendroid_mode_key); - enableReadingPref = (SwitchPreference) getPreferenceScreen().findPreference(key); - enabled = sharedPref.getBoolean(key, enableReadingPref.isChecked()); - enableReadingPref.setChecked(enabled); - } - - protected void addWebsitePreferenceClickListener(int keyId) { - Preference preference = findPreference(getString(keyId)); - preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(preference.getSummary().toString())); - startActivity(intent); - return true; - } - }); - } - - protected void sendSMS() { - final Context context = getActivity(); - - TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - String phoneNumber = tMgr.getLine1Number(); - String message = getString(R.string.test_sms_content); - - PendingIntent pi = PendingIntent.getActivity(context, -1, new Intent(context, SettingsActivity.class), 0); - SmsManager sms = SmsManager.getDefault(); - sms.sendTextMessage(phoneNumber, null, message, pi, null); - - } - - } -} Copied: branches/widget/src/org/chorem/android/saymytexts/SettingsActivity.java (from rev 47, trunk/src/org/chorem/android/saymytexts/SettingsActivity.java) =================================================================== --- branches/widget/src/org/chorem/android/saymytexts/SettingsActivity.java (rev 0) +++ branches/widget/src/org/chorem/android/saymytexts/SettingsActivity.java 2014-05-08 20:47:27 UTC (rev 49) @@ -0,0 +1,215 @@ +package org.chorem.android.saymytexts; + +/* + * #%L + * Say My Texts + * $Id:$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import android.app.Activity; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.media.AudioManager; +import android.net.Uri; +import android.os.Bundle; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.PreferenceFragment; +import android.preference.PreferenceManager; +import android.preference.SwitchPreference; +import android.speech.RecognitionListener; +import android.speech.RecognizerIntent; +import android.speech.SpeechRecognizer; +import android.speech.tts.TextToSpeech; +import android.telephony.SmsManager; +import android.telephony.TelephonyManager; +import android.util.Log; +import android.widget.Toast; + +import java.util.ArrayList; +import java.util.Locale; + +/** + * Activity to set settings + * + * @author Kevin Morin (Code Lutin) + * @since 1.0 + */ +public class SettingsActivity extends Activity { + + private static final String TAG = "SettingsActivity"; + + protected static final int CHECK_TTS_REQUEST_CODE = 42; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + getFragmentManager().beginTransaction() + .replace(android.R.id.content, new SettingsFragment()) + .commit(); + + Intent checkIntent = new Intent(); + checkIntent.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA); + startActivityForResult(checkIntent, CHECK_TTS_REQUEST_CODE); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == CHECK_TTS_REQUEST_CODE) { + + if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL) { + Intent installIntent = new Intent(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); + startActivity(installIntent); + } + + } else { + super.onActivityResult(requestCode, resultCode, data); + } + } + + public static class SettingsFragment extends PreferenceFragment + implements SharedPreferences.OnSharedPreferenceChangeListener { + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.preferences); + + Preference testPreference = findPreference(getString(R.string.preference_test_sms_key)); + testPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + sendSMS(); + return true; + } + }); + + try { + Context context = getActivity(); + String currentVersion = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName; + Preference versionPreference = findPreference(getString(R.string.preference_version_key)); + versionPreference.setSummary(currentVersion); + + } catch (PackageManager.NameNotFoundException e) { + Log.e(TAG, "error while getting the version"); + } + + addWebsitePreferenceClickListener(R.string.preference_documentation_key); + addWebsitePreferenceClickListener(R.string.preference_issue_tracker_key); + + SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity()); + + String key = getString(R.string.preference_reading_profile_key); + ListPreference listPreference = (ListPreference) findPreference(key); + CharSequence summary = listPreference.getEntry(); + listPreference.setSummary(summary); + + key = getString(R.string.preference_enable_interaction_key); + SwitchPreference switchPreference = (SwitchPreference) findPreference(key); + boolean enabled = sharedPref.getBoolean(key, switchPreference.isChecked()); + switchPreference.setChecked(enabled); + + key = getString(R.string.preference_voice_recognizer_max_attempt_number_key); + String maxAttemptValue = sharedPref.getString(key, null); + int maxAttemptNumber; + try { + maxAttemptNumber = Integer.parseInt(maxAttemptValue); + } catch (NumberFormatException e) { + maxAttemptNumber = 3; + } + Preference preference = findPreference(key); + preference.setSummary(String.valueOf(maxAttemptNumber)); + preference.setEnabled(enabled); + + key = getString(R.string.preference_enable_heisendroid_mode_key); + switchPreference = (SwitchPreference) findPreference(key); + enabled = sharedPref.getBoolean(key, switchPreference.isChecked()); + switchPreference.setChecked(enabled); + + sharedPref.registerOnSharedPreferenceChangeListener(this); + } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + + if (getString(R.string.preference_reading_profile_key).equals(key)) { + ListPreference preference = (ListPreference) findPreference(key); + CharSequence summary = preference.getEntry(); + preference.setSummary(summary); + + } else if (getString(R.string.preference_enable_interaction_key).equals(key)) { + SwitchPreference switchPreference = (SwitchPreference) findPreference(key); + boolean enabled = sharedPreferences.getBoolean(key, switchPreference.isChecked()); + switchPreference.setChecked(enabled); + findPreference(getString(R.string.preference_voice_recognizer_max_attempt_number_key)).setEnabled(enabled); + + } else if (getString(R.string.preference_voice_recognizer_max_attempt_number_key).equals(key)) { + String maxAttemptValue = sharedPreferences.getString(key, null); + int maxAttemptNumber; + try { + maxAttemptNumber = Integer.parseInt(maxAttemptValue); + } catch (NumberFormatException e) { + maxAttemptNumber = 3; + } + findPreference(key).setSummary(String.valueOf(maxAttemptNumber)); + + } else if (getString(R.string.preference_enable_heisendroid_mode_key).equals(key)) { + SwitchPreference switchPreference = (SwitchPreference) findPreference(key); + boolean enabled = sharedPreferences.getBoolean(key, switchPreference.isChecked()); + switchPreference.setChecked(enabled); + } + } + + protected void addWebsitePreferenceClickListener(int keyId) { + Preference preference = findPreference(getString(keyId)); + preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(preference.getSummary().toString())); + startActivity(intent); + return true; + } + }); + } + + protected void sendSMS() { + final Context context = getActivity(); + + TelephonyManager tMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + String phoneNumber = tMgr.getLine1Number(); + String message = getString(R.string.test_sms_content); + + PendingIntent pi = PendingIntent.getActivity(context, -1, new Intent(context, SettingsActivity.class), 0); + SmsManager sms = SmsManager.getDefault(); + sms.sendTextMessage(phoneNumber, null, message, pi, null); + + } + + } +}
participants (1)
-
kmorin@users.chorem.org