解决:长按一条接收到的彩信,快捷菜单“选择性复制”功能错误

【测试步骤】长按一条接收到的彩信,快捷菜单——“选择性复制”

【测试结果】功能错误,未实现选择性复制,实际是播放彩信内容

【预期结果】应该选择复制彩信内容

通过分析代码我们定位到以下代码:

private final class MsgListMenuClickListener implements MenuItem.OnMenuItemClickListener {

private MessageItem mMsgItem;

public MsgListMenuClickListener(MessageItem msgItem) {

mMsgItem = msgItem;

}

@Override

public boolean onMenuItemClick(MenuItem item) {

if (mMsgItem == null) {

return false;

}

......

case MENU_SELECT_COPY_MESSAGE_TEXT:

                    AdapterView.AdapterContextMenuInfo info;

try {

info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();

} catch (ClassCastException exception) {

Log.e(TAG, "Bad menuInfo.", exception);

return false;

}

final Cursor cursor = (Cursor) mMsgListAdapter.getItem(info.position);

if (mMsgItem.isSms()) {

showSmsMessageContent(cursor);

} else {

MessageUtils.viewMmsMessageAttachment(ComposeMessageActivity.this,

ContentUris.withAppendedId(Mms.CONTENT_URI, mMsgItem.mMsgId), null,

getAsyncDialog());

}

                    return true;

......

}

通过对以上代码我们发现,这里对彩信和短信分别进行了处理,在接着追踪代码时我们发现,如果信息为短信则现实短信的详细信息包括发件人,发件时间等,如果信息为彩信则直接进入彩信幻灯片播放界面,并播放幻灯片。与选项描述和原始业务逻辑相违背,因此作出一下修改。

我们只提取信息的文本,如果信息为彩信,并且彩信只有附件,则屏蔽该选项(Select text to copy)。

因此作出以下修改:

修改ComposeMessageActivity文件中, OnCreateContextMenuListener子类中onCreateContextMenu()方法。

这是修改前的源文件:

......

// Forward is not available for undownloaded messages.

if (msgItem.isDownloaded() && (msgItem.isSms() || msgItem.mIsForwardable)) {

menu.add(0, MENU_FORWARD_MESSAGE, 0, R.string.menu_forward)

.setOnMenuItemClickListener(l);

}

            if (!msgItem.isMms() || msgItem.isDownloaded()) {

menu.add(0, MENU_SELECT_COPY_MESSAGE_TEXT, 0, R.string.select_copy_message_text)

.setOnMenuItemClickListener(l);

}

//only failed send message have resend function

if (msgItem.isFailedMessage()) {

menu.add(0, MENU_RESEND, 0, R.string.menu_resend)

.setOnMenuItemClickListener(l);

}

......

下面是修改后的源代码:(将上述代码中蓝色加粗代码修改为下面红色加粗代码)

......

// Forward is not available for undownloaded messages.

if (msgItem.isDownloaded() && (msgItem.isSms() || msgItem.mIsForwardable)) {

menu.add(0, MENU_FORWARD_MESSAGE, 0, R.string.menu_forward)

.setOnMenuItemClickListener(l);

}

            String selectText=null;

selectText=msgItem.mBody;

if( (!msgItem.isMms() || msgItem.isDownloaded())&&(selectText!=null)){

menu.add(0, MENU_SELECT_COPY_MESSAGE_TEXT, 0, R.string.select_copy_message_text)

.setOnMenuItemClickListener(l);

}

//only failed send message have resend function

if (msgItem.isFailedMessage()) {

menu.add(0, MENU_RESEND, 0, R.string.menu_resend)

.setOnMenuItemClickListener(l);

}

......

添加SelectTextToCopyActivity文件,该类为对信息文本内容进行自由复制操作界面:

package com.android.mms.ui;

import java.util.ArrayList;

import android.app.ActionBar;

import android.app.Activity;

import android.app.AlertDialog;

import android.app.ProgressDialog;

import android.content.ActivityNotFoundException;

import android.content.AsyncQueryHandler;

import android.content.ContentResolver;

import android.content.ContentValues;

import android.content.Context;

import android.content.DialogInterface;

import android.content.DialogInterface.OnClickListener;

import android.content.Intent;

import android.database.Cursor;

import android.database.sqlite.SqliteWrapper;

import android.graphics.drawable.Drawable;

import android.net.Uri;

import android.os.AsyncTask;

import android.os.Bundle;

import android.os.Handler;

import android.os.Looper;

import android.os.Message;

import android.provider.ContactsContract;

import android.provider.ContactsContract.Contacts;

import android.provider.Settings;

import android.provider.Settings.SettingNotFoundException;

import android.provider.Telephony.Mms;

import android.provider.Telephony.Sms;

import android.telephony.PhoneNumberUtils;

import android.text.method.HideReturnsTransformationMethod;

import android.text.style.URLSpan;

import android.text.SpannableStringBuilder;

import android.text.TextUtils;

import android.view.GestureDetector;

import android.view.Menu;

import android.view.MenuItem;

import android.view.MotionEvent;

import android.view.ScaleGestureDetector;

import android.view.View;

import android.view.ViewGroup;

import android.view.Window;

import android.util.Log;

import android.util.TypedValue;

import android.widget.ArrayAdapter;

import android.widget.TextView;

import android.widget.Toast;

import com.android.mms.data.Contact;

import com.android.mms.LogTag;

import com.android.mms.R;

import com.android.mms.transaction.MessageSender;

import com.android.mms.transaction.MessagingNotification;

import com.android.mms.transaction.SmsMessageSender;

import com.android.mms.ui.MessageUtils;

import com.android.mms.ui.WwwContextMenuActivity;

import com.android.mms.util.SmileyParser;

import com.google.android.mms.MmsException;

public class SelectTextToCopyActivity extends Activity {

private static final String TAG = "SelectTextToCopyActivity";

private String mMsgText;// Text of message

private TextView mBodyTextView;

private float mScaleFactor = 1;

private  ScaleGestureDetector mScaleDetector;

private  GestureDetector mGestureDetector;

private static final int ZOOM_IN = 4;

private static final int ZOOM_OUT = 5;

private final int MAX_ZOOM_IN_SIZE = 60;

private final int MAX_ZOOM_OUT_SIZE = 20;

private final int THE_SIZE_OF_PER_ZOOM = 9;

private float mTextSize = 27;

private int mZoomMsg = -1;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

setContentView(R.layout.activity_select_text_to_copy);

getIntentData();

initUi();

}

@Override

public boolean onSearchRequested() {

return false;

}

@Override

public boolean onPrepareOptionsMenu(Menu menu) {

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {

case android.R.id.home:

finish();

break;

}

return true;

}

private void getIntentData() {

Intent intent = getIntent();

mMsgText = intent.getStringExtra("select");

}

private void initUi() {

mBodyTextView = (TextView) findViewById(R.id.text_select);

mBodyTextView.setTransformationMethod(HideReturnsTransformationMethod.getInstance());

mBodyTextView.setTextIsSelectable(true);

mBodyTextView.setText(formatMessage(mMsgText));

mBodyTextView.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

onMailBoxMessageClick(SelectTextToCopyActivity.this);

}

});

mScaleDetector = new ScaleGestureDetector(this, new MyScaleListener());

mGestureDetector = new GestureDetector(this,

new GestureDetector.SimpleOnGestureListener(){ });

mGestureDetector.setOnDoubleTapListener(null);

ActionBar actionBar = getActionBar();

actionBar.setDisplayHomeAsUpEnabled(true);

}

