/* * Geopaparazzi - Digital field mapping on Android based devices * Copyright (C) 2016 HydroloGIS (www.hydrologis.com) * * 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/>. */ package eu.geopaparazzi.library.sms; import java.io.IOException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Build; import android.preference.PreferenceManager; import android.telephony.SmsManager; import android.telephony.TelephonyManager; import android.widget.Toast; import eu.geopaparazzi.library.R; import eu.geopaparazzi.library.database.GPLog; import eu.geopaparazzi.library.util.GPDialogs; import eu.geopaparazzi.library.util.LibraryConstants; import eu.geopaparazzi.library.util.PositionUtilities; import eu.geopaparazzi.library.util.UrlUtilities; import eu.geopaparazzi.library.util.Utilities; /** * Utilities for sms handling. * * @author Andrea Antonello (www.hydrologis.com) */ @SuppressWarnings("nls") public class SmsUtilities { /** * Create a text containing the OSM link to the current position. * * @param context the {@link Context} to use. * @param messageText the text to add before the url. * @return the position url. */ public static String createPositionText(final Context context, String messageText) { SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); double[] gpsLocation = PositionUtilities.getGpsLocationFromPreferences(preferences); if (gpsLocation == null) { gpsLocation = PositionUtilities.getMapCenterFromPreferences(preferences, false, false); } StringBuilder sB = new StringBuilder(); if (gpsLocation != null) { String osmUrl = UrlUtilities.osmUrlFromLatLong((float) gpsLocation[1], (float) gpsLocation[0], true, true); sB.append(osmUrl); if (messageText != null) sB.append(" ").append(messageText); } else { sB.append(context.getString(R.string.last_position_unknown)); } return sB.toString(); } /** * Send an SMS. * * @param context the {@link Context} to use. * @param number the number to which to send the SMS. * @param msg the SMS body text. * @param sendMessage if <code>true</code>, a {@link Toast} tells the user that the message was sent. */ public static void sendSMS(Context context, String number, String msg, boolean sendMessage) { Object systemService = context.getSystemService(Context.TELEPHONY_SERVICE); if (systemService instanceof TelephonyManager) { TelephonyManager telManager = (TelephonyManager) systemService; String networkOperator = telManager.getNetworkOperator(); if (networkOperator.trim().length() == 0) { GPDialogs.warningDialog(context, "This functionality works only when connected to a GSM network.", null); return; } } SmsManager mng = SmsManager.getDefault(); PendingIntent dummyEvent = PendingIntent.getBroadcast(context, 0, new Intent("com.devx.SMSExample.IGNORE_ME"), 0); try { if (msg.length() > 160) { msg = msg.substring(0, 160); if (GPLog.LOG) GPLog.addLogEntry("SMSUTILITIES", "Trimming msg to: " + msg); } mng.sendTextMessage(number, null, msg, dummyEvent, dummyEvent); if (sendMessage) GPDialogs.toast(context, R.string.message_sent, Toast.LENGTH_LONG); } catch (Exception e) { GPLog.error(context, e.getLocalizedMessage(), e); GPDialogs.warningDialog(context, "An error occurred while sending the SMS.", null); } } /** * Opens the system sms app to send the message. * * @param context the {@link Context} to use. * @param number the number to which to send to or <code>null</code>, in which * case the number will be prompted in the sms app. * @param msg the message to send or <code>null</code>. */ public static void sendSMSViaApp(Context context, String number, String msg) { Object systemService = context.getSystemService(Context.TELEPHONY_SERVICE); if (systemService instanceof TelephonyManager) { TelephonyManager telManager = (TelephonyManager) systemService; int phoneType = telManager.getPhoneType(); if (phoneType == TelephonyManager.PHONE_TYPE_NONE) { // no phone GPDialogs.warningDialog(context, "This functionality works only when connected to a GSM network.", null); return; } } if (number == null) { number = ""; } if (msg == null) { msg = ""; } if (Build.VERSION.SDK_INT >= 19) { try { Class<?> smsClass = Class.forName("android.provider.Telephony$Sms"); Method getPackageMethod = smsClass.getMethod("getDefaultSmsPackage", Context.class); Object defaultSmsPackageNameObj = getPackageMethod.invoke(null, context); if (defaultSmsPackageNameObj instanceof String) { String defaultSmsPackageName = (String) defaultSmsPackageNameObj; // String defaultSmsPackageName = Telephony.Sms.getDefaultSmsPackage(context); Intent sendIntent = new Intent(Intent.ACTION_SEND); sendIntent.setType("text/plain"); sendIntent.putExtra(Intent.EXTRA_TEXT, msg); sendIntent.setPackage(defaultSmsPackageName); context.startActivity(sendIntent); } } catch (Exception e) { GPLog.error("SmsUtilities", "Error sending sms in > 4.4.", e); } } else { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("sms:" + number)); intent.putExtra("sms_body", msg); context.startActivity(intent); } } /** * Converts an sms data content to the data. * <p/> * <p> * The format is of the type <b>gp.eu/n:x,y,desc;n:x,y,z,desc;b:x,y,desc;b:x,y,z,desc;...</b> * </p> * <p> * Where n = note, in which case z can be added and is the altitude; and * b = bookmark, in which case z can be added and is the zoom. * </p> * * @param url the sms data url to convert. * @return the list of {@link SmsData} containing notes and bookmarks data. * @throws IOException if something goes wrong. */ public static List<SmsData> sms2Data(String url) throws IOException { List<SmsData> smsDataList = new ArrayList<SmsData>(); url = url.replaceFirst("http://", ""); // remove gp:// url = url.substring(6); String[] dataSplit = url.split(";"); for (String data : dataSplit) { if (data.startsWith("n:") || data.startsWith("b:")) { String dataTmp = data.substring(2); String[] values = dataTmp.split(","); if (values.length < 3) { throw new IOException(); } float x = Float.parseFloat(values[0]); float y = Float.parseFloat(values[1]); float z = -1; String descr = null; if (values.length > 3) { z = Float.parseFloat(values[2]); descr = values[3]; } else { descr = values[2]; } SmsData smsData = new SmsData(); if (data.startsWith("n:")) { smsData.TYPE = SmsData.NOTE; } else if (data.startsWith("b:")) { smsData.TYPE = SmsData.BOOKMARK; } smsData.x = x; smsData.y = y; smsData.z = z; smsData.text = descr; smsDataList.add(smsData); } } return smsDataList; } /** * Checks if the device supports phone. * * @param context the context to use. * @return if something goes wrong. */ public static boolean hasPhone(Context context) { TelephonyManager telephonyManager1 = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); if (telephonyManager1.getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) { return false; } else { return true; } } }