Search in sources :

Example 1 with Message

use of com.klinker.android.send_message.Message in project kdeconnect-android by KDE.

the class SmsMmsUtils method sendMessage.

/**
 * Sends SMS or MMS message.
 *
 * @param context       context in which the method is called.
 * @param textMessage   text body of the message to be sent.
 * @param addressList   List of addresses.
 * @param attachedFiles List of attachments. Pass empty list if none.
 * @param subID         Note that here subID is of type int and not long because klinker library requires it as int
 *                      I don't really know the exact reason why they implemented it as int instead of long
 */
public static void sendMessage(Context context, String textMessage, @NonNull List<SMSHelper.Attachment> attachedFiles, List<SMSHelper.Address> addressList, int subID) {
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    boolean longTextAsMms = prefs.getBoolean(context.getString(R.string.set_long_text_as_mms), false);
    boolean groupMessageAsMms = prefs.getBoolean(context.getString(R.string.set_group_message_as_mms), true);
    int sendLongAsMmsAfter = Integer.parseInt(prefs.getString(context.getString(R.string.convert_to_mms_after), context.getString(R.string.convert_to_mms_after_default)));
    TelephonyHelper.LocalPhoneNumber sendingPhoneNumber;
    List<TelephonyHelper.LocalPhoneNumber> allPhoneNumbers = TelephonyHelper.getAllPhoneNumbers(context);
    Optional<TelephonyHelper.LocalPhoneNumber> maybeSendingPhoneNumber = allPhoneNumbers.stream().filter(localPhoneNumber -> localPhoneNumber.subscriptionID == subID).findAny();
    if (maybeSendingPhoneNumber.isPresent()) {
        sendingPhoneNumber = maybeSendingPhoneNumber.get();
    } else {
        if (allPhoneNumbers.isEmpty()) {
            // We were not able to get any phone number for the user's device
            // Use a null "dummy" number instead. This should behave the same as not setting
            // the FromAddress (below) since the default value there is null.
            // The only more-correct thing we could do here is query the user (maybe in a
            // persistent configuration) for their phone number(s).
            sendingPhoneNumber = new TelephonyHelper.LocalPhoneNumber(null, subID);
            Log.w(SENDING_MESSAGE, "We do not know *any* phone numbers for this device. " + "Attempting to send a message without knowing the local phone number is likely " + "to result in strange behavior, such as the message being sent to yourself, " + "or might entirely fail to send (or be received).");
        } else {
            // Pick an arbitrary phone number
            sendingPhoneNumber = allPhoneNumbers.get(0);
        }
        Log.w(SENDING_MESSAGE, "Unable to determine correct outgoing address for sub ID " + subID + ". Using " + sendingPhoneNumber);
    }
    if (sendingPhoneNumber.number != null) {
        // If the message is going to more than one target (to allow the user to send a message to themselves)
        if (addressList.size() > 1) {
            // Remove the user's phone number if present in the list of recipients
            addressList.removeIf(address -> sendingPhoneNumber.isMatchingPhoneNumber(address.address));
        }
    }
    try {
        Settings settings = new Settings();
        TelephonyHelper.ApnSetting apnSettings = TelephonyHelper.getPreferredApn(context, subID);
        if (apnSettings != null) {
            settings.setMmsc(apnSettings.getMmsc().toString());
            settings.setProxy(apnSettings.getMmsProxyAddressAsString());
            settings.setPort(Integer.toString(apnSettings.getMmsProxyPort()));
        } else {
            settings.setUseSystemSending(true);
        }
        settings.setSendLongAsMms(longTextAsMms);
        settings.setSendLongAsMmsAfter(sendLongAsMmsAfter);
        settings.setGroup(groupMessageAsMms);
        if (subID != -1) {
            settings.setSubscriptionId(subID);
        }
        Transaction transaction = new Transaction(context, settings);
        List<String> addresses = new ArrayList<>();
        for (SMSHelper.Address address : addressList) {
            addresses.add(address.toString());
        }
        Message message = new Message(textMessage, addresses.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
        // If there are any attachment files add those into the message
        for (SMSHelper.Attachment attachedFile : attachedFiles) {
            byte[] file = Base64.decode(attachedFile.getBase64EncodedFile(), Base64.DEFAULT);
            String mimeType = attachedFile.getMimeType();
            String fileName = attachedFile.getUniqueIdentifier();
            message.addMedia(file, mimeType, fileName);
        }
        message.setFromAddress(sendingPhoneNumber.number);
        message.setSave(true);
        // This is the reason why there are separate branch handling for SMS and MMS.
        if (transaction.checkMMS(message)) {
            Log.v("", "Sending new MMS");
            // transaction.sendNewMessage(message, Transaction.NO_THREAD_ID);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
                sendMmsMessageNative(context, message, settings);
            } else {
                // Cross fingers and hope Klinker's library works for this case
                transaction.sendNewMessage(message, Transaction.NO_THREAD_ID);
            }
        } else {
            Log.v(SENDING_MESSAGE, "Sending new SMS");
            transaction.sendNewMessage(message, Transaction.NO_THREAD_ID);
        }
    // TODO: Notify other end
    } catch (Exception e) {
        // TODO: Notify other end
        Log.e(SENDING_MESSAGE, "Exception", e);
    }
}
Also used : Telephony(android.provider.Telephony) RequiresApi(androidx.annotation.RequiresApi) Bundle(android.os.Bundle) Message(com.klinker.android.send_message.Message) NonNull(androidx.annotation.NonNull) PduPart(com.google.android.mms.pdu_alt.PduPart) Uri(android.net.Uri) SmsManager(android.telephony.SmsManager) Random(java.util.Random) Utils(com.klinker.android.send_message.Utils) Transaction(com.klinker.android.send_message.Transaction) ByteArrayInputStream(java.io.ByteArrayInputStream) ContentResolver(android.content.ContentResolver) SmilXmlSerializer(com.android.mms.dom.smil.parser.SmilXmlSerializer) PreferenceManager(android.preference.PreferenceManager) Log(android.util.Log) SendReq(com.google.android.mms.pdu_alt.SendReq) IOUtils(org.apache.commons.io.IOUtils) List(java.util.List) ContentType(com.google.android.mms.ContentType) SmilHelper(com.google.android.mms.smil.SmilHelper) Optional(java.util.Optional) ContentValues(android.content.ContentValues) MultimediaMessagePdu(com.google.android.mms.pdu_alt.MultimediaMessagePdu) SMSHelper(org.kde.kdeconnect.Helpers.SMSHelper) Context(android.content.Context) ByteArrayOutputStream(java.io.ByteArrayOutputStream) BitmapFactory(android.graphics.BitmapFactory) ArrayUtils(org.apache.commons.lang3.ArrayUtils) MMSPart(com.google.android.mms.MMSPart) TelephonyHelper(org.kde.kdeconnect.Helpers.TelephonyHelper) R(org.kde.kdeconnect_tp.R) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Build(android.os.Build) InvalidHeaderValueException(com.google.android.mms.InvalidHeaderValueException) PduHeaders(com.google.android.mms.pdu_alt.PduHeaders) NetworkPacket(org.kde.kdeconnect.NetworkPacket) RetrieveConf(com.google.android.mms.pdu_alt.RetrieveConf) EncodedStringValue(com.google.android.mms.pdu_alt.EncodedStringValue) FileOutputStream(java.io.FileOutputStream) TextUtils(android.text.TextUtils) IOException(java.io.IOException) File(java.io.File) SharedPreferences(android.content.SharedPreferences) Bitmap(android.graphics.Bitmap) Base64(android.util.Base64) CharacterSets(com.google.android.mms.pdu_alt.CharacterSets) PduComposer(com.google.android.mms.pdu_alt.PduComposer) Settings(com.klinker.android.send_message.Settings) PduBody(com.google.android.mms.pdu_alt.PduBody) ContentUris(android.content.ContentUris) InputStream(java.io.InputStream) Message(com.klinker.android.send_message.Message) SharedPreferences(android.content.SharedPreferences) ArrayList(java.util.ArrayList) SMSHelper(org.kde.kdeconnect.Helpers.SMSHelper) InvalidHeaderValueException(com.google.android.mms.InvalidHeaderValueException) IOException(java.io.IOException) Transaction(com.klinker.android.send_message.Transaction) TelephonyHelper(org.kde.kdeconnect.Helpers.TelephonyHelper) Settings(com.klinker.android.send_message.Settings)