public void onMailBoxMessageClick(final Context context) {

// Check for links. If none, do nothing; if 1, open it; if >1, ask user

// to pick one

final URLSpan[] spans = mBodyTextView.getUrls();

if (spans.length == 1) {

String url = spans[0].getURL();

if (MessageUtils.isWebUrl(url)) {

Uri uri = Uri.parse(url);

Intent intent = new Intent(context, WwwContextMenuActivity.class);

intent.setData(uri);

context.startActivity(intent);

} else {

final String telPrefix = "tel:";

if (url.startsWith(telPrefix)) {

url = url.substring(telPrefix.length());

}

if (PhoneNumberUtils.isWellFormedSmsAddress(url)) {

MessageUtils.showNumberOptions(this, url);

} else {

spans[0].onClick(mBodyTextView);

}

}

} else if (spans.length > 1) {

ArrayAdapter<URLSpan> adapter = new ArrayAdapter<URLSpan>(context,

android.R.layout.select_dialog_item, spans) {

@Override

public View getView(int position, View convertView, ViewGroup parent) {

View v = super.getView(position, convertView, parent);

try {

URLSpan span = getItem(position);

String url = span.getURL();

Uri uri = Uri.parse(url);

TextView tv = (TextView) v;

Drawable d = context.getPackageManager().getActivityIcon(

new Intent(Intent.ACTION_VIEW, uri));

if (d != null) {

d.setBounds(0, 0, d.getIntrinsicHeight(),

d.getIntrinsicHeight());

tv.setCompoundDrawablePadding(10);

tv.setCompoundDrawables(d, null, null, null);

}

// If prefix string is "mailto" then translate

// it.

final String mailPrefix = "mailto:";

String tmpUrl = null;

if (url != null) {

if (url.startsWith(mailPrefix)) {

url = context.getResources().getString(R.string.mail_to) +

url.substring(mailPrefix.length());

}

tmpUrl = url.replaceAll("tel:", "");

}

tv.setText(tmpUrl);

} catch (android.content.pm.PackageManager.NameNotFoundException ex) {

// it‘s ok if we‘re unable to set the drawable

// for this view - the user

// can still use it

}

return v;

}

};

AlertDialog.Builder b = new AlertDialog.Builder(context);

DialogInterface.OnClickListener click = new DialogInterface.OnClickListener() {

@Override

public final void onClick(DialogInterface dialog, int which) {

if (which >= 0) {

String url = spans[which].getURL();

if (MessageUtils.isWebUrl(url)) {

Uri uri = Uri.parse(url);

Intent intent = new Intent(SelectTextToCopyActivity.this,

WwwContextMenuActivity.class);

intent.setData(uri);

context.startActivity(intent);

} else {

final String telPrefix = "tel:";

if (url.startsWith(telPrefix)) {

url = url.substring(telPrefix.length());

}

if (PhoneNumberUtils.isWellFormedSmsAddress(url)) {

MessageUtils.showNumberOptions(context, url);

} else {

spans[which].onClick(mBodyTextView);

}

}

}

dialog.dismiss();

}

};

b.setTitle(R.string.select_link_title);

b.setCancelable(true);

b.setAdapter(adapter, click);

b.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {

@Override

public final void onClick(DialogInterface dialog, int which) {

dialog.dismiss();

}

});

b.show();

}

}

private Handler mUiHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case ZOOM_IN:

zoomIn();

mBodyTextView.invalidate();

break;

case ZOOM_OUT:

zoomOut();

mBodyTextView.invalidate();

break;

default:

break;

}

}

};

private void zoomIn() {

mTextSize = mTextSize + THE_SIZE_OF_PER_ZOOM <= MAX_ZOOM_IN_SIZE ?

mTextSize + THE_SIZE_OF_PER_ZOOM : MAX_ZOOM_IN_SIZE;

if (mTextSize >= MAX_ZOOM_IN_SIZE) {

mTextSize = MAX_ZOOM_IN_SIZE;

}

mBodyTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX,mTextSize);

}

private void zoomOut() {

mTextSize = mTextSize - THE_SIZE_OF_PER_ZOOM < MAX_ZOOM_OUT_SIZE ?

MAX_ZOOM_OUT_SIZE : mTextSize - THE_SIZE_OF_PER_ZOOM;

if (mTextSize <= MAX_ZOOM_OUT_SIZE) {

mTextSize = MAX_ZOOM_OUT_SIZE;

}

mBodyTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX,mTextSize);

}

private class MyScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

@Override

public boolean onScale(ScaleGestureDetector detector) {

float scale = detector.getScaleFactor();

if (scale < 0.999999 || scale > 1.00001) {

mScaleFactor = scale;

}

return true;

}

@Override

public boolean onScaleBegin(ScaleGestureDetector detector) {

return true;

}

@Override

public void onScaleEnd(ScaleGestureDetector detector) {

float scale = detector.getScaleFactor();

if (mScaleFactor > 1.0) {

mZoomMsg = ZOOM_IN;

} else if (mScaleFactor < 1.0) {

mZoomMsg = ZOOM_OUT;

}

}

}

public boolean onInterceptTouchEvent(MotionEvent ev) {

mScaleDetector.onTouchEvent(ev);

final int action = ev.getAction();

switch (action) {

case MotionEvent.ACTION_DOWN:

mGestureDetector.onTouchEvent(ev);

return false;

case MotionEvent.ACTION_MOVE:

mGestureDetector.onTouchEvent(ev);

return false;

case MotionEvent.ACTION_UP:

mGestureDetector.onTouchEvent(ev);

Message msg = Message.obtain();

msg.what = mZoomMsg;

mUiHandler.sendMessage(msg);

mZoomMsg = -1;

return false;

}

return true;

}

public boolean onTouchEvent(MotionEvent ev) {

mScaleDetector.onTouchEvent(ev);

final int action = ev.getAction();

switch (action) {

case MotionEvent.ACTION_DOWN:

mGestureDetector.onTouchEvent(ev);

return true;

case MotionEvent.ACTION_MOVE:

mGestureDetector.onTouchEvent(ev);

return true;

case MotionEvent.ACTION_UP:

mGestureDetector.onTouchEvent(ev);

Message msg = Message.obtain();

msg.what = mZoomMsg;

mUiHandler.sendMessage(msg);

mZoomMsg = -1;

return true;

case MotionEvent.ACTION_CANCEL:

mGestureDetector.onTouchEvent(ev);

return true;

default:

if (mGestureDetector.onTouchEvent(ev)) {

return true;

}

return true;

}

}

private CharSequence formatMessage(String body) {

SpannableStringBuilder buf = new SpannableStringBuilder();

if (!TextUtils.isEmpty(body)) {

SmileyParser parser = SmileyParser.getInstance();

buf.append(parser.addSmileySpans(body));

}

return buf;

}

@Override

protected void onDestroy() {

super.onDestroy();

mUiHandler.removeCallbacksAndMessages(null);

}

}

添加activity_select_text_to_copy.xml文件,为相对应布局文件:

<?xml version="1.0" encoding="utf-8"?>

<!-- AddBy:yabin.huang BugID:SWBUG00030439 Date:20140626 -->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:id="@+id/outlayout"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="@android:color/white"

android:gravity="center_horizontal"

android:isScrollContainer="true"

android:orientation="vertical" >

<LinearLayout

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:minHeight="50dip"

android:orientation="vertical" >

<TextView

android:id="@+id/text_select"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:autoLink="all"

android:linksClickable="false"

android:padding="20dp"

android:textColor="#000000"

android:textSize="18dip" />

</LinearLayout>

</LinearLayout>

并在清单文件中对Activity进行注册:

<activity android:name=".ui.SelectTextToCopyActivity"

android:label="@string/select_copy_message_text"

android:theme="@style/MmsHoloTheme"

android:configChanges="orientation|screenSize|keyboardHidden"

android:launchMode="singleTop" >

</activity>

OK!问题得到解决。

解决:长按一条接收到的彩信,快捷菜单“选择性复制”功能错误

时间: 2024-08-05 07:05:20

解决:长按一条接收到的彩信,快捷菜单“选择性复制”功能错误的相关文章

解决在转发一条内容为满的彩信,删除主题FWD,发送的时候提示转化为短信。

问题描述: 1.长按一条输入内容为满的彩信,选择转发 2.输入联系人-删除主题FWD-发送 测试结果为:提示正转化为短信(见附件) 预期结果为:不应该有提示,应该还是彩信 测试结果图为: 根据提示的Toast内容"Converting to text message..."进行代码最终进行代码定位到ComposeMessageActivity类的showConvertToSmsToast()方法,并打印堆栈: private void showConvertToSmsToast() {

解决 Elasticsearch 超过 10000 条无法查询的问题

解决 Elasticsearch 超过 10000 条无法查询的问题 问题描述 分页查询场景,当查询记录数超过 10000 条时,会报错. 使用 Kibana 的 Dev Tools 工具查询 从第 10001 条到 10010 条数据. 查询语句如下: GET alarm/_search { "from": 10000, "size": 10 } 查询结果,截图如下: 报错信息如下: { "error": { "root_cause&

解决js(ajax)提交后端的“ _xsrf&#39; argument missing from POST” 的错误

首先先简述一下CSRF: CSRF是Cross Site Request Forgery的缩写(也缩写为XSRF),直译过来就是跨站请求伪造的意思,也就是在用户会话下对某个CGI做一些GET/POST的事情——这些事情用户未必知道和愿意做,你可以把它想做HTTP会话劫持. 网站是通过cookie来识别用户的,当用户成功进行身份验证之后浏览器就会得到一个标识其身份的cookie,只要不关闭浏览器或者退出登录,以后访问 这个网站会带上这个cookie.如果这期间浏览器被人控制着请求了这个网站的url

解决VS命令提示符 “Setting environment for using Microsoft Visual Studio. 此时不应有“系列错误

一.起因 最近在玩Boost库.当然首先是要进行Booist库的安装和配置.于是浅墨Google了一下boost库的安装配置攻略,下载了最新版1.55的boost库,就愉悦地开始进行配置了. 当进行到第五步,要在VS命令提示符中运行bootstrap.bat的时候,问题就来了,按着攻略打开Visual Studio2010命令提示符,就迎面报错: "Setting environment for using MicrosoftVisual Studio. 此时不应有\Mirosoft"

解决php 5.4下dedecms登陆后台空白,标题不能为空错误

这两天有人反应新版的php-fpm的php版本为5.4.7对dedecms5.6兼容性不好. dedecms安装完成后会出现登陆后台空白,发布文章时提示"标题不能为空". 1.解决dedecms登陆后台空白错误因为php5.4的版本废除了session_register,所以需要去掉session_register函数 修改:"include/userlogin.class.php",注释掉session_register,修改后如下//@session_regis

笔记本Win10触控板无法双击弹出快捷菜单怎样解决

现在使用笔记本的朋友越来越多,有朋友就出现自己在使用刚升级Win10系统的笔记本时,想通过触控板双击来打开快捷菜单,但是在双击后没有弹出快捷菜单,而且也没有任何反应.出现这样的问题是怎么回事呢?这里就给大家介绍下笔记本Win10触控板无法双击弹出快捷菜单的具体解决方法吧! 具体步骤如下: 1.在Win10系统中打开注册表编辑器,找到注册表目录项HKEY_CURRENT_USER\SOFTWARE\Elantech\SmartPad; 2.在HKEY_CURRENT_USER\SOFTWARE\E

vim应用:终极解决windows系统gvim/vim的各种乱码(文件,菜单,提示信息)!

这个方法解决了我的windows下 gvim的中文乱码问题(跟大家分享一下). 此方法引用   http://www.douban.com/note/145491549/ 查看文件的编码::echo &fileencoding Vim 有四个跟字符编码方式有关的选项,encoding.fileencoding.fileencodings.termencoding (这些选项可能的取值请参考 Vim 在线帮助 :help encoding-names),它们的意义如下: encoding: Vim

[掌眼]解决Castle.ActiveRecord在ASP.NET或WCF环境中HttpContext.Current无效的错误

AR設定檔要指定threadinfotype,不指定的話,預設值是用WebThreadScopeInfo,是用 HttpContext.Current.Items 來存放 SesionScope,所以碰到與UI無關的執行緒,沒有 HttpContext.Current 程式就掛啦. 解决方案一: 1.检查“web.config” <activeRecord isWeb="true" isDebug="false"> <config>... .

解决nextjs部署到now上之后出现的“Unable to import module &#39;now__launcher&#39;”错误

解决nextjs部署到now上之后出现的"Unable to import module 'now__launcher'"错误 这个错误是由于在next.config.js中直接引用了withLess之类的插件导致的.在now环境下require插件需要在PHASE_PRODUCTION_SERVER阶段下,如果不加这个阶段的判断就会报错. 这个是错误的做法 // ? Don't put this here const withCSS = require('@zeit/next-css