package 列表处理dao;
import android.content.ContentUris;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.provider.Telephony;
import android.util.Log;
import android.widget.Toast;
import com.android.mms.MmsApp;
import com.android.mms.R;
import com.android.mms.data.Contact;
import com.android.mms.data.RecipientIdCache;
import com.android.mms.data.WorkingMessage;
import com.android.mms.model.SlideshowModel;
import com.google.android.mms.pdu.PduBody;
import com.vogtec.sdk.utils.L;
import com.vogtec.sms.MmsListActivity;
import com.vogtec.sms.Tools.CustomThreadPool;
import com.vogtec.sms.Tools.FileUtils;
import com.vogtec.sms.bean.MmsBean;
import java.util.ArrayList;
import java.util.List;
/**
* 彩信数据管理
* Create by Sage Luo
* on 2020/12/16 0016 09:02
*/
public class MmsDao {
private final static Uri CONTENT_URI_PART = Uri.parse("content://mms/part"); //彩信附件表
private static final MmsDao instance = new MmsDao();
// private final Map<String, MmsBean> mmsBeanMap = new HashMap<>();
private List<MmsBean> mmsBeanList = new ArrayList<>();
private OnMmsChangeListener onMmsChangeListener;
private boolean isInit;
private MmsContentObserver mmsContentObserver;
public static MmsDao getInstance() {
return instance;
}
public void init (Context context) {
if (!isInit) {
updateAll(context);
mmsContentObserver = new MmsContentObserver(new Handler(context.getApplicationContext().getMainLooper()), context);
context.getApplicationContext().getContentResolver().registerContentObserver(Telephony.Mms.Inbox.CONTENT_URI, true, mmsContentObserver);
isInit = true;
}
}
public void updateAll(Context context) {
mmsBeanList.clear();
CustomThreadPool.get().execute(() -> {
try (Cursor cursor = context.getApplicationContext().getContentResolver().query(Telephony.Mms.Inbox.CONTENT_URI, null, null, null, "date desc")) {
int count = 0;
if (cursor.moveToFirst()) {
do {
// Log.e("Sage Text", "count = " + (++count));
int idColumn = cursor.getColumnIndex("_id");
int threadIdColumn = cursor.getColumnIndex("thread_id");
int dateColumn = cursor.getColumnIndex("date");
// int msgBoxColumn = cursor.getColumnIndex("msg_box");
int readColumn = cursor.getColumnIndex("read");
// int seenColumn = cursor.getColumnIndex("seen");
long id = cursor.getInt(idColumn);
long threadId = cursor.getLong(threadIdColumn);
long date = cursor.getLong(dateColumn) * 1000;
int read = cursor.getInt(readColumn);
String subject = cursor.getString(cursor.getColumnIndex("sub"));//彩信主题
String address = RecipientIdCache.getSingleAddressFromCanonicalAddressInDb(context, threadId + "");
boolean isHasVideo = false;
boolean isHasAudio = false;
boolean isHasImage = false;
String bodyStr = "";
try (Cursor cPart = context.getContentResolver().query(CONTENT_URI_PART, null, "mid=?", new String[]{String.valueOf(id)}, null)) {
//根据彩信ID查询彩信的附件
String[] coloumns;
String[] values = null;
if (cPart.moveToFirst()) {
do {
coloumns = cPart.getColumnNames();
if (values == null)
values = new String[coloumns.length];
for (int i = 0; i < cPart.getColumnCount(); i++) {
values[i] = cPart.getString(i);
}
if (values[3].startsWith("text/")) { // 文字
// 获取彩信文字
if (values[12] != null) {//所以该处需判断一下,如果_date为null,可直接设置内容为"text"
bodyStr = FileUtils.getMmsText(values[0], context);
} else {
bodyStr = values[13];
}
} else if (values[3].startsWith("image/")) {//图片附件
isHasImage = true;
} else if (values[3].startsWith("audio/")) { // 音频附件
isHasAudio = true;
} else if (values[3].startsWith("video/")) { // 视频附件
isHasVideo = true;
}
} while (cPart.moveToNext());
}
} catch (RuntimeException e) {
L.e(e.getMessage());
}
String sender = Contact.get(address, false).getName();
String phone = Contact.get(address, false).getNumber();
MmsBean mmsBean = new MmsBean(id, read, date, subject, sender, phone);
mmsBean.setPartContent(bodyStr);
mmsBean.setHasVideo(isHasVideo);
mmsBean.setHasAudio(isHasAudio);
mmsBean.setHasImage(isHasImage);
mmsBean.setThreadId(threadId);
mmsBeanList.add(mmsBean);
if ((++count) % 10 == 0)
notifyDataChanged(context, false);
} while (cursor.moveToNext());
if (mmsBeanList.size() > 0 && (count % 10) != 0)
notifyDataChanged(context, false);
}
} catch (Exception e) {
e.printStackTrace();
}
});
}
private void notifyDataChanged(Context context, boolean isNew) {
new Handler(context.getMainLooper()).post(() -> {
if (onMmsChangeListener != null) {
onMmsChangeListener.mmsChanged(mmsBeanList, isNew);
}
});
}
/**
* 获取彩信数据集合
*/
public List<MmsBean> getMmsBeanList(Context context) {
if (!isInit) {
init(context);
} else if (mmsBeanList.size() == 0) {
updateAll(context);
}
return mmsBeanList;
}
public interface OnMmsChangeListener {
void mmsChanged(List<MmsBean> mmsBeanList, boolean isNew);
}
public void setOnMmsChangeListener(OnMmsChangeListener onMmsChangeListener) {
this.onMmsChangeListener = onMmsChangeListener;
}
private static class MmsContentObserver extends ContentObserver {
// content://mms/1608170134281/part 附件标志
private final Context context;
private boolean isHasPart;
public MmsContentObserver(Handler handler, Context context) {
super(handler);
this.context = context;
}
@Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
Log.i("Sage Test", "uri = " + uri);
if (uri != null) {
if (uri.toString().startsWith("content://mms/inbox") && isHasPart) {
isHasPart = false;
CustomThreadPool.get().execute(() -> instance.updateByUri(uri, context));
} else if (uri.toString().startsWith("content://mms") && uri.toString().endsWith("/part"))
isHasPart = true;
else if (uri.toString().startsWith("content://mms/outbox"))
Toast.makeText(context, R.string.strOk, Toast.LENGTH_SHORT).show();
}
}
}
private void updateByUri(Uri uri, Context context) {
try (Cursor cursor = context.getContentResolver().query(uri, null, null, null)) {
if (cursor.moveToFirst()) {
int idColumn = cursor.getColumnIndex("_id");
int threadIdColumn = cursor.getColumnIndex("thread_id");
int dateColumn = cursor.getColumnIndex("date");
// int msgBoxColumn = cursor.getColumnIndex("msg_box");
int readColumn = cursor.getColumnIndex("read");
long id = cursor.getInt(idColumn);
long threadId = cursor.getLong(threadIdColumn);
long date = cursor.getLong(dateColumn) * 1000;
int read = cursor.getInt(readColumn);
String subject = cursor.getString(cursor.getColumnIndex("sub"));//彩信主题
String address = RecipientIdCache.getSingleAddressFromCanonicalAddressInDb(context, threadId + "");
boolean isHasVideo = false;
boolean isHasAudio = false;
boolean isHasImage = false;
String bodyStr = "";
try (Cursor cPart = context.getContentResolver().query(CONTENT_URI_PART, null, "mid=?", new String[]{String.valueOf(id)}, null)) {
//根据彩信ID查询彩信的附件
String[] coloumns;
String[] values = null;
if (cPart.moveToFirst()) {
do {
coloumns = cPart.getColumnNames();
if (values == null)
values = new String[coloumns.length];
for (int i = 0; i < cPart.getColumnCount(); i++) {
values[i] = cPart.getString(i);
}
if (values[3].startsWith("text/")) { // 文字
// 获取彩信文字
if (values[12] != null) {//所以该处需判断一下,如果_date为null,可直接设置内容为"text"
bodyStr = FileUtils.getMmsText(values[0], context);
} else {
bodyStr = values[13];
}
} else if (values[3].startsWith("image/")) {//图片附件
isHasImage = true;
} else if (values[3].startsWith("audio/")) { // 音频附件
isHasAudio = true;
} else if (values[3].startsWith("video/")) { // 视频附件
isHasVideo = true;
}
} while (cPart.moveToNext());
}
} catch (RuntimeException e) {
L.e(e.getMessage());
}
String sender = Contact.get(address, false).getName();
String phone = Contact.get(address, false).getNumber();
MmsBean mmsBean = new MmsBean(id, read, date, subject, sender, phone);
mmsBean.setPartContent(bodyStr);
mmsBean.setHasVideo(isHasVideo);
mmsBean.setHasAudio(isHasAudio);
mmsBean.setHasImage(isHasImage);
mmsBean.setThreadId(threadId);
boolean isHas = false;
for (int i = 0; i < mmsBeanList.size(); i++) {
MmsBean mb = mmsBeanList.get(i);
if (mb.getId() == id) {
mmsBeanList.set(i, mmsBean);
isHas = true;
break;
}
}
if (!isHas) {
List<MmsBean> cacheList = new ArrayList<>();
cacheList.add(mmsBean);
cacheList.addAll(mmsBeanList);
mmsBeanList = cacheList;
}
}
notifyDataChanged(context, true);
} catch (Exception e) {
e.printStackTrace();
}
}
public void unregisterMmsDao(Context context) {
if (mmsContentObserver != null)
context.getApplicationContext().getContentResolver().unregisterContentObserver(mmsContentObserver);
}
public void deleteOneData(Context context, long _id) {
CustomThreadPool.get().execute(() -> {
try {
PduBody body = null;
SlideshowModel slideModels = null;
try {
body = SlideshowModel.getPduBody(context, ContentUris.withAppendedId(Telephony.Mms.Inbox.CONTENT_URI, _id));
slideModels = SlideshowModel.createFromPduBody(context, body);
WorkingMessage.removeThumbnailsFromCache(slideModels);
MmsApp.getApplication().getPduLoaderManager().
removePdu(ContentUris.withAppendedId(Telephony.Mms.Inbox.CONTENT_URI, _id));
context.getContentResolver().delete(ContentUris.withAppendedId(Telephony.Mms.Inbox.CONTENT_URI, _id), null, null);
} catch (Exception e) {
e.printStackTrace();
}
updateAll(context);
} catch (Exception e) {
e.printStackTrace();
}
});
}
public void deleteAllData(Context context) {
CustomThreadPool.get().execute(() -> {
try {
for (MmsBean mmsBean : mmsBeanList) {
PduBody body = null;
SlideshowModel slideModels = null;
try {
body = SlideshowModel.getPduBody(context, ContentUris.withAppendedId(Telephony.Mms.Inbox.CONTENT_URI, mmsBean.getId()));
slideModels = SlideshowModel.createFromPduBody(context, body);
WorkingMessage.removeThumbnailsFromCache(slideModels);
MmsApp.getApplication().getPduLoaderManager().
removePdu(ContentUris.withAppendedId(Telephony.Mms.Inbox.CONTENT_URI, mmsBean.getId()));
} catch (Exception e) {
e.printStackTrace();
}
}
updateAll(context);
} catch (Exception e) {
e.printStackTrace();
}
});
}
}
package 彩信显示;
import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Movie;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.BitmapDrawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.provider.ContactsContract;
import android.provider.Telephony;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListPopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
import com.android.mms.R;
import com.android.mms.data.WorkingMessage;
import com.vogtec.sdk.constans.MM;
import com.vogtec.sdk.ui.activity.BaseActivity;
import com.vogtec.sdk.ui.view.GifView;
import com.vogtec.sdk.utils.AppUtils;
import com.vogtec.sdk.utils.L;
import com.vogtec.sdk.utils.T;
import com.vogtec.sdk.utils.Utils;
import com.vogtec.sdk.view.MyEditTextView;
import com.vogtec.sms.Tools.BitmapTools;
import com.vogtec.sms.Tools.CustomThreadPool;
import com.vogtec.sms.Tools.FileUtils;
import com.vogtec.sms.Tools.MmsTools;
import com.vogtec.sms.Tools.SmsTools;
import com.vogtec.sms.bean.MediaRecognize;
import com.vogtec.sms.bean.MmsBean;
import com.vogtec.sms.bean.MmsMediaPart;
import com.vogtec.sms.dao.MmsDao;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* 彩信收件箱
* Create by Sage Luo
* on 2020/12/15 0015 14:04
*/
public class MmsDetailActivity_2 extends BaseActivity {
private TextView tvName, tvSubTitle, tvPhoneNum;
private MmsBean mmsBean;
private LinearLayout llMedia;
private final List<Bitmap> bitmapList = new ArrayList<>();
private int screenWidth, screenHeight;
private RelativeLayout rlMmsDetail;
private MediaRecognize videoRecognize;
private MediaRecognize audioRecognize;
private MediaRecognize imageRecognize;
private VideoView videoView;
private FrameLayout flMedia;
// private final Uri CONTENT_URI = Uri.parse("content://mms/inbox"); //彩信收件箱
private final static Uri CONTENT_URI_PART = Uri.parse("content://mms/part"); //彩信附件表
/**
* typeTag:(1:收件箱,2:发件箱,3:草稿箱)
*/
public static final String TYPE_TAG = "typeTag";
private final static int[] MENU_NORMAL = {R.string.replay_sms, R.string.sned_sms, R.string.forward_sms, R.string.make_call, R.string.delete};
private final static int[] MENU_WITH_MEDIA = {R.string.play, R.string.replay_sms, R.string.forward_sms, R.string.sned_sms, R.string.make_call, R.string.delete};
private AnimationDrawable audioAnimation;
private MediaPlayer audioPlayer;
private final StringBuilder stringBuilder = new StringBuilder();
private final List<MmsMediaPart> mediaParts = new ArrayList<>();
private List<MmsMediaPart> audios = new ArrayList<>();
private List<MmsMediaPart> videos = new ArrayList<>();
private List<MmsMediaPart> gifs = new ArrayList<>();
private List<MmsMediaPart> pictures = new ArrayList<>();
private Bitmap[] imageBitmaps;
private RelativeLayout rlInputRecipient;
private MyEditTextView etTo;
private ListPopupWindow mPopup;
private TextView tips;
final ArrayList<ContactBean> contactBeans = new ArrayList<>();
private int fromType = 0;
private FilterTask filterTask = new FilterTask();
private final MyAdapter adapter = new MyAdapter(contactBeans);
private final static int PRE_MESSAGE_SENT = 0x111;
private final static int MESSAGE_SENT = 0x112;
private final static int PENDING_MESSAGES_REACHED = 0x113;
private final static int ATTACHMENT_ERROR = 0x114;
private final static int PRE_MMS_SENT = 0x115;
// private boolean isExcuting;
// private boolean isExcuteCancel;
@Override
protected int getLayoutResId() {
return R.layout.activity_mms_detail_2;
}
@Override
protected void initHeadBtmAndView() {
tvName = findView(R.id.tv_name);
tvPhoneNum = findView(R.id.tvPhoneNum);
tvSubTitle = findView(R.id.tvSubTitle);
llMedia = findView(R.id.llMedia);
rlMmsDetail = findView(R.id.rlMmsDetail);
rlInputRecipient = findViewById(R.id.rlInputRecipient);
tips = findViewById(R.id.tips);
etTo = findView(R.id.et_number);
setBtmLeftRightString(R.string.menu, R.string.back);
initData();
}
private void initData() {
mmsBean = (MmsBean) getIntent().getSerializableExtra("data");
showMms(this);
tvName.setText(mmsBean.getSender());
tvPhoneNum.setText(mmsBean.getPhone());
if (!TextUtils.isEmpty(mmsBean.getSubject())) {
tvSubTitle.setText(mmsBean.getSubject());
tvSubTitle.setVisibility(View.VISIBLE);
}
int[] screenSize = getScreenSize();
screenWidth = screenSize[0];
screenHeight = screenSize[1];
initContact();
}
private void showMms(Context context) {
CustomThreadPool.get().execute(() -> {
ContentValues cvs = new ContentValues();
cvs.put("read", 1);
getContentResolver().update(Telephony.Mms.CONTENT_URI, cvs, "_id=?", new String[]{String.valueOf(mmsBean.getId())});
List<Bitmap> bitmaps = new ArrayList<>();
try (Cursor cPart = getContentResolver().query(CONTENT_URI_PART, null, "mid=?", new String[]{String.valueOf(mmsBean.getId())}, null)) {
//根据彩信ID查询彩信的附件
String bodyStr = "";
String[] coloumns;
String[] values = null;
int count = 0;
if (cPart.moveToFirst()) {
do {
coloumns = cPart.getColumnNames();
if (values == null)
values = new String[coloumns.length];
for (int i = 0; i < cPart.getColumnCount(); i++) {
values[i] = cPart.getString(i);
}
if (values[3].startsWith("text/")) { // 文字
// 获取彩信文字
if (values[12] != null) {//所以该处需判断一下,如果_date为null,可直接设置内容为"text"
bodyStr = FileUtils.getMmsText(values[0], MmsDetailActivity_2.this);
} else {
bodyStr = values[13];
}
showContent(bodyStr);
} else if (values[3].startsWith("image/")) {//图片附件
if (values[3].equals("image/gif")) {
showGif(values[0]);
} else {
Bitmap bitmap = getMmsImage(values[0]);
bitmaps.add(bitmap);
if (bitmap == null) continue;
int[] size = getBetterSize(bitmap.getWidth(), bitmap.getHeight());
if (size[2] > 1) {
bitmap = BitmapTools.getBitmap(bitmap, size[2]);
}
showBitmap(size[0], size[1], bitmap);
}
} else if (values[3].startsWith("audio/")) { // 音频附件
// getAudio(values[0], values[4]);
showAudioUi(values[0]);
} else if (values[3].startsWith("video/")) { // 视频附件
Bitmap thumbnail = BitmapTools.getVideoThumbnailPicture(context, Uri.parse("content://mms/part/" + values[0]));
showVideoUi(values[0], thumbnail);
}
if (!values[3].equals("application/smil") && !values[3].startsWith("text/")) {
addMediaPart(values[0], values[3], values[4], bitmaps);
}
} while (cPart.moveToNext());
}
} catch (RuntimeException e) {
L.e(e.getMessage());
}
});
}
private void addMediaPart(String _id, String mediaType, String mediaName, List<Bitmap> bitmaps) {
Uri partURI = Uri.parse("content://mms/part/" + _id );
try (InputStream is = getContentResolver().openInputStream(partURI)) {
byte[] bytes = FileUtils.getBytesByInputStream(is);
MmsDetailActivity_2.this.runOnUiThread(() -> {
MmsMediaPart mmsMediaPart = new MmsMediaPart(bytes, mediaType, mediaName, partURI);
if (mediaType.startsWith("audio/")) {
audios.add(mmsMediaPart);
mmsMediaPart.setAttachmentType(WorkingMessage.AUDIO);
} else if (mediaType.startsWith("video/")) {
videos.add(mmsMediaPart);
mmsMediaPart.setAttachmentType(WorkingMessage.VIDEO);
} else if (mediaType.equals("image/gif")) {
gifs.add(mmsMediaPart);
mmsMediaPart.setAttachmentType(WorkingMessage.IMAGE);
} else if ((mediaType.startsWith("image/"))) {
imageBitmaps = new Bitmap[bitmaps.size()];
for (int i = 0; i < imageBitmaps.length; i++) {
imageBitmaps[i] = bitmaps.get(i);
}
pictures.add(mmsMediaPart);
mmsMediaPart.setAttachmentType(WorkingMessage.IMAGE);
} else if (mediaType.startsWith("text/")) {
mmsMediaPart.setAttachmentType(WorkingMessage.TEXT);
}
mediaParts.add(mmsMediaPart);
});
} catch (Exception e) {
e.printStackTrace();
}
}
private void showBitmap(final int width, final int height, final Bitmap bitmap) {
runOnUiThread(() -> {
bitmapList.add(bitmap);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(width, height);
layoutParams.bottomMargin = 10;
layoutParams.gravity = Gravity.CENTER;
FrameLayout frameLayout = new FrameLayout(MmsDetailActivity_2.this);
frameLayout.setBackgroundResource(R.drawable.selector_item_bg_white_orange);
frameLayout.setLayoutParams(layoutParams);
frameLayout.setPadding(1,1,1,1);
frameLayout.setFocusableInTouchMode(true);
llMedia.addView(frameLayout);
ImageView imageView = new ImageView(MmsDetailActivity_2.this);
FrameLayout.LayoutParams ivParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
imageView.setLayoutParams(ivParams);
frameLayout.addView(imageView);
imageView.setImageBitmap(bitmap);
imageView.setBackgroundResource(R.color.white);
});
}
private void showContent(final String content) {
runOnUiThread(() -> {
stringBuilder.append(content);
TextView textView = new TextView(MmsDetailActivity_2.this);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.bottomMargin = 10;
textView.setLayoutParams(layoutParams);
textView.setTextAppearance(MmsDetailActivity_2.this, R.style.SubContentStyle);
llMedia.addView(textView);
textView.setText(content);
});
}
private void showGif(final String id) {
runOnUiThread(() -> {
Uri partURI = Uri.parse("content://mms/part/" + id );
try (InputStream is = getContentResolver().openInputStream(partURI)) {
Movie movie = Movie.decodeStream(is);
GifView gifView = new GifView(MmsDetailActivity_2.this);
gifView.setPaused(false);
gifView.setMovie(movie);
int[] size = getBetterSize(movie.width(), movie.height());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(size[0], size[1]);
params.gravity = Gravity.CENTER;
FrameLayout frameLayout = new FrameLayout(MmsDetailActivity_2.this);
frameLayout.setBackgroundResource(R.drawable.selector_item_bg_white_orange);
frameLayout.setLayoutParams(params);
frameLayout.setPadding(1, 1, 1, 1);
frameLayout.setFocusableInTouchMode(true);
FrameLayout.LayoutParams gvParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
gifView.setLayoutParams(gvParams);
frameLayout.addView(gifView);
gifView.setBackgroundResource(R.color.white);
llMedia.addView(frameLayout);
} catch (IOException e) {
e.printStackTrace();
}
});
}
private void showVideoUi(final String _id, final Bitmap bitmap) {
runOnUiThread(() -> {
bitmapList.add(bitmap);
FrameLayout frameLayout = new FrameLayout(MmsDetailActivity_2.this);
LinearLayout.LayoutParams fParams;
int padding = llMedia.getPaddingLeft() + llMedia.getPaddingRight();
fParams = new LinearLayout.LayoutParams(screenWidth - padding, screenWidth / 3 * 2);
fParams.gravity = Gravity.CENTER_HORIZONTAL;
fParams.bottomMargin = 10;
frameLayout.setBackgroundResource(R.drawable.selector_item_bg_balck_orange);
frameLayout.setLayoutParams(fParams);
frameLayout.setPadding(2,2,2,2);
// 缩略图
ImageView ivBg = new ImageView(MmsDetailActivity_2.this);
FrameLayout.LayoutParams ibParams;
ibParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
if (bitmap == null) {
ivBg.setBackgroundResource(android.R.color.background_dark);
} else {
ivBg.setBackground(new BitmapDrawable(getResources(), bitmap));
}
ibParams.gravity = Gravity.CENTER;
ivBg.setLayoutParams(ibParams);
ivBg.setScaleType(ImageView.ScaleType.CENTER_CROP);
frameLayout.addView(ivBg);
// 播放按钮
ImageView imageView = new ImageView(MmsDetailActivity_2.this);
FrameLayout.LayoutParams iParams = new FrameLayout.LayoutParams(60, 60);
iParams.gravity = Gravity.CENTER;
imageView.setLayoutParams(iParams);
imageView.setImageResource(R.drawable.video_small);
frameLayout.addView(imageView);
llMedia.addView(frameLayout);
frameLayout.setFocusableInTouchMode(true);
frameLayout.setOnFocusChangeListener((view, b) -> {
if (b) {
videoRecognize = new MediaRecognize(_id, MediaRecognize.VIDEO);
} else {
videoRecognize = null;
}
});
});
}
private void showAudioUi(String _id) {
runOnUiThread(() -> {
FrameLayout frameLayout = new FrameLayout(MmsDetailActivity_2.this);
LinearLayout.LayoutParams fParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 50);
fParams.bottomMargin = 10;
frameLayout.setBackgroundResource(R.drawable.selector_audio_background);
frameLayout.setLayoutParams(fParams);
frameLayout.setPadding(10, 10, 10, 10);
ImageView imageView = new ImageView(MmsDetailActivity_2.this);
FrameLayout.LayoutParams iParams = new FrameLayout.LayoutParams(30, 30);
iParams.gravity = Gravity.CENTER_VERTICAL;
imageView.setLayoutParams(iParams);
imageView.setImageDrawable(getResources().getDrawable(R.drawable.animation_paly_audio));
frameLayout.addView(imageView);
llMedia.addView(frameLayout);
frameLayout.setFocusableInTouchMode(true);
frameLayout.setOnFocusChangeListener(new OnAudioFocusChangedListener(_id, imageView));
});
}
private class OnAudioFocusChangedListener implements View.OnFocusChangeListener {
private final String _id;
private final ImageView imageView;
public OnAudioFocusChangedListener(String _id, ImageView imageView) {
this._id = _id;
this.imageView = imageView;
}
@Override
public void onFocusChange(View view, boolean b) {
if (b) {
audioRecognize = new MediaRecognize(_id, MediaRecognize.AUDIO);
audioAnimation = (AnimationDrawable) imageView.getDrawable();
} else {
stopAudio();
}
}
}
private Bitmap getMmsImage(String _id){ //读取图片附件
Uri partURI = Uri.parse("content://mms/part/" + _id );
InputStream is = null;
Bitmap bitmap=null;
try {
is = getContentResolver().openInputStream(partURI);
bitmap = BitmapFactory.decodeStream(is);
}catch (IOException e) {
e.printStackTrace();
L.e("读取图片异常"+e.getMessage());
}finally{
if (is != null){
try {
is.close();
}catch (IOException e){
L.e("读取图片异常"+e.getMessage());
}
}
}
return bitmap;
}
private int[] getScreenSize() {
DisplayMetrics outMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getRealMetrics(outMetrics);
int widthPixel = outMetrics.widthPixels;
int heightPixel = outMetrics.heightPixels;
return new int[]{widthPixel, heightPixel};
}
private int[] getBetterSize(int oWidth, int oHeight) {
int padding = llMedia.getPaddingLeft() + llMedia.getPaddingRight();
if (screenWidth - padding >= oWidth) {
return new int[]{oWidth, oHeight, 1};
} else {
int nHeight = screenWidth * oHeight / oWidth;
int dw = screenWidth - padding;
int dh = dw * nHeight / screenWidth;
return new int[] {dw, dh, oWidth / screenWidth};
}
}
@Override
public void onDestroy() {
super.onDestroy();
for (Bitmap bitmap : bitmapList) {
if (bitmap != null) {
bitmap.recycle();
}
}
if (imageBitmaps != null) {
for (Bitmap bitmap : imageBitmaps) {
if (bitmap != null)
bitmap.recycle();
}
}
}
private void initVideo() {
if (videoRecognize != null) {
flMedia = new FrameLayout(MmsDetailActivity_2.this);
flMedia.setBackgroundResource(android.R.color.background_dark);
RelativeLayout.LayoutParams fParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
fParams.addRule(RelativeLayout.ABOVE, R.id.layout_common_btm);
flMedia.setLayoutParams(fParams);
rlMmsDetail.addView(flMedia);
videoView = new VideoView(MmsDetailActivity_2.this);
Uri partURI = Uri.parse("content://mms/part/" + videoRecognize.getId());
videoView.setVideoURI(partURI);
FrameLayout.LayoutParams vParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
vParams.gravity = Gravity.CENTER;
videoView.setLayoutParams(vParams);
flMedia.addView(videoView);
videoView.setOnPreparedListener(mp -> {
if (flMedia != null && videoView != null && !videoView.isPlaying()) {
videoView.start();
setBtmLeftString(R.string.txt_pause);
}
});
videoView.setOnCompletionListener(mp -> {
//视频播放完成后的回调
if (flMedia != null && videoView != null && flMedia.isShown())
setBtmLeftString(R.string.play);
});
videoView.setOnErrorListener((mp, what, extra) -> {
//异常回调
stopVideo();
Toast.makeText(MmsDetailActivity_2.this, R.string.txt_video_format_error, Toast.LENGTH_SHORT).show();
return false;//如果方法处理了错误,则为true;否则为false。返回false或根本没有OnErrorListener,将导致调用OnCompletionListener。
});
}
}
@Override
public boolean onSoftLeftKeyEvent(KeyEvent event, boolean isActionUp) {
if (isActionUp) {
if (!handleVideo() && !handleAudio()){
showMenu(MENU_NORMAL);
}
}
return true;
}
private boolean handleAudio() {
if (audioPlayer != null) {
if (audioPlayer.isPlaying()) {
if (audioAnimation != null)
audioAnimation.stop();
audioPlayer.pause();
setBtmLeftString(R.string.play);
} else {
if (audioAnimation != null)
audioAnimation.start();
audioPlayer.start();
setBtmLeftString(R.string.txt_pause);
}
return true;
} else if (audioRecognize != null) {
showMenu(MENU_WITH_MEDIA);
return true;
}
return false;
}
private boolean handleVideo() {
if (flMedia != null && videoView != null) {
if (videoView.isPlaying()) {
videoView.pause();
setBtmLeftString(R.string.play);
} else {
videoView.start();
setBtmLeftString(R.string.txt_pause);
}
return true;
} else if (videoRecognize != null){
showMenu(MENU_WITH_MEDIA);
return true;
}
return false;
}
@Override
protected void onMenuSelect(String selectString, int position) {
if (selectString.equals(getString(R.string.play))) {
initVideo();
initAudio();
} else if (selectString.equals(getString(R.string.replay_sms)) || selectString.equals(getString(R.string.sned_sms))) {
SmsTools.sendNewSms(this, selectString.equals(getString(R.string.replay_sms)) ? 2 : 1,
selectString.equals(getString(R.string.replay_sms)) ? mmsBean.getPhone() : "");
} else if (selectString.equals(getString(R.string.forward_sms))) {
forwardMms();
} else if (selectString.equals(getString(R.string.make_call))) {
Utils.makeCall(this, mmsBean.getPhone());
} else if (selectString.equals(getString(R.string.delete))) {
MmsDao.getInstance().deleteOneData(this, mmsBean.getId());
finish();
}
}
private void forwardMms() {
etTo.setShowPop(false);
etTo.setDelKey(KeyEvent.KEYCODE_ENTER);
etTo.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
if (etTo.isFocused()) {
if (editable.toString().endsWith("; ")) {
refreshBottomTip(true);
if (mPopup != null && mPopup.isShowing()) {
mPopup.dismiss();
}
return;
}
if (filterTask != null && filterTask.getStatus() == AsyncTask.Status.RUNNING) {
filterTask.cancel(true);
filterTask = null;
}
filterTask = new FilterTask();
String find = "";
if (MM.isMfs(MM.MF_TWNSCT)) {
find = editable.toString();
} else {
if (editable.toString().contains("; ")) {
find = editable.toString().substring(editable.toString().lastIndexOf("; ") + 2);
} else {
find = editable.toString();
}
}
filterTask.execute(find);
}
}
});
etTo.setText("");
etTo.requestFocus();
etTo.setSelection(0);
if (!MM.isMfs(MM.MF_TWNSCT)) {
etTo.setSingleLine(false);
etTo.setMaxLines(20);
}
etTo.setInputStatusChangeLinster(new MyEditTextView.InputStatusChangeLinster() {
@Override
public void onInputTypeChangeed(MyEditTextView editTextView, String type) {
setBtmCenterString(type);
}
@Override
public void onDeleteableChangeed(boolean canDelete) {
if (canDelete) {
setBtmLeftString(R.string.delete);
setBtmRightString(R.string.select);
} else {
setBtmLeftString(R.string.empty_string);
setBtmRightString(R.string.back);
}
}
});
if (!MM.isMfs(MM.MF_TWNSCT)) {
etTo.setOnKeyListener((v, keyCode, event) -> {
if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT || keyCode == KeyEvent.KEYCODE_DPAD_UP) {
return true;
}
if ((keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_OK || keyCode == KeyEvent.KEYCODE_DPAD_CENTER)
&& ((mPopup != null && (!mPopup.isShowing() || mPopup.getSelectedItemPosition() == -1)) || fromType != 0)) {
if (etTo.length() > 0 && event.getAction() == KeyEvent.ACTION_UP) {
String string = etTo.getText().toString();
if (string.endsWith("; ")) {
etTo.setText(string.subSequence(0, string.length() - 2));
} else {
etTo.setText(string.subSequence(0, string.length() - 1));
}
etTo.setSelection(etTo.length());
}
return true;
} else if (keyCode >= KeyEvent.KEYCODE_0 && keyCode <= KeyEvent.KEYCODE_9) {
String[] rs = etTo.getText().toString().split("; ");
if (rs != null && rs.length > 100) {
T.makeToast(getString(R.string.new_message_contacts_limit, 100));
return true;
}
} else if (keyCode == KeyEvent.KEYCODE_STAR) {
if (!event.isDown()) {
etTo.getText().append("+");
etTo.setSelection(etTo.length());
}
return true;
}
return etTo.onKey(v, keyCode, event);
});
}
etTo.setOnFocusChangeListener((view, b) -> {
if (!b) {
if (mPopup != null && mPopup.isShowing()) {
mPopup.dismiss();
refreshBottomTip(true);
}
}
});
rlInputRecipient.setVisibility(View.VISIBLE);
tips.setVisibility(View.VISIBLE);
if (TextUtils.isEmpty(etTo.getText()))
setBtmLeftString(R.string.empty_string);
else
setBtmLeftString(R.string.delete);
}
// private final MyEditTextView.InputStatusChangeLinster inputStatusChangeLinster = ;
// private final View.OnKeyListener onKeyListener =;
private void initAudio() {
if (audioRecognize != null) {
audioPlayer = new MediaPlayer();
try {
Uri uri = Uri.parse("content://mms/part/" + audioRecognize.getId());
audioPlayer.setDataSource(this, uri);
audioPlayer.prepare();
setBtmLeftString(R.string.txt_pause);
audioPlayer.setOnCompletionListener(mediaPlayer -> {
if (audioAnimation != null) {
audioAnimation.stop();
}
setBtmLeftString(R.string.play);
});
audioPlayer.setOnErrorListener((mediaPlayer, i, i1) -> {
Toast.makeText(MmsDetailActivity_2.this, R.string.txt_audio_format_error, Toast.LENGTH_SHORT).show();
stopAudio();
return false;
});
audioPlayer.start();
if (audioAnimation != null)
audioAnimation.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@Override
public boolean onSoftRightKeyEvent(KeyEvent event, boolean isActionUp) {
if (isActionUp) {
if (rlInputRecipient.isShown()) {
stopSendMms();
} else if (flMedia != null && flMedia.isShown()) {
stopVideo();
return true;
} else if (audioPlayer != null){
stopAudio();
return true;
}
}
return super.onSoftRightKeyEvent(event, isActionUp);
}
private void stopSendMms() {
// etTo.setText("");
// isExcuteCancel = true;
rlInputRecipient.setVisibility(View.GONE);
tips.setVisibility(View.GONE);
etTo.addTextChangedListener(null);
etTo.setOnFocusChangeListener(null);
etTo.setInputStatusChangeLinster(null);
etTo.setOnKeyListener(null);
filterTask.cancel(true);
// isExcuting = false;
// rlInputRecipient = null;
// tips = null;
// etTo = null;
if (mPopup != null) mPopup.dismiss();
setBtmLeftString(R.string.menu);
}
private void stopVideo() {
flMedia.setVisibility(View.GONE);
if (videoView != null) {
videoView.setOnPreparedListener(null);
videoView.setOnCompletionListener(null);
videoView.setOnErrorListener(null);
videoView.stopPlayback();
videoView = null;
}
flMedia = null;
setBtmLeftString(R.string.menu);
}
private void stopAudio() {
if (audioAnimation != null) {
audioAnimation.stop();
}
if (audioPlayer != null) {
audioPlayer.stop();
audioPlayer.setOnErrorListener(null);
audioPlayer.setOnCompletionListener(null);
}
audioAnimation = null;
audioPlayer = null;
audioRecognize = null;
setBtmLeftString(R.string.menu);
}
private void numberPast() {
//show number if from calllog
if (getIntent().getData() != null) {
String phoneNumber = getIntent().getData().toString();
phoneNumber = phoneNumber.substring(6) + "; ";
etTo.setText(phoneNumber);
if (mPopup != null && mPopup.isShowing()) {
refreshBottomTip(true);
mPopup.dismiss();
}
}
}
public void refreshBottomTip(boolean isSendMessage) {
tips.setText(isSendMessage ? R.string.hint_send_message : R.string.hint_select);
}
private void initContact() {
CustomThreadPool.get().execute(() -> {
Cursor contactCursor = getContentResolver().query(
ContactsContract.RawContactsEntity.CONTENT_URI,
new String[]{ContactsContract.RawContactsEntity.CONTACT_ID, ContactsContract.RawContactsEntity.MIMETYPE,
ContactsContract.RawContactsEntity.DATA1, ContactsContract.RawContactsEntity.DATA2, "account_type"},
"deleted=0", null, "contact_id ASC");
// String printCursor = Utils.printCursor(contactCursor);
// contactCursor.moveToFirst();
while (contactCursor.moveToNext()) {
String idString = contactCursor.getString(0);
String mimeTypeString = contactCursor.getString(1);
String data1String = contactCursor.getString(2);
String data2String = contactCursor.getString(3);
String accountTypeString = contactCursor.getString(4);
if (contactBeans.size() == 0
|| !TextUtils.equals(contactBeans.get(contactBeans.size() - 1).id, idString)) {
contactBeans.add(new ContactBean());
}
if (TextUtils.isEmpty(contactBeans.get(contactBeans.size() - 1).id)) {
contactBeans.get(contactBeans.size() - 1).id = idString;
contactBeans.get(contactBeans.size() - 1).isFromSimCard = !TextUtils
.equals("Local Phone Account", accountTypeString);
}
if (TextUtils.equals(mimeTypeString, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)) {
contactBeans.get(contactBeans.size() - 1).name = data1String;
} else if (TextUtils.equals(mimeTypeString, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
if ("1".equals(data2String) || "2".equals(data2String)) {
contactBeans.get(contactBeans.size() - 1).mobileCallNum = data1String;
} else if ("3".equals(data2String)) {
contactBeans.get(contactBeans.size() - 1).officeCallNum = data1String;
} else if ("7".equals(data2String)) {
contactBeans.get(contactBeans.size() - 1).otherCallNum = data1String;
}
}
}
contactCursor.close();
});
}
private static class ContactBean {
private String id = "", name = "", officeCallNum = "", mobileCallNum = "", otherCallNum = "", simIndex = "";
private boolean isFromSimCard;
@Override
public String toString() {
return name + "," + officeCallNum + "," + mobileCallNum + "," + otherCallNum + ",";
}
}
@Override
public boolean onOkKeyEvent(KeyEvent event, boolean isActionUp) {
if (isActionUp) {
if (rlInputRecipient.isShown()) {
String phoneNums = etTo.getText().toString().trim();
String[] recivers = phoneNums.split(";");
if (recivers.length > 0) {
forwardMms(recivers);
}
}
}
return super.onOkKeyEvent(event, isActionUp);
}
private void forwardMms(String[] recivers) {
/*Toast.makeText(this, R.string.chat_setting_sending, Toast.LENGTH_SHORT).show();
CustomThreadPool.get().execute(() -> {
String subject = TextUtils.isEmpty(mmsBean.getSubject()) ? getString(R.string.forward_sms) : mmsBean.getSubject();
SmsTools.sendMms(MmsDetailActivity_2.this, stringBuilder.toString(), recivers, subject,
mmsBean.getThreadId(), audios, videos, gifs, imageBitmaps);
});
stopSendMms();
finish();
Intent intent = getIntent();
intent.setClass(this, MmsDetailActivity_2.class);
startActivity(intent);*/
// Uri uri = Uri.parse("content://mms/inbox/" + mmsBean.getId());
// List<String> numbers = Arrays.asList(recivers);
// String subject = TextUtils.isEmpty(mmsBean.getSubject()) ? getString(R.string.forward_sms) : mmsBean.getSubject();
// SmsTools.sendMmsBySystem(this, uri, mmsBean.getThreadId(), numbers, mmsBean.getPartContent(), subject, mediaParts,
// numbers.size() > 0, true, messageStatusListener);
try {
// Log.v("Sage Test", "彩信发送中");
Toast.makeText(this, R.string.ipmsg_send_exception, Toast.LENGTH_SHORT).show();
MmsTools.send(this, recivers[0], TextUtils.isEmpty(mmsBean.getSubject()) ? getString(R.string.forward_sms) : mmsBean.getSubject(),
mmsBean.getId());
stopSendMms();
finish();
Intent intent = getIntent();
intent.setClass(this, MmsDetailActivity_2.class);
startActivity(intent);
} catch (Exception e) {
e.printStackTrace();
}
}
// private final TextWatcher textWatcher = ;
@SuppressLint("StaticFieldLeak")
private class FilterTask extends AsyncTask<String, Void, ArrayList<ContactBean>> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// isExcuting = true;
}
@Override
protected ArrayList<ContactBean> doInBackground(String... params) {
ArrayList<ContactBean> contactBeen = new ArrayList<ContactBean>();
String tag = params[0];
if (!MM.isMfs(MM.MF_TWNSCT)) {
boolean hasChar = false;
for (int i = 0; i < tag.length(); i++) {
char charAt = tag.charAt(i);
if (!(charAt >= '0' && charAt <= '9') && charAt != '+') {
hasChar = true;
break;
}
}
if (!hasChar) {
ContactBean cb1 = new ContactBean();
cb1.name = tag;
cb1.mobileCallNum = tag;
contactBeen.add(cb1);
}
}
for (ContactBean contactBean : contactBeans) {
if (contactBean.name.toLowerCase().contains(tag.toLowerCase())) {
if (!TextUtils.isEmpty(contactBean.mobileCallNum)) {
ContactBean cb1 = new ContactBean();
cb1.name = contactBean.name;
cb1.mobileCallNum = contactBean.mobileCallNum;
contactBeen.add(cb1);
}
if (!TextUtils.isEmpty(contactBean.officeCallNum)) {
ContactBean cb2 = new ContactBean();
cb2.name = contactBean.name;
cb2.mobileCallNum = contactBean.officeCallNum;
contactBeen.add(cb2);
}
if (!TextUtils.isEmpty(contactBean.otherCallNum)) {
ContactBean cb3 = new ContactBean();
cb3.name = contactBean.name;
cb3.mobileCallNum = contactBean.otherCallNum;
contactBeen.add(cb3);
}
} else {
if (contactBean.mobileCallNum.contains(tag)) {
ContactBean cb1 = new ContactBean();
cb1.name = contactBean.name;
cb1.mobileCallNum = contactBean.mobileCallNum;
contactBeen.add(cb1);
}
if (contactBean.officeCallNum.contains(tag)) {
ContactBean cb2 = new ContactBean();
cb2.name = contactBean.name;
cb2.mobileCallNum = contactBean.officeCallNum;
contactBeen.add(cb2);
}
if (contactBean.otherCallNum.contains(tag)) {
ContactBean cb3 = new ContactBean();
cb3.name = contactBean.name;
cb3.mobileCallNum = contactBean.otherCallNum;
contactBeen.add(cb3);
}
}
}
return contactBeen;
}
@Override
protected void onPostExecute(ArrayList<ContactBean> result) {
initListPopuwindow();
if (result.size() == 0) {
ContactBean contactBean = new ContactBean();
contactBean.id = "-1";
contactBean.name = getString(R.string.input_sms_um_error_tips);
result.add(contactBean);
}
adapter.setContactBeans(result);
if (result.size() > 3) {
mPopup.setHeight(AppUtils.screenH / 2 - 7);
} else {
mPopup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
}
refreshBottomTip(false);
mPopup.show();
mPopup.getListView().setDivider(getDrawable(R.drawable.bg_divider_horizontal));
}
}
private class MyAdapter extends BaseAdapter {
ArrayList<ContactBean> contactBeans;
public MyAdapter(ArrayList<ContactBean> contactBeans) {
this.contactBeans = contactBeans;
}
public void setContactBeans(ArrayList<ContactBean> contactBeans) {
this.contactBeans = contactBeans;
notifyDataSetChanged();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(MmsDetailActivity_2.this).inflate(R.layout.simple_expandable_list_item_2,
null);
}
TextView tv1 = ((TextView) convertView.findViewById(android.R.id.text1));
TextView tv2 = (TextView) convertView.findViewById(android.R.id.text2);
if (position == 0 && !MM.isMfs(MM.MF_TWNSCT)) {
tv2.setVisibility(View.GONE);
} else {
tv2.setVisibility(View.VISIBLE);
}
tv1.setText(getItem(position).name);
tv2.setText(getItem(position).mobileCallNum);
return convertView;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public ContactBean getItem(int position) {
return this.contactBeans.get(position);
}
@Override
public int getCount() {
return this.contactBeans.size();
}
}
public void initListPopuwindow() {
if (mPopup == null) {
mPopup = new ListPopupWindow(this);
mPopup.setAdapter(adapter);
mPopup.setOnItemClickListener(contactItemClickListener);
mPopup.setAnchorView(etTo);
mPopup.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
mPopup.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
mPopup.setForceIgnoreOutsideTouch(true);
}
}
private final AdapterView.OnItemClickListener contactItemClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
// if (isExcuteCancel) return;
String mobileCallNum = ((ContactBean) mPopup.getListView().getSelectedItem()).mobileCallNum.replace(" ", "");
String ts = mobileCallNum;
if (!MM.isMfs(MM.MF_TWNSCT)) {
String textstring = etTo.getText().toString();
if (textstring.contains("; ") && (textstring.startsWith(mobileCallNum + "; ") || textstring.contains("; " + mobileCallNum + "; "))) {
T.makeToast(R.string.duplicated_recipient);
// isSelected = false;
ts = textstring.substring(0, textstring.lastIndexOf("; ")) + "; ";
etTo.setText(ts);
etTo.setSelection(etTo.length());
return;
}
if (textstring.contains("; ")) {
ts = textstring
+ mobileCallNum.substring(textstring.substring(textstring.lastIndexOf("; ") + 2).length());
ts = textstring.substring(0, textstring.lastIndexOf("; ")) + "; " + mobileCallNum;
}
ts += "; ";
}
etTo.setText(ts);
etTo.setSelection(etTo.length());
}
};
@Override
public boolean dispatchKeyEvent(int keyCode, boolean isActionUp, KeyEvent event) {
if (mPopup != null && mPopup.isShowing()) {
if (event.getKeyCode() == KeyEvent.KEYCODE_DPAD_DOWN || event.getKeyCode() == KeyEvent.KEYCODE_DPAD_UP || event.getKeyCode() == KeyEvent.KEYCODE_DPAD_CENTER
|| event.getKeyCode() == KeyEvent.KEYCODE_BACK || event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
// if (event.getAction() == KeyEvent.ACTION_UP) {
switch (event.getKeyCode()) {
case KeyEvent.KEYCODE_DPAD_DOWN:
if (event.getAction() == KeyEvent.ACTION_UP)
mPopup.setSelection(mPopup.getSelectedItemPosition() + 1);
break;
case KeyEvent.KEYCODE_DPAD_UP:
if (event.getAction() == KeyEvent.ACTION_UP)
mPopup.setSelection(mPopup.getSelectedItemPosition() - 1);
break;
case KeyEvent.KEYCODE_BACK:
if (event.getAction() == KeyEvent.ACTION_UP) {
if (etTo.getText().length() == 0) {
backUI();
return true;
}
selectInputItem();
}
return true;
case KeyEvent.KEYCODE_DPAD_CENTER:
if (event.getAction() == KeyEvent.ACTION_UP) {
selectInputItem();
}
break;
case KeyEvent.KEYCODE_ENTER:
etTo.dispatchKeyEvent(event);
break;
case KeyEvent.KEYCODE_M:
if (isActionUp)
backUI();
return true;
default:
break;
}
// }
return true;
}
}
if (rlInputRecipient.isShown() && keyCode == KeyEvent.KEYCODE_M) {
if (isActionUp)
backUI();
return true;
}
return super.dispatchKeyEvent(keyCode, isActionUp, event);
}
private void backUI() {
stopSendMms();
finish();
Intent intent = getIntent();
intent.setClass(this, MmsDetailActivity_2.class);
startActivity(intent);
}
private void selectInputItem() {
if (adapter.getCount() == 0) {
return;
}
int p = mPopup.getSelectedItemPosition();
if (p == -1) {
p = 0;
}
mPopup.setSelection(p);
ContactBean selectedItem = (ContactBean) mPopup.getListView().getSelectedItem();
if (TextUtils.equals("-1", selectedItem.id)) {//id为-1时,联系人输入错误
T.makeToast(R.string.input_sms_um_error_tips);
return;
} else {
if (!TextUtils.isEmpty(selectedItem.mobileCallNum)) {//处理输入+号的情况
if (TextUtils.equals("+", selectedItem.mobileCallNum)) {
T.makeToast(R.string.input_sms_um_error_tips);
return;
} else {
if (selectedItem.mobileCallNum.contains("+") && selectedItem.mobileCallNum.lastIndexOf("+") != 0) {
T.makeToast(R.string.input_sms_um_error_tips);
return;
}
}
}
}
contactItemClickListener.onItemClick(null, null, p, 0);
refreshBottomTip(true);
mPopup.dismiss();
}
private final WorkingMessage.MessageStatusListener messageStatusListener = new WorkingMessage.MessageStatusListener(){
private final static String TAG = "Sage Test";
@Override
public void onProtocolChanged(boolean isMms, boolean needToast) {
Log.v(TAG, "== onProtocolChanged == isMms = " + isMms);
}
@Override
public void onAttachmentChanged() {
Log.v(TAG, "== onAttachmentChanged ==");
}
@Override
public void onPreMessageSent() {
Log.v(TAG, "== onPreMessageSent ==");
handler.sendEmptyMessage(PRE_MESSAGE_SENT);
}
@Override
public void onMessageSent() {
Log.v(TAG, "== onMessageSent ==");
handler.sendEmptyMessage(MESSAGE_SENT);
}
@Override
public void onMaxPendingMessagesReached() { // 信息队列太多,不允许发送
Log.v(TAG, "== onMaxPendingMessagesReached ==");
handler.sendEmptyMessage(PENDING_MESSAGES_REACHED);
}
@Override
public void onAttachmentError(int error) {
Log.v(TAG, "== onAttachmentError ==");
handler.sendEmptyMessage(ATTACHMENT_ERROR);
}
@Override
public void onPreMmsSent() {
Log.v(TAG, "== onPreMmsSent ==");
handler.sendEmptyMessage(PRE_MMS_SENT);
}
};
private void restartThis() {
stopSendMms();
Intent intent = getIntent();
intent.setClass(this, MmsDetailActivity_2.class);
startActivity(intent);
}
@SuppressLint("HandlerLeak")
private final Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
super.handleMessage(message);
switch (message.what) {
case PRE_MESSAGE_SENT:
Utils.showProgressDialog(MmsDetailActivity_2.this, R.string.sending_message);
break;
case MESSAGE_SENT:
Utils.dismissProgressDialog();
Toast.makeText(MmsDetailActivity_2.this, R.string.strOk, Toast.LENGTH_SHORT).show();
restartThis();
break;
case PENDING_MESSAGES_REACHED:
break;
case ATTACHMENT_ERROR:
Utils.dismissProgressDialog();
// Toast.makeText(MmsDetailActivity_2.this, R.string.ipmsg_send_exception, Toast.LENGTH_SHORT).show();
restartThis();
break;
case PRE_MMS_SENT:
break;
}
}
};
}
在使用MmsTools之前可能要添加
android {
…
useLibrary ‘org.apache.http.legacy’
}
package 发送彩信工具类;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.net.http.AndroidHttpClient;
import android.provider.Telephony;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.android.mms.R;
import com.android.mms.model.SlideshowModel;
import com.google.android.mms.MmsException;
import com.google.android.mms.pdu.CharacterSets;
import com.google.android.mms.pdu.EncodedStringValue;
import com.google.android.mms.pdu.PduBody;
import com.google.android.mms.pdu.PduComposer;
import com.google.android.mms.pdu.PduPart;
import com.google.android.mms.pdu.SendReq;
import com.vogtec.sms.MmsListActivity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
/**
* Create by Sage Luo
* on 2020/12/23 0023 09:17
*/
public class MmsTools {
private final static String TAG = "Sage Test";
// 电信彩信中心url,代理,端口
// 彩信中心URL:mmsc.vnet.mobi
// WAP网关IP地址:10.0.0.200
public static String mmscUrl_ct = "http://mmsc.vnet.mobi";
public static String mmsProxy_ct = "10.0.0.200";
// 移动彩信中心url,代理,端口
// ⑧MMSC:mmsc.monternet.com
// ⑨彩信代理:010.000.000.172
public static String mmscUrl_cm = "http://mmsc.monternet.com";
public static String mmsProxy_cm = "010.000.000.172";
// 联通彩信中心url,代理,端口
// 8 MMSC:mmsc.myuni.com.cn
// 9 彩信代理:010.000.000.172
// public static String mmscUrl_uni = "http://mmsc.vnet.mobi";
// public static String mmsProxy_uni = "10.0.0.172";
public static String mmscUrl_uni = "http://mmsc.myuni.com.cn";
public static String mmsProxy_uni = "010.000.000.172";
private static List<String> getSimMNC(Context context){
TelephonyManager telManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imsi = telManager.getSubscriberId();
Log.i(TAG, "imsi = " + imsi);
if(imsi!=null){
ArrayList<String> list = new ArrayList<>();
if(imsi.startsWith("46000") || imsi.startsWith("46002") || imsi.startsWith("46007")){
//因为移动网络编号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时,就需要切换:
*/
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 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 boolean sendMMMS(List<String> list, final Activity activity, byte[] pdu) throws Exception {
// HDR_AVLUE_ACCEPT_LANGUAGE = getHttpAcceptLanguage();
if(list==null){
activity.runOnUiThread(() -> {
Toast.makeText(activity, R.string.ipmsg_getsim_failed, 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(activity, 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 Activity activity, byte[] pdu) throws Exception {
HDR_AVLUE_ACCEPT_LANGUAGE = getHttpAcceptLanguage();
// if(list==null){
// activity.runOnUiThread(() -> {
// Toast.makeText(activity, "找不到sim卡", Toast.LENGTH_LONG).show();
// });
// return false;
// }
// String mmsUrl = (String) list.get(0);
// String mmsProxy = (String) list.get(1);
// return false;
// }
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 activity
* @param phone 手机号
* @param subject 主题
* @param text 文字
* @param imagePath 图片路径
* @param audioPath 音频路径
*/
public static void send(final Activity activity, String phone,String subject,String text,String imagePath,String audioPath) {
// String subject = "测试彩信";
Log.v("Sage Test", 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("file://mnt//sdcard//.lv//photo//1326858009625.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(activity, sendRequest);
final byte[] bytesToSend = composer.make();
final List<String> list = getSimMNC(activity);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
//因为在切换apn过程中需要一定时间,所以需要加上一个重试操作
int retry = 0;
do {
// Log.d(TAG, "重试次数:"+(retry+1));
try {
if (sendMMMS(list, activity, bytesToSend)) {
activity.runOnUiThread(()->{
Toast.makeText(activity, R.string.strOk,
Toast.LENGTH_LONG).show();
});
return;
}
retry++;
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
} while (retry < 5);
activity.runOnUiThread(() -> {
Toast.makeText(activity, R.string.strFail, Toast.LENGTH_LONG).show();
});
}
});
t.start();
}
public static void send(final Activity activity, String phone,String subject, long id) throws MmsException {
// String subject = "测试彩信";
Log.v("Sage Test", 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 = SlideshowModel.getPduBody(activity, ContentUris.withAppendedId(Telephony.Mms.Inbox.CONTENT_URI, id));
sendRequest.setBody(pduBody);
final PduComposer composer = new PduComposer(activity, sendRequest);
final byte[] bytesToSend = composer.make();
final List<String> list = getSimMNC(activity);
Thread t = new Thread(() -> {
//因为在切换apn过程中需要一定时间,所以需要加上一个重试操作
int retry = 0;
do {
// Log.d(TAG, "重试次数:"+(retry+1));
try {
if (sendMMMS(list, activity, bytesToSend)) {
activity.runOnUiThread(()->{
Toast.makeText(activity, R.string.strOk,
Toast.LENGTH_LONG).show();
});
return;
}
retry++;
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
} while (retry < 5);
activity.runOnUiThread(() -> {
Toast.makeText(activity, R.string.strFail, Toast.LENGTH_LONG).show();
});
});
t.start();
}
}