Example 2 with Message

use of com.klinker.android.send_message.Message in project kdeconnect-android by KDE.

the class SmsMmsUtils method sendMmsMessageNative.

/**
 * Send an MMS message using SmsManager.sendMultimediaMessage
 *
 * @param context
 * @param message
 * @param klinkerSettings
 */
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1)
protected static void sendMmsMessageNative(Context context, Message message, Settings klinkerSettings) {
    ArrayList<MMSPart> data = new ArrayList<>();
    for (Message.Part p : message.getParts()) {
        MMSPart part = new MMSPart();
        if (p.getName() != null) {
            part.Name = p.getName();
        } else {
            part.Name = p.getContentType().split("/")[0];
        }
        part.MimeType = p.getContentType();
        part.Data = p.getMedia();
        data.add(part);
    }
    if (message.getText() != null && !message.getText().equals("")) {
        // add text to the end of the part and send
        MMSPart part = new MMSPart();
        part.Name = "text";
        part.MimeType = "text/plain";
        part.Data = message.getText().getBytes();
        data.add(part);
    }
    SendReq sendReq = buildPdu(context, message.getFromAddress(), message.getAddresses(), message.getSubject(), data, klinkerSettings);
    Bundle configOverrides = new Bundle();
    configOverrides.putBoolean(SmsManager.MMS_CONFIG_GROUP_MMS_ENABLED, klinkerSettings.getGroup());
    // Write the PDUs to disk so that we can pass them to the SmsManager
    final String fileName = "send." + Math.abs(new Random().nextLong()) + ".dat";
    File mSendFile = new File(context.getCacheDir(), fileName);
    Uri contentUri = (new Uri.Builder()).authority(context.getPackageName() + ".MmsFileProvider").path(fileName).scheme(ContentResolver.SCHEME_CONTENT).build();
    try (FileOutputStream writer = new FileOutputStream(mSendFile)) {
        writer.write(new PduComposer(context, sendReq).make());
    } catch (final IOException e) {
        android.util.Log.e(SENDING_MESSAGE, "Error while writing temporary PDU file: ", e);
    }
    SmsManager mSmsManager;
    if (klinkerSettings.getSubscriptionId() < 0) {
        mSmsManager = SmsManager.getDefault();
    } else {
        mSmsManager = SmsManager.getSmsManagerForSubscriptionId(klinkerSettings.getSubscriptionId());
    }
    mSmsManager.sendMultimediaMessage(context, contentUri, null, null, null);
}
Also used : Message(com.klinker.android.send_message.Message) Bundle(android.os.Bundle) ArrayList(java.util.ArrayList) IOException(java.io.IOException) SendReq(com.google.android.mms.pdu_alt.SendReq) Uri(android.net.Uri) PduComposer(com.google.android.mms.pdu_alt.PduComposer) SmsManager(android.telephony.SmsManager) Random(java.util.Random) FileOutputStream(java.io.FileOutputStream) MMSPart(com.google.android.mms.MMSPart) File(java.io.File) RequiresApi(androidx.annotation.RequiresApi)

Aggregations

Uri (android.net.Uri)2 Bundle (android.os.Bundle)2 SmsManager (android.telephony.SmsManager)2 RequiresApi (androidx.annotation.RequiresApi)2 MMSPart (com.google.android.mms.MMSPart)2 PduComposer (com.google.android.mms.pdu_alt.PduComposer)2 SendReq (com.google.android.mms.pdu_alt.SendReq)2 Message (com.klinker.android.send_message.Message)2 File (java.io.File)2 FileOutputStream (java.io.FileOutputStream)2 IOException (java.io.IOException)2 ArrayList (java.util.ArrayList)2 Random (java.util.Random)2 ContentResolver (android.content.ContentResolver)1 ContentUris (android.content.ContentUris)1 ContentValues (android.content.ContentValues)1 Context (android.content.Context)1 SharedPreferences (android.content.SharedPreferences)1 Bitmap (android.graphics.Bitmap)1 BitmapFactory (android.graphics.BitmapFactory)1