当前位置: 编程技术>移动开发
本页文章导读:
▪双模(CDMA/GSM)手机兑现短信监听 双模(CDMA/GSM)手机实现短信监听
一、问题分析:最近在做一个通过短信远程启动应用的功能,要用到短信监听,代码如下import android.content.BroadcastReceiver;import android.content.Context;import android.co.........
▪ TextView一部分文字高亮显示并同时显示表情 TextView部分文字高亮显示并同时显示表情
这里显示表情的思路是,先把表情准备到本地中,给表情添加一个bean,TextView通过替换编码来显示表情。
例如【嘻嘻】,找到这样的字符串则去本.........
▪ java-universal-tween-engine,一个卡通片系统库 java-universal-tween-engine,一个动画系统库
http://code.google.com/p/java-universal-tween-engine/可以用来创建平滑的移动系统,比如循环,移动,旋转等。由于项目使用纯java写成,所以支持swt,swing,android,.........
[1]双模(CDMA/GSM)手机兑现短信监听
来源: 互联网 发布时间: 2014-02-18
双模(CDMA/GSM)手机实现短信监听
一、问题分析:
最近在做一个通过短信远程启动应用的功能,要用到短信监听,代码如下
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;
public class SMSReceiver extends BroadcastReceiver
{
/*当收到短信时,就会触发此方法*/
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
if(bundle!=null && bundle.get("pdus")!=null){
Object[] pdus = (Object[]) bundle.get("pdus"); //得到由短信内容组成的数组对象
if(pdus!=null && pdus.length>0){
SmsMessage[] messages = new SmsMessage[pdus.length];
for(int i=0;i<pdus.length;i++){
byte[] pdu = (byte[]) pdus[i]; //得到短信内容,内容是以pdu格式存放的
messages[i] = SmsMessage.createFromPdu(pdu);
}
for(SmsMessage msg:messages){
String smscontent = msg.getMessageBody(); //得到短信内容
String smssender = msg.getOriginatingAddress(); //得到短信发送者的手机号
}
}
}
}
}
实际应用时发现双模手机对接收到的短信处理时总是在SmsMessage.createFromPdu的地方出现异常,异常信息:
java.lang.OutOfMemoryError: array size too large
at com.android.internal.telephony.cdma.SmsMessage.parsePdu(SmsMessage.java:658)
at com.android.internal.telephony.cdma.SmsMessage.createFromPdu(SmsMessage.java:116)
at android.telephony.SmsMessage.createFromPdu(SmsMessage.java:162)
而在android的源码中可以看到createFromPdu方法:
public static SmsMessage createFromPdu(byte[] pdu) {
SmsMessageBase wrappedMessage;
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu);
} else {
wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
}
return new SmsMessage(wrappedMessage);
}
如果是双模手机,调用此方法时会产生错误,问题就在于源码的TelephonyManager.getDefault().getPhoneType();该方法的返回值没有对应的双模手机的类型,而原生的android系统是不支持双模手机的。
二、解决办法:
我们可以采用广播接收者和内容观察者相结合的方式,直接读取手机的短信数据库,这样就避免了错误的产生,废话就不多说了,直接上代码:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
public class SMSReceiver extends BroadcastReceiver {
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private Context m_Context;
private SmsContentObserver m_Smsobserver = new SmsContentObserver(new Handler());
@Override
public void onReceive(Context context, Intent intent) {
this.m_Context = context;
if (intent.getAction().equals(SMS_RECEIVED)) {
//注册短信变化监听
context.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, m_Smsobserver);
}
}
/**
* 短信内容观察者
* @author sinber
*
*/
private class SmsContentObserver extends ContentObserver{
public SmsContentObserver(Handler handler) {
super(handler);
}
/**
* @Description 当短信表发送改变时,调用该方法
* 需要两种权限
* <li>android.permission.READ_SMS读取短信 </li>
* <li>android.permission.WRITE_SMS写短信 </li>
* @Author sinebr
*
*/
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Cursor cursor = null;
try{
//读取收件箱中的短信
cursor = m_Context.getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, "date desc");
String body;
boolean hasDone = false;
if (cursor != null){
while (cursor.moveToNext()){
body = cursor.getString(cursor.getColumnIndex("body"));
if(body != null && body.equals("【startMyActivity】")){
//此处略去启动应用的代码
hasDone = true;
break;
}
if (hasDone){
break;
}
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(cursor!=null)
cursor.close();
}
}
}
}
最后别忘了在AndroidManifest.xml中添加相应的权限,
<!-- 接收短信权限 -->
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<!-- 发送短信权限 -->
<uses-permission android:name="android.permission.SEND_SMS"/>
还有别忘了注册广播接收者:
<receiver android:name=".SMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
这样就能适应所有的android手机了,无论是双模还是单模都没问题,问题解决了。
原文链接:http://www.cnblogs.com/sinber/archive/2011/06/22/CDMA_GSM_SMS.html
一、问题分析:
最近在做一个通过短信远程启动应用的功能,要用到短信监听,代码如下
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.widget.Toast;
public class SMSReceiver extends BroadcastReceiver
{
/*当收到短信时,就会触发此方法*/
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
if(bundle!=null && bundle.get("pdus")!=null){
Object[] pdus = (Object[]) bundle.get("pdus"); //得到由短信内容组成的数组对象
if(pdus!=null && pdus.length>0){
SmsMessage[] messages = new SmsMessage[pdus.length];
for(int i=0;i<pdus.length;i++){
byte[] pdu = (byte[]) pdus[i]; //得到短信内容,内容是以pdu格式存放的
messages[i] = SmsMessage.createFromPdu(pdu);
}
for(SmsMessage msg:messages){
String smscontent = msg.getMessageBody(); //得到短信内容
String smssender = msg.getOriginatingAddress(); //得到短信发送者的手机号
}
}
}
}
}
实际应用时发现双模手机对接收到的短信处理时总是在SmsMessage.createFromPdu的地方出现异常,异常信息:
java.lang.OutOfMemoryError: array size too large
at com.android.internal.telephony.cdma.SmsMessage.parsePdu(SmsMessage.java:658)
at com.android.internal.telephony.cdma.SmsMessage.createFromPdu(SmsMessage.java:116)
at android.telephony.SmsMessage.createFromPdu(SmsMessage.java:162)
而在android的源码中可以看到createFromPdu方法:
public static SmsMessage createFromPdu(byte[] pdu) {
SmsMessageBase wrappedMessage;
int activePhone = TelephonyManager.getDefault().getPhoneType();
if (PHONE_TYPE_CDMA == activePhone) {
wrappedMessage = com.android.internal.telephony.cdma.SmsMessage.createFromPdu(pdu);
} else {
wrappedMessage = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
}
return new SmsMessage(wrappedMessage);
}
如果是双模手机,调用此方法时会产生错误,问题就在于源码的TelephonyManager.getDefault().getPhoneType();该方法的返回值没有对应的双模手机的类型,而原生的android系统是不支持双模手机的。
二、解决办法:
我们可以采用广播接收者和内容观察者相结合的方式,直接读取手机的短信数据库,这样就避免了错误的产生,废话就不多说了,直接上代码:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
public class SMSReceiver extends BroadcastReceiver {
private static final String SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private Context m_Context;
private SmsContentObserver m_Smsobserver = new SmsContentObserver(new Handler());
@Override
public void onReceive(Context context, Intent intent) {
this.m_Context = context;
if (intent.getAction().equals(SMS_RECEIVED)) {
//注册短信变化监听
context.getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, m_Smsobserver);
}
}
/**
* 短信内容观察者
* @author sinber
*
*/
private class SmsContentObserver extends ContentObserver{
public SmsContentObserver(Handler handler) {
super(handler);
}
/**
* @Description 当短信表发送改变时,调用该方法
* 需要两种权限
* <li>android.permission.READ_SMS读取短信 </li>
* <li>android.permission.WRITE_SMS写短信 </li>
* @Author sinebr
*
*/
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
Cursor cursor = null;
try{
//读取收件箱中的短信
cursor = m_Context.getContentResolver().query(Uri.parse("content://sms/inbox"), null, null, null, "date desc");
String body;
boolean hasDone = false;
if (cursor != null){
while (cursor.moveToNext()){
body = cursor.getString(cursor.getColumnIndex("body"));
if(body != null && body.equals("【startMyActivity】")){
//此处略去启动应用的代码
hasDone = true;
break;
}
if (hasDone){
break;
}
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
if(cursor!=null)
cursor.close();
}
}
}
}
最后别忘了在AndroidManifest.xml中添加相应的权限,
<!-- 接收短信权限 -->
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<!-- 发送短信权限 -->
<uses-permission android:name="android.permission.SEND_SMS"/>
还有别忘了注册广播接收者:
<receiver android:name=".SMSReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
这样就能适应所有的android手机了,无论是双模还是单模都没问题,问题解决了。
原文链接:http://www.cnblogs.com/sinber/archive/2011/06/22/CDMA_GSM_SMS.html
[2] TextView一部分文字高亮显示并同时显示表情
来源: 互联网 发布时间: 2014-02-18
TextView部分文字高亮显示并同时显示表情
这里显示表情的思路是,先把表情准备到本地中,给表情添加一个bean,TextView通过替换编码来显示表情。
例如【嘻嘻】,找到这样的字符串则去本地文件夹中寻找对应的图片并显示。
package com.uim.microblog.util;
import java.lang.reflect.Field;
import java.util.List;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ImageSpan;
import android.text.style.URLSpan;
import android.util.Log;
import android.widget.TextView;
import com.uim.R;
import com.uim.microblog.model.Emotions;
import com.uim.microblog.ui.BlogHomeActivity;
/**
* 处理TextView界面的类
* @author mzba
* @version 2011-06-23
*
*/
public class TextAutoLink {
// 加入话题 好友 URL的连结
public static char strarray[];
public static void addURLSpan(Activity activity, String str, TextView textView) {
try{
SpannableString ss = new SpannableString(str);
strarray = str.toCharArray();
int l = str.length() - 10;
for (int i = 0; i < l; i++) {
if (strarray[i] == 'h' && strarray[i + 1] == 't'
&& strarray[i + 2] == 't' && strarray[i + 3] == 'p'
&& strarray[i + 4] == ':' && strarray[i + 5] == '/'
&& strarray[i + 6] == '/') {
StringBuffer sb = new StringBuffer("http://");
for (int j = i + 7; true; j++) {
if (strarray[j] != ' ')
sb.append(strarray[j]);
else {
Log.d("http", sb.toString());
ss.setSpan(new URLSpan(sb.toString()), i, j,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
i = j;
break;
}
}
}
}
// 处理话题
l = str.length();
StringBuffer sb = null;
boolean start = false;
int startIndex = 0;
for (int i = 0; i < l; i++) {
if (strarray[i] == '@') {
start = true;
sb = new StringBuffer("weibo://weibo.view/");
startIndex = i;
} else {
if (start) {
if (strarray[i] == ':') {
ss.setSpan(new URLSpan(sb.toString()), startIndex, i,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sb = null;
start = false;
} else {
sb.append(strarray[i]);
}
}
}
}
// 处理 话题
start = false;
startIndex = 0;
for (int i = 0; i < l; i++) {
if (strarray[i] == '#') {
if (!start) {
start = true;
sb = new StringBuffer("weibo://weibo.view/");
startIndex = i;
} else {
sb.append('#');
ss.setSpan(new URLSpan(sb.toString()), startIndex, i + 1,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
sb = null;
start = false;
}
} else {
if (start) {
sb.append(strarray[i]);
}
}
}
//处理显示表情
String content = str;
int len = 0;
int starts = 0;
int end = 0;
while(len < content.length()){
if(content.indexOf("[", starts) != -1 && content.indexOf("]", end) != -1){
starts = content.indexOf("[", starts);
end = content.indexOf("]", end);
String phrase = content.substring(starts,end + 1);
String imageName = "";
List<Emotions> list = BlogHomeActivity.emotions;
for (Emotions emotions : list) {
if (emotions.getPhrase().equals(phrase)) {
imageName = emotions.getImageName();
}
}
try {
Field f = (Field)R.drawable.class.getDeclaredField(imageName);
int i= f.getInt(R.drawable.class);
Drawable drawable = activity.getResources().getDrawable(i);
if (drawable != null) {
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE);
ss.setSpan(span, starts,end + 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
}
} catch (SecurityException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
}
starts = end;
len = end;
end++;
}else{
starts++;
end++;
len = end;
}
}
textView.setText(ss); // 设定TextView话题和url和好友 连接
strarray = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
[3] java-universal-tween-engine,一个卡通片系统库
来源: 互联网 发布时间: 2014-02-18
java-universal-tween-engine,一个动画系统库
http://code.google.com/p/java-universal-tween-engine/
可以用来创建平滑的移动系统,比如循环,移动,旋转等。由于项目使用纯java写成,所以支持swt,swing,android,opengles等。Tween缓冲大家应该都不陌生,说白了就是从一起始位置逐渐移动到目标位置的过程,这个过程可以是加速移动,也可以是减速移动,这些不同的缓动方式就是Tween的各种ease。
源码在最后,将其解压后复制到src就可以了。
用法,先定义一个需要运动的物体:
然后,实现Tweenable接口,用于表明运动的返回值和变化值
最后,在Activity中运动:
http://code.google.com/p/java-universal-tween-engine/
可以用来创建平滑的移动系统,比如循环,移动,旋转等。由于项目使用纯java写成,所以支持swt,swing,android,opengles等。Tween缓冲大家应该都不陌生,说白了就是从一起始位置逐渐移动到目标位置的过程,这个过程可以是加速移动,也可以是减速移动,这些不同的缓动方式就是Tween的各种ease。
源码在最后,将其解压后复制到src就可以了。
用法,先定义一个需要运动的物体:
public class Particule {
private float x, y;
public float getX() {
return x;
}
public float getY() {
return y;
}
public void setX(float x) {
this.x = x;
}
public void setY(float y) {
this.y = y;
}
}
然后,实现Tweenable接口,用于表明运动的返回值和变化值
import aurelienribon.tweenengine.Tweenable;
public class TweenableParticule implements Tweenable {
// The following lines define the different possible tween types.
// It's up to you to define what you need :-)
public static final int X = 1;
public static final int Y = 2;
public static final int XY = 3;
// Composition pattern
private Particule target;
// Constructor
public TweenableParticule(Particule particule) {
this.target = particule;
}
// Tweenable implementation
@Override
public int getTweenValues(int tweenType, float[] returnValues) {
switch (tweenType) {
case X: returnValues[0] = target.getX(); return 1;
case Y: returnValues[0] = target.getY(); return 1;
case XY:
returnValues[0] = target.getX();
returnValues[1] = target.getY();
return 2;
default: assert false; return 0;
}
}
@Override
public void onTweenUpdated(int tweenType, float[] newValues) {
switch (tweenType) {
case X: target.setX(newValues[0]); break;
case Y: target.setY(newValues[1]); break;
case XY:
target.setX(newValues[0]);
target.setY(newValues[1]);
break;
default: assert false; break;
}
}
}
最后,在Activity中运动:
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import aurelienribon.tweenengine.Tween;
import aurelienribon.tweenengine.TweenGroup;
import aurelienribon.tweenengine.TweenManager;
import aurelienribon.tweenengine.Tweenable;
import aurelienribon.tweenengine.equations.*;
import com.ql.test.Particule;
import com.ql.test.TweenableParticule;
/**
* http://code.google.com/p/java-universal-tween-engine/
* @author admin
*
*/
public class Screen4 extends Activity {
Particule particule;
TweenManager manager;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.screen_4);
// Button btn_11=(Button)findViewById(R.id.btn_11);
setContentView(new ScreenView(this));
// Let's say we are working with an Android target. We need to pool our objects.
Tween.setPoolEnabled(true);
// We also need a manager to handle every tween.
manager = new TweenManager();
// We can now create as many interpolations as we need !
particule=new Particule();
particule.setX(100);
particule.setY(100);
Tweenable tweenParticle=new TweenableParticule(particule);
Tween tween = Tween.to(tweenParticle, TweenableParticule.XY, 10000, Cubic.OUT).target(400, 500);
manager.add(tween.start());
tween = Tween.to(tweenParticle, TweenableParticule.XY, 10000, Bounce.OUT).target(100, 500).delay(10000);
manager.add(tween.start());
// TweenGroup tweenGroup=new TweenGroup().pack(
// Tween.set(tweenParticle, TweenableParticule.XY),
// Tween.to(tweenParticle, TweenableParticule.XY, 10000, Sine.OUT),
// Tween.from(tweenParticle, TweenableParticule.XY, 10000, Sine.OUT),
// Tween.to(tweenParticle, TweenableParticule.XY, 10000, Bounce.OUT)
// );
// manager.add(tweenGroup.sequence().repeat(2,5000).start());
// TweenGroup tweenGroup= new TweenGroup().pack(
// Tween.to(tweenParticle, TweenableParticule.XY, 500, Quad.INOUT).target(200),
// Tween.to(tweenParticle, TweenableParticule.XY, 500, Quad.INOUT).target(100),
// Tween.to(tweenParticle, TweenableParticule.XY, 500, Quad.INOUT).target(200).delay(1000)
// ).sequence().start();
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
manager.clear();
}
class ScreenView extends View{
Paint paint;
public ScreenView(Context context) {
super(context);
// TODO Auto-generated constructor stub
paint=new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.FILL_AND_STROKE);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
//super.onDraw(canvas);
canvas.drawCircle(particule.getX(), particule.getY(), 20, paint);
manager.update();
invalidate();
}
}
}
1 楼
wxw404
2011-11-01
谢谢收了 拿来用
2 楼
2006her
2012-03-09
感谢分享啊。
最新技术文章: