您的位置:首页 > 移动开发 > Android开发

android自定义发彩信实现(不调用系统发彩信界面)

2012-05-17 16:20 796 查看
最近几天,因为项目需要,发彩信界面不再是调用系统的界面,即不跳转到短信界面,这个功能起初感觉应该很简单,但是真正做起来后,发现其实没有想象中那么简单,刚做完项目,趁头脑清晰,先把代码写下来先:

这几天为了这个项目,网上找了不少资料,大都资料都差不多,对于如何不跳用系统界面发彩信都有讲解,但是这个的前提是apn必须是wap,当如果是net时,因为连接超时而无法发送,正以内发彩信必须通过wap接入点才能发送,即使是在系统界面发彩信时,如果接入点不是wap,则会自动切换过来,待发送完后再切换回去,所以这个模块的核心,其实就是,如何在调用发彩信时,切换apn至wap,待发送完毕后再切换回去。。。

首先,根据不同移动供应商,需要设置不同的url和proxy

[java] // 电信彩信中心url,代理,端口

public static String mmscUrl_ct = "http://mmsc.vnet.mobi";

public static String mmsProxy_ct = "10.0.0.200";

// 移动彩信中心url,代理,端口

public static String mmscUrl_cm = "http://mmsc.monternet.com";

public static String mmsProxy_cm = "010.000.000.172";

// 联通彩信中心url,代理,端口

public static String mmscUrl_uni = "http://mmsc.vnet.mobi";

public static String mmsProxy_uni = "10.0.0.172";

// 电信彩信中心url,代理,端口

public static String mmscUrl_ct = "http://mmsc.vnet.mobi";

public static String mmsProxy_ct = "10.0.0.200";

// 移动彩信中心url,代理,端口

public static String mmscUrl_cm = "http://mmsc.monternet.com";

public static String mmsProxy_cm = "010.000.000.172";

// 联通彩信中心url,代理,端口

public static String mmscUrl_uni = "http://mmsc.vnet.mobi";

public static String mmsProxy_uni = "10.0.0.172";

方法实现如下:

[java] private static List<String> getSimMNC(Context context){

TelephonyManager telManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

String imsi = telManager.getSubscriberId();

if(imsi!=null){

ArrayList<String> list = new ArrayList<String>();

if(imsi.startsWith("46000") ||imsi.startsWith("46002")){

//因为移动网络编号46000下的IMSI已经用完,所以虚拟了一个46002编号,134/159号段使用了此编号

//中国移动

list.add(mmscUrl_cm);

list.add(mmsProxy_cm);

}else if(imsi.startsWith("46001")){

//中国联通

list.add(mmscUrl_uni);

list.add(mmsProxy_uni);

}else if(imsi.startsWith("46003")){

//中国电信

list.add(mmscUrl_ct);

list.add(mmsProxy_ct);

}

shouldChangeApn(context);

return list;

}

return null;

}

private static List<String> getSimMNC(Context context){

TelephonyManager telManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);

String imsi = telManager.getSubscriberId();

if(imsi!=null){

ArrayList<String> list = new ArrayList<String>();

if(imsi.startsWith("46000") ||imsi.startsWith("46002")){

//因为移动网络编号46000下的IMSI已经用完,所以虚拟了一个46002编号,134/159号段使用了此编号

//中国移动

list.add(mmscUrl_cm);

list.add(mmsProxy_cm);

}else if(imsi.startsWith("46001")){

//中国联通

list.add(mmscUrl_uni);

list.add(mmsProxy_uni);

}else if(imsi.startsWith("46003")){

//中国电信

list.add(mmscUrl_ct);

list.add(mmsProxy_ct);

}

shouldChangeApn(context);

return list;

}

return null;

}

当当前的apn接入点不是发彩信所需要的wap时,就需要切换:

[java] private static boolean shouldChangeApn(final Context context){

final String wapId = getWapApnId(context);

String apnId = getApn(context);

//若当前apn不是wap,则切换至wap

if(!wapId.equals(apnId)){

APN_NET_ID = apnId;

setApn(context,wapId);

//切换apn需要一定时间,先让等待2秒

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

return true;

}

return false;

}

private static boolean shouldChangeApn(final Context context){

final String wapId = getWapApnId(context);

String apnId = getApn(context);

//若当前apn不是wap,则切换至wap

if(!wapId.equals(apnId)){

APN_NET_ID = apnId;

setApn(context,wapId);

//切换apn需要一定时间,先让等待2秒

try {

Thread.sleep(2000);

} catch (InterruptedException e) {

e.printStackTrace();

}

return true;

}

return false;

}

所有的apn信息都是存在数据表里,可以通过adb pull data/data/com.android.providers.telephony d:/ 直接拷出来,不过前提是手机有root权限:[java] private static String getApn(Context context){

ContentResolver resoler = context.getContentResolver();

String[] projection = new String[]{"_id"};

Cursor cur = resoler.query(Uri.parse("content://telephony/carriers/preferapn"),projection, null, null, null);

String apnId = null;

if(cur!=null&&cur.moveToFirst()){

do {

apnId = cur.getString(cur.getColumnIndex("_id"));

} while (cur.moveToNext());

}

return apnId;

}

