Sending MMS programmatically on Android

断了今生、忘了曾经 提交于 2020-02-21 11:15:30

问题


I am having an issue with a task I'm supposed to do, I'm supposed to send MMS using our own interface on android 2.1 so as you can guess calling the default Activity is out of the question. So my question, is there a way to programatically send MMS using the android SDK without calling their intent, I tried importing the MMS app in eclipse but most of the classes are com.google.android which means they are not open sourced, so I have no idea how to get them if possible, or, how to mimic them. I was even thinking of using reflection to load them from Dalvik, but I think that this is a final effort and may not bring results.

any ideas?

btw, I found

How to send image via MMS in Android?

Sending MMS into different Android devices

but they do not work.. (with out the proprietary classes)


回答1:


Although this question was left unanswered for a while, I kinda found a way back then, just forgot to post. however I got the original MMS app and crippled the binary classes and added corresponding requirements to finish since most of them were private to the build system. The ONLY way do make an mms sender in android (that I know of) is to build the app with the source tree. In that manner you will have access to the restricted MMS functions and it is generally very easy since there is a MMSManager in the source it's self, although this is not public in the sdk. I know my answer is a bit vague, but for those of you going down this path.. prepare for some bumps on the road.. :)




回答2:


Like SmsManager there is something like MmsManager api which is not being exposed by android framework.

So to send MMS first you have to acquire MMS netwotk and then make http calls.

/**
 * Synchronously acquire MMS network connectivity
 *
 * @throws MmsNetworkException If failed permanently or timed out
 */

void acquireNetwork() throws MmsNetworkException {
    Log.i(MmsService.TAG, "Acquire MMS network");
    synchronized (this) {
        try {
            mUseCount++;
            mWaitCount++;
            if (mWaitCount == 1) {
                // Register the receiver for the first waiting request
                registerConnectivityChangeReceiverLocked();
            }
            long waitMs = sNetworkAcquireTimeoutMs;
            final long beginMs = SystemClock.elapsedRealtime();
            do {
                if (!isMobileDataEnabled()) {
                    // Fast fail if mobile data is not enabled
                    throw new MmsNetworkException("Mobile data is disabled");
                }
                // Always try to extend and check the MMS network connectivity
                // before we start waiting to make sure we don't miss the change
                // of MMS connectivity. As one example, some devices fail to send
                // connectivity change intent. So this would make sure we catch
                // the state change.
                if (extendMmsConnectivityLocked()) {
                    // Connected
                    return;
                }
                try {
                    wait(Math.min(waitMs, NETWORK_ACQUIRE_WAIT_INTERVAL_MS));
                } catch (final InterruptedException e) {
                    Log.w(MmsService.TAG, "Unexpected exception", e);
                }
                // Calculate the remaining time to wait
                waitMs = sNetworkAcquireTimeoutMs - (SystemClock.elapsedRealtime() - beginMs);
            } while (waitMs > 0);
            // Last check
            if (extendMmsConnectivityLocked()) {
                return;
            } else {
                // Reaching here means timed out.
                throw new MmsNetworkException("Acquiring MMS network timed out");
            }
        } finally {
            mWaitCount--;
            if (mWaitCount == 0) {
                // Receiver is used to listen to connectivity change and unblock
                // the waiting requests. If nobody's waiting on change, there is
                // no need for the receiver. The auto extension timer will try
                // to maintain the connectivity periodically.
                unregisterConnectivityChangeReceiverLocked();
            }
        }
    }
}

Here is the piece of code which I got from android native source code.

/**
 * Run the MMS request.
 *
 * @param context the context to use
 * @param networkManager the MmsNetworkManager to use to setup MMS network
 * @param apnSettingsLoader the APN loader
 * @param carrierConfigValuesLoader the carrier config loader
 * @param userAgentInfoLoader the user agent info loader
 */



public void sendMms(final Context context, final MmsNetworkManager networkManager,
        final ApnSettingsLoader apnSettingsLoader,
        final CarrierConfigValuesLoader carrierConfigValuesLoader,
        final UserAgentInfoLoader userAgentInfoLoader) {
    Log.i(MmsService.TAG, "Execute " + this.getClass().getSimpleName());
    int result = SmsManager.MMS_ERROR_UNSPECIFIED;
    int httpStatusCode = 0;
    byte[] response = null;
    final Bundle mmsConfig = carrierConfigValuesLoader.get(MmsManager.DEFAULT_SUB_ID);
    if (mmsConfig == null) {
        Log.e(MmsService.TAG, "Failed to load carrier configuration values");
        result = SmsManager.MMS_ERROR_CONFIGURATION_ERROR;
    } else if (!loadRequest(context, mmsConfig)) {
        Log.e(MmsService.TAG, "Failed to load PDU");
        result = SmsManager.MMS_ERROR_IO_ERROR;
    } else {
        // Everything's OK. Now execute the request.
        try {
            // Acquire the MMS network
            networkManager.acquireNetwork();
            // Load the potential APNs. In most cases there should be only one APN available.
            // On some devices on which we can't obtain APN from system, we look up our own
            // APN list. Since we don't have exact information, we may get a list of potential
            // APNs to try. Whenever we found a successful APN, we signal it and return.
            final String apnName = networkManager.getApnName();
            final List<ApnSettingsLoader.Apn> apns = apnSettingsLoader.get(apnName);
            if (apns.size() < 1) {
                throw new ApnException("No valid APN");
            } else {
                Log.d(MmsService.TAG, "Trying " + apns.size() + " APNs");
            }
            final String userAgent = userAgentInfoLoader.getUserAgent();
            final String uaProfUrl = userAgentInfoLoader.getUAProfUrl();
            MmsHttpException lastException = null;
            for (ApnSettingsLoader.Apn apn : apns) {
                Log.i(MmsService.TAG, "Using APN ["
                        + "MMSC=" + apn.getMmsc() + ", "
                        + "PROXY=" + apn.getMmsProxy() + ", "
                        + "PORT=" + apn.getMmsProxyPort() + "]");
                try {
                    final String url = getHttpRequestUrl(apn);
                    // Request a global route for the host to connect
                    requestRoute(networkManager.getConnectivityManager(), apn, url);
                    // Perform the HTTP request
                    response = doHttp(
                            context, networkManager, apn, mmsConfig, userAgent, uaProfUrl);
                    // Additional check of whether this is a success
                    if (isWrongApnResponse(response, mmsConfig)) {
                        throw new MmsHttpException(0/*statusCode*/, "Invalid sending address");
                    }
                    // Notify APN loader this is a valid APN
                    apn.setSuccess();
                    result = Activity.RESULT_OK;
                    break;
                } catch (MmsHttpException e) {
                    Log.w(MmsService.TAG, "HTTP or network failure", e);
                    lastException = e;
                }
            }
            if (lastException != null) {
                throw lastException;
            }
        } catch (ApnException e) {
            Log.e(MmsService.TAG, "MmsRequest: APN failure", e);
            result = SmsManager.MMS_ERROR_INVALID_APN;
        } catch (MmsNetworkException e) {
            Log.e(MmsService.TAG, "MmsRequest: MMS network acquiring failure", e);
            result = SmsManager.MMS_ERROR_UNABLE_CONNECT_MMS;
        } catch (MmsHttpException e) {
            Log.e(MmsService.TAG, "MmsRequest: HTTP or network I/O failure", e);
            result = SmsManager.MMS_ERROR_HTTP_FAILURE;
            httpStatusCode = e.getStatusCode();
        } catch (Exception e) {
            Log.e(MmsService.TAG, "MmsRequest: unexpected failure", e);
            result = SmsManager.MMS_ERROR_UNSPECIFIED;
        } finally {
            // Release MMS network
            networkManager.releaseNetwork();
        }
    }
    // Process result and send back via PendingIntent
    returnResult(context, result, response, httpStatusCode);
}




/**
 * Request the route to the APN (either proxy host or the MMSC host)
 *
 * @param connectivityManager the ConnectivityManager to use
 * @param apn the current APN
 * @param url the URL to connect to
 * @throws MmsHttpException for unknown host or route failure
 */
private static void requestRoute(final ConnectivityManager connectivityManager,
        final ApnSettingsLoader.Apn apn, final String url) throws MmsHttpException {
    String host = apn.getMmsProxy();
    if (TextUtils.isEmpty(host)) {
        final Uri uri = Uri.parse(url);
        host = uri.getHost();
    }
    boolean success = false;
    // Request route to all resolved host addresses
    try {
        for (final InetAddress addr : InetAddress.getAllByName(host)) {
            final boolean requested = requestRouteToHostAddress(connectivityManager, addr);
            if (requested) {
                success = true;
                Log.i(MmsService.TAG, "Requested route to " + addr);
            } else {
                Log.i(MmsService.TAG, "Could not requested route to " + addr);
            }
        }
        if (!success) {
            throw new MmsHttpException(0/*statusCode*/, "No route requested");
        }
    } catch (UnknownHostException e) {
        Log.w(MmsService.TAG, "Unknown host " + host);
        throw new MmsHttpException(0/*statusCode*/, "Unknown host");
    }
}



回答3:


 private void sendSMS(String phoneNumber, String message)
    {        
        PendingIntent pi = PendingIntent.getActivity(this, 0,
            new Intent(this, SMS.class), 0);                
        SmsManager sms = SmsManager.getDefault();
        sms.sendTextMessage(phoneNumber, null, message, pi, null);        
    }    
}

try this



来源:https://stackoverflow.com/questions/3811416/sending-mms-programmatically-on-android

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!