/**

* 设置接入点

* @param id

*/

private static void setApn(Context context ,String id){

Uri uri = Uri.parse("content://telephony/carriers/preferapn");

ContentResolver resolver = context.getContentResolver();

ContentValues values = new ContentValues();

values.put("apn_id", id);

resolver.update(uri, values, null, null);

}

private static String APN_NET_ID = null;

/**

* 取到wap接入點的id

* @return

*/

private static String getWapApnId(Context context){

ContentResolver contentResolver = context.getContentResolver();

String[] projection = new String[]{"_id","proxy"};

Cursor cur = contentResolver.query(Uri.parse("content://telephony/carriers"), projection, "current = 1", null, null);

if(cur!=null&&cur.moveToFirst()){

do {

String id = cur.getString(0);

String proxy = cur.getString(1);

if(!TextUtils.isEmpty(proxy)){

return id;

}

} while (cur.moveToNext());

}

return null;

}

private static String getApn(Context context){

ContentResolver resoler = context.getContentResolver();

String[] projection = new String[]{"_id"};

Cursor cur = resoler.query(Uri.parse("content://telephony/carriers/preferapn"),projection, null, null, null);

String apnId = null;

if(cur!=null&&cur.moveToFirst()){

do {

apnId = cur.getString(cur.getColumnIndex("_id"));

} while (cur.moveToNext());

}

return apnId;

}

/**

* 设置接入点

* @param id

*/

private static void setApn(Context context ,String id){

Uri uri = Uri.parse("content://telephony/carriers/preferapn");

ContentResolver resolver = context.getContentResolver();

ContentValues values = new ContentValues();

values.put("apn_id", id);

resolver.update(uri, values, null, null);

}

private static String APN_NET_ID = null;

/**

* 取到wap接入點的id

* @return

*/

private static String getWapApnId(Context context){

ContentResolver contentResolver = context.getContentResolver();

String[] projection = new String[]{"_id","proxy"};

Cursor cur = contentResolver.query(Uri.parse("content://telephony/carriers"), projection, "current = 1", null, null);

if(cur!=null&&cur.moveToFirst()){

do {

String id = cur.getString(0);

String proxy = cur.getString(1);

if(!TextUtils.isEmpty(proxy)){

return id;

}

} while (cur.moveToNext());

}

return null;

}

取wap接入点的id方法中,就是从carriers表中读取到current=1的条目,只有这种条目能够显示在手机的apn设置中,即:



接下来这个方法,是处理发彩信请求:

[java] private static boolean sendMMMS(List<String> list,final Context context, byte[] pdu) throws Exception {

// HDR_AVLUE_ACCEPT_LANGUAGE = getHttpAcceptLanguage();

if(list==null){

myHandler.post(new Runnable() {

@Override

public void run() {

Toast.makeText(context, "找不到sim卡", Toast.LENGTH_LONG).show();

}

});

return false;

}

String mmsUrl = (String) list.get(0);

String mmsProxy = (String) list.get(1);

HttpClient client = null;

try {

URI hostUrl = new URI(mmsUrl);

HttpHost target = new HttpHost(hostUrl.getHost(),

hostUrl.getPort(), HttpHost.DEFAULT_SCHEME_NAME);

client = AndroidHttpClient.newInstance("Android-Mms/2.0");

HttpPost post = new HttpPost(mmsUrl);

ByteArrayEntity entity = new ByteArrayEntity(pdu);

entity.setContentType("application/vnd.wap.mms-message");

post.setEntity(entity);

post.addHeader(HDR_KEY_ACCEPT, HDR_VALUE_ACCEPT);

post.addHeader(HDR_KEY_ACCEPT_LANGUAGE, HDR_VALUE_ACCEPT_LANGUAGE);

HttpParams params = client.getParams();

HttpProtocolParams.setContentCharset(params, "UTF-8");

ConnRouteParams.setDefaultProxy(params, new HttpHost(mmsProxy,

80));

HttpResponse response = client.execute(target, post);

StatusLine status = response.getStatusLine();

System.out.println("status : " + status.getStatusCode());

if (status.getStatusCode() != 200) {

throw new IOException("HTTP error: " + status.getReasonPhrase());

}

//彩信发送完毕后检查是否需要把接入点切换回来

if(null!=APN_NET_ID){

setApn(context,APN_NET_ID);

}

return true;

} catch (Exception e) {

e.printStackTrace();

Log.d(TAG, "彩信发送失败:"+e.getMessage());

//发送失败处理

}

return false;

}

private static boolean sendMMMS(List<String> list,final Context context, byte[] pdu) throws Exception {

// HDR_AVLUE_ACCEPT_LANGUAGE = getHttpAcceptLanguage();

if(list==null){

myHandler.post(new Runnable() {

@Override

public void run() {

Toast.makeText(context, "找不到sim卡", Toast.LENGTH_LONG).show();

}

});

return false;

}

String mmsUrl = (String) list.get(0);

String mmsProxy = (String) list.get(1);

HttpClient client = null;

try {

URI hostUrl = new URI(mmsUrl);

HttpHost target = new HttpHost(hostUrl.getHost(),

hostUrl.getPort(), HttpHost.DEFAULT_SCHEME_NAME);

client = AndroidHttpClient.newInstance("Android-Mms/2.0");

HttpPost post = new HttpPost(mmsUrl);

ByteArrayEntity entity = new ByteArrayEntity(pdu);

entity.setContentType("application/vnd.wap.mms-message");

post.setEntity(entity);

post.addHeader(HDR_KEY_ACCEPT, HDR_VALUE_ACCEPT);

post.addHeader(HDR_KEY_ACCEPT_LANGUAGE, HDR_VALUE_ACCEPT_LANGUAGE);

HttpParams params = client.getParams();

HttpProtocolParams.setContentCharset(params, "UTF-8");

ConnRouteParams.setDefaultProxy(params, new HttpHost(mmsProxy,

80));

HttpResponse response = client.execute(target, post);

StatusLine status = response.getStatusLine();

System.out.println("status : " + status.getStatusCode());

if (status.getStatusCode() != 200) {

throw new IOException("HTTP error: " + status.getReasonPhrase());

}

//彩信发送完毕后检查是否需要把接入点切换回来

if(null!=APN_NET_ID){

setApn(context,APN_NET_ID);

}

return true;

} catch (Exception e) {

e.printStackTrace();

Log.d(TAG, "彩信发送失败:"+e.getMessage());

//发送失败处理

}

return false;

}

发彩信程序主入口:

[java] private static String HDR_VALUE_ACCEPT_LANGUAGE = "";

private static final String HDR_KEY_ACCEPT = "Accept";

private static final String HDR_KEY_ACCEPT_LANGUAGE = "Accept-Language";

private static final String HDR_VALUE_ACCEPT = "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic";

/**

* 发彩信接口 by liuhanzhi

* @param context

* @param phone 手机号

* @param subject 主题

* @param text 文字

* @param imagePath 图片路径

* @param audioPath 音频路径

*/

public static void send(final Context context,String phone,String subject,String text,String imagePath,String audioPath) {

// String subject = "测试彩信";

Log.v("MmsTestActivity", subject);

// String recipient = "18911722352";// 138xxxxxxx

SendReq sendRequest = new SendReq();

EncodedStringValue[] sub = EncodedStringValue.extract(subject);

if (sub != null && sub.length > 0) {

sendRequest.setSubject(sub[0]);

}

EncodedStringValue[] phoneNumbers = EncodedStringValue

.extract(phone);

if (phoneNumbers != null && phoneNumbers.length > 0) {

sendRequest.addTo(phoneNumbers[0]);

}

PduBody pduBody = new PduBody();

if(!TextUtils.isEmpty(text)){

PduPart partPdu3 = new PduPart();

partPdu3.setCharset(CharacterSets.UTF_8);

partPdu3.setName("mms_text.txt".getBytes());

partPdu3.setContentType("text/plain".getBytes());

partPdu3.setData(text.getBytes());

pduBody.addPart(partPdu3);

}

if(!TextUtils.isEmpty(imagePath)){

PduPart partPdu = new PduPart();

partPdu.setCharset(CharacterSets.UTF_8);

partPdu.setName("camera.jpg".getBytes());

partPdu.setContentType("image/png".getBytes());

// partPdu.setDataUri(Uri.parse("http://www.2cto.com/uploadfile/2012/0414/20120414101424728.jpg"));

partPdu.setDataUri(Uri.fromFile(new File(imagePath)));

pduBody.addPart(partPdu);

}

if(!TextUtils.isEmpty(audioPath)){

PduPart partPdu2 = new PduPart();

partPdu2.setCharset(CharacterSets.UTF_8);

partPdu2.setName("speech_test.amr".getBytes());

partPdu2.setContentType("audio/amr".getBytes());

// partPdu2.setContentType("audio/amr-wb".getBytes());

// partPdu2.setDataUri(Uri.parse("file://mnt//sdcard//.lv//audio//1326786209801.amr"));

partPdu2.setDataUri(Uri.fromFile(new File(audioPath)));

pduBody.addPart(partPdu2);

}

sendRequest.setBody(pduBody);

final PduComposer composer = new PduComposer(context, sendRequest);

final byte[] bytesToSend = composer.make();

final List<String> list = getSimMNC(context);

Thread t = new Thread(new Runnable() {

@Override

public void run() {

//因为在切换apn过程中需要一定时间,所以需要加上一个重试操作

int retry = 0;

do {

Log.d(TAG, "重试次数:"+(retry+1));

try {

if (sendMMMS(list, context, bytesToSend)) {

myHandler.post(new Runnable() {

@Override

public void run() {

Toast.makeText(context, "彩信发送成功!",

Toast.LENGTH_LONG).show();

}

});

return;

}

retry++;

Thread.sleep(2000);

} catch (Exception e) {

e.printStackTrace();

}

} while (retry < 5);

myHandler.post(new Runnable() {

@Override

public void run() {

Toast.makeText(context, "彩信发送失败!", Toast.LENGTH_LONG).show();

}

});

}

});

t.start();

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: