android131 360 05 手势触摸滑动,sim卡,开机启动的广播,手机联系人,SharedPreferences,拦截短信
安卓手势触摸滑动:
package com.itheima52.mobilesafe.activity; import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast; /**
* 设置引导页的基类, 不需要在清单文件中注册, 因为不需要界面展示,子类要在清单文件写。
* <activity android:name=".activity.HomeActivity" />
<activity android:name=".activity.SettingActivity" />
<activity android:name=".activity.LostFindActivity" />
<activity android:name=".activity.Setup1Activity" />
<activity android:name=".activity.Setup2Activity" />
<activity android:name=".activity.Setup3Activity" />
<activity android:name=".activity.Setup4Activity" />
<activity android:name=".activity.ContactActivity" /> */
public abstract class BaseSetupActivity extends Activity {
private GestureDetector mDectector;//安卓自带的手势识别器
public SharedPreferences mPref; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPref = getSharedPreferences("config", MODE_PRIVATE);
// 手势识别器
mDectector = new GestureDetector(this, new SimpleOnGestureListener() {
/**
* 监听手势滑动事件 e1表示滑动的起点,e2表示滑动终点 velocityX表示水平速度 velocityY表示垂直速度
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2,float velocityX, float velocityY) {
// 判断纵向滑动幅度是否过大, 过大的话不允许切换界面
if (Math.abs(e2.getRawY() - e1.getRawY()) > 100) {//getRawY()是基于整个屏幕的位置,屏幕左上角为(0,0)点,getY()基于父控件的坐标位置,父控件的左上角为(0,0)。
Toast.makeText(BaseSetupActivity.this, "不能这样划哦!",Toast.LENGTH_SHORT).show();
return true;
}
// 判断滑动是否过慢
if (Math.abs(velocityX) < 100) {
Toast.makeText(BaseSetupActivity.this, "滑动的太慢了!",Toast.LENGTH_SHORT).show();
return true;
}
// 向右划,上一页
if (e2.getRawX() - e1.getRawX() > 200) {
showPreviousPage();
return true;
}
// 向左划, 下一页
if (e1.getRawX() - e2.getRawX() > 200) {
showNextPage();
return true;
}
return super.onFling(e1, e2, velocityX, velocityY);
}
});
} /**
* 展示下一页, 子类必须实现
*/
public abstract void showNextPage(); /**
* 展示上一页, 子类必须实现
*/
public abstract void showPreviousPage(); // 点击下一页按钮
public void next(View view) {
showNextPage();
} // 点击上一页按钮
public void previous(View view) {
showPreviousPage();
} //滑动事件
@Override
public boolean onTouchEvent(MotionEvent event) {
mDectector.onTouchEvent(event);// 委托手势识别器处理触摸事件
return super.onTouchEvent(event);
}
}
获取sim卡信息:
package com.itheima52.mobilesafe.activity; import android.content.Intent;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener; import com.itheima52.mobilesafe.R;
import com.itheima52.mobilesafe.utils.ToastUtils;
import com.itheima52.mobilesafe.view.SettingItemView; /**
* 第2个设置向导页
*/
public class Setup2Activity extends BaseSetupActivity {
private SettingItemView sivSim;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setup2); sivSim = (SettingItemView) findViewById(R.id.siv_sim); String sim = mPref.getString("sim", null);
if (!TextUtils.isEmpty(sim)) {
sivSim.setChecked(true);//初始化时是否勾选单选框
} else {
sivSim.setChecked(false);
}
sivSim.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (sivSim.isChecked()) {
sivSim.setChecked(false);
mPref.edit().remove("sim").commit();// 删除已绑定的sim卡
} else {
sivSim.setChecked(true);
// 保存sim卡信息,sim卡里面也是有内存的,sim卡也有唯一的序列号。
TelephonyManager tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);//sim卡服务
String simSerialNumber = tm.getSimSerialNumber();// 获取sim卡序列号,READ_PHONE_STATE权限。
System.out.println("sim卡序列号:" + simSerialNumber);
mPref.edit().putString("sim", simSerialNumber).commit();// 将sim卡序列号保存在sp中
}
}
});
} @Override
public void showNextPage() {
// 如果sim卡没有绑定,就不允许进入下一个页面
String sim = mPref.getString("sim", null);
if (TextUtils.isEmpty(sim)) {
ToastUtils.showToast(this, "必须绑定sim卡!");
return;
}
startActivity(new Intent(this, Setup3Activity.class));
finish();
// 两个界面切换的动画
overridePendingTransition(R.anim.tran_in, R.anim.tran_out);// 进入动画和退出动画
} @Override
public void showPreviousPage() {
startActivity(new Intent(this, Setup1Activity.class));
finish();
// 两个界面切换的动画
overridePendingTransition(R.anim.tran_previous_in,R.anim.tran_previous_out);// 进入动画和退出动画
}
}
监听手机开机启动的广播:
package com.itheima52.mobilesafe.receiver; import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils; /**
* 监听手机开机启动的广播
* 清单文件注册广播接受者:
<receiver android:name=".receiver.BootCompleteReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
权限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
*/
public class BootCompleteReceiver extends BroadcastReceiver { @Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sp = context.getSharedPreferences("config",Context.MODE_PRIVATE);
boolean protect = sp.getBoolean("protect", false);
// 只有在防盗保护开启的前提下才进行sim卡判断
if (protect) {//为true
String sim = sp.getString("sim", null);// 获取绑定的sim卡
if (!TextUtils.isEmpty(sim)) {
// 获取当前手机的sim卡
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String currentSim = tm.getSimSerialNumber() + "111";// 拿到当前手机的sim卡
if (sim.equals(currentSim)) {
System.out.println("手机安全");
} else {
System.out.println("sim卡已经变化, 发送报警短信!!!");
String phone = sp.getString("safe_phone", "");// 读取安全号码
// 发送短信给安全号码
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phone, null,"sim card changed!", null, null);
}
}
}
}
}
读取手机联系人:
package com.itheima52.contact; import java.util.ArrayList;
import java.util.HashMap; import android.app.Activity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter; public class MainActivity extends Activity { private ListView lvList; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); lvList = (ListView) findViewById(R.id.lv_list);
ArrayList<HashMap<String, String>> readContact = readContact();
lvList.setAdapter(new SimpleAdapter(this, readContact,
R.layout.contact_list_item, new String[] { "name", "phone" },
new int[] { R.id.tv_name, R.id.tv_phone }));
//contact_list_item.xml
/*<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp" >
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#f00"
android:textSize="20sp" />
<TextView
android:id="@+id/tv_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000"
android:textSize="18sp" />
</LinearLayout>*/
} private ArrayList<HashMap<String, String>> readContact() {
// 首先,从raw_contacts表中读取联系人的id("contact_id")
// 其次, 根据contact_id从data1表中查询出相应的电话号码和联系人名称,电话号码和联系人名称是在2行分别存着,并且是同一个字段。
// 然后,根据mimetypes表来区分哪个是联系人,哪个是电话号码
Uri rawContactsUri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri = Uri.parse("content://com.android.contacts/data"); ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>(); // 从raw_contacts中读取联系人的id("contact_id"), getContentResolver()得到的是内容提供者对象。
//new String[] { "contact_id" }是查询的字段,第一个null是查询条件类似于where条件,第二个null是where条件的参数,第三个null是排序
Cursor rawContactsCursor = getContentResolver().query(rawContactsUri,new String[] { "contact_id" }, null, null, null);
if (rawContactsCursor != null) {
while (rawContactsCursor.moveToNext()) {//遍历
String contactId = rawContactsCursor.getString(0);
// System.out.println(contactId); // 根据contact_id从data1表中查询出相应的电话号码和联系人名称, 实际上查询的是视图view_data
Cursor dataCursor = getContentResolver().query(dataUri,
new String[] { "data1", "mimetype" }, "contact_id=?",
new String[] { contactId }, null); if (dataCursor != null) {
HashMap<String, String> map = new HashMap<String, String>();
while (dataCursor.moveToNext()) {
String data1 = dataCursor.getString(0);
String mimetype = dataCursor.getString(1);
// System.out.println(contactId + ";" + data1 + ";" + mimetype);
if ("vnd.android.cursor.item/phone_v2".equals(mimetype)) {//电话号码
map.put("phone", data1);
} else if ("vnd.android.cursor.item/name"
.equals(mimetype)) {//联系人
map.put("name", data1);
}
}
list.add(map);
dataCursor.close();
}
}
rawContactsCursor.close();
}
return list;
}
}
单击选择联系人:
lvList.setOnItemClickListener(new OnItemClickListener() { @Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
String phone = readContact.get(position).get("phone");// 读取当前item的电话号码
Intent intent = new Intent();
intent.putExtra("phone", phone);
setResult(Activity.RESULT_OK, intent);// 将数据放在intent中返回给上一个页面 finish();
}
});
Toast工具类:
public class ToastUtils { public static void showToast(Context ctx, String text) {
Toast.makeText(ctx, text, Toast.LENGTH_SHORT).show();
}
}
弹出数字键盘:
<EditText
android:id="@+id/et_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="phone" <!-- 弹出数字键盘 -->
android:hint="请输入或选择安全号码" />
SharedPreferences使用
SharedPreferences:
public SharedPreferences mPref = getSharedPreferences("config", MODE_PRIVATE);//读取配置文件config.xml,SharedPreferences的内容是保存在配置文件中的。 String phone = mPref.getString("safe_phone", "");//获取配置文件字段,""是没有该属性时的默认值 mPref.edit().putString("safe_phone", "aaaaa").commit();// 保存
带文字的checkbox
<CheckBox
android:id="@+id/cb_protect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="防盗保护没有开启" />
cbProtect = (CheckBox) findViewById(R.id.cb_protect);
boolean protect = mPref.getBoolean("protect", false);
// 根据sp保存的状态,更新checkbox
if (protect) {
cbProtect.setText("防盗保护已经开启");
cbProtect.setChecked(true);
} else {
cbProtect.setText("防盗保护没有开启");
cbProtect.setChecked(false);
}
后台发送短信:
// 后台发送短信,权限 <uses-permission android:name="android.permission.SEND_SMS" />
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage("", null,"sim card changed!", null, null);
拦截短信:
package com.itheima52.mobilesafe.receiver; import com.itheima52.mobilesafe.R;
import com.itheima52.mobilesafe.service.LocationService; import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.sax.StartElementListener;
import android.telephony.SmsMessage; /**
* 拦截短信
* 接收短信权限:<uses-permission android:name="android.permission.RECEIVE_SMS" />
* 清单文件注册:
* <receiver android:name=".receiver.SmsReceiver" >
<intent-filter android:priority="2147483647" > 优先级是int的最大值
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
*/
public class SmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Object[] objects = (Object[]) intent.getExtras().get("pdus");//短信数组
for (Object object : objects) {// 短信最多140字节,超出的话,会分为多条短信发送,所以是一个数组,其实是一条短信,因为我们的短信指令很短,所以for循环只执行一次
SmsMessage message = SmsMessage.createFromPdu((byte[]) object);
String originatingAddress = message.getOriginatingAddress();// 短信来源号码
String messageBody = message.getMessageBody();// 短信内容
System.out.println(originatingAddress + ":" + messageBody);
if ("#*alarm*#".equals(messageBody)) {
// 播放报警音乐, 即使手机调为静音,也能播放音乐, 因为使用的是媒体声音的通道,和铃声无关
MediaPlayer player = MediaPlayer.create(context, R.raw.ylzs);
player.setVolume(1f, 1f);
player.setLooping(true);
player.start();
abortBroadcast();// 中断短信的传递, 从而系统短信app就收不到内容了
} else if ("#*location*#".equals(messageBody)) {
// 获取经纬度坐标
context.startService(new Intent(context, LocationService.class));// 开启定位服务
SharedPreferences sp = context.getSharedPreferences("config",Context.MODE_PRIVATE);
String location = sp.getString("location","getting location...");
System.out.println("location:" + location);
abortBroadcast();// 中断短信的传递, 从而系统短信app就收不到内容了,不中断则系统短信还是能够接收到短信。
} else if ("#*wipedata*#".equals(messageBody)) {
System.out.println("远程清除数据");
abortBroadcast();
} else if ("#*lockscreen*#".equals(messageBody)) {
System.out.println("远程锁屏");
abortBroadcast();
}
}
}
}
android131 360 05 手势触摸滑动,sim卡,开机启动的广播,手机联系人,SharedPreferences,拦截短信的更多相关文章
- Android本机号码及Sim卡状态的获取
SIM卡存储的数据可分为四类:第一类是固定存放的数据.这类数据在移动电话机被出售之前由SIM卡中心写入,包括国际移动用户识别号(IMSI).鉴权密钥(KI).鉴权和加密算法等等.第二类是暂时存放的有关 ...
- 部分SIM卡被曝存安全漏洞:7.5亿部手机受牵连
7月22日消息,据国外媒体报道,一安全研究人员发现部分移动SIM卡所使用的加密方式存在一个安全漏洞,可能会导致手机被黑客远程控制. DES数据加密标准的SIM卡——DES是一种较旧的标准,目前正被部分 ...
- 三种尺寸:手机SIM卡使用指南
毫无疑问目前卖的最火的手机非iPhone 5s莫属,相信仍有不少网友目前处于观望之中,由于iPhone 5s和iPhone 5c采用与iPhone相同的Nano-SIM卡,因此不少新用户在使用之前也徒 ...
- [android] 手机卫士绑定sim卡
更新: 收不到启动广播,查看知乎,好像是说高版本的系统都禁止了 还可以通过adb发送开机广播 adb shell am broadcast -a android.intent.action.BOOT_ ...
- SIM卡的消失会让运营商们恐慌吗?
中国移动.联通.电信三大运营商原本高高在上,每天乐滋滋地数钱数到手抽筋,但近年来移动互联网的快速普及,让运营商的制霸状态不复存在.成为众多互联网公司的"流量通道",语音.短信等业 ...
- SIM卡
SIM卡是(Subscriber Identity Module 客户识别模块)的缩写 也称为用户身份识别卡.智能卡,GSM数字移动电话机必须装上此卡方能使用.在电脑芯片上存储了数字移动电话客户的信息 ...
- SIM卡基础知识
一:了解Sim卡和GSM网络登录步骤的基本知识 (一)名词解释: SIM卡(Subscriber Identity Module),即用户识别卡,它是一张符合GSM规范的“智慧卡”,SIM卡有大小之分 ...
- 简易实现 TextView单行文本水平触摸滑动效果
为了方便查看,已使用markdown编辑形成新博文. 本文Mardown地址 近期做应用的时候实用到TextView单行长文本,当文本内容过长时候又想实现触摸水平滑动效果. 网上找了非常多,都没有看到 ...
- sim卡中的汉字存储格式
Sim卡中的ucs2格式 Sim卡中的中文都是以ucs2格式存储的,ucs2和unicode只是字节序不同,unicode是小头在前,ucs2是大头在前. Ucs2与GB2312互换可以用VC中的Wi ...
随机推荐
- [POJ 2588] Snakes
同swustoj 8 Snakes Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1015 Accepted: 341 ...
- VC++6.0环境下调试c语言代码的方法和步骤_附图
1.C语言程序四步开发步骤 (1)编辑.可以用任何一种编辑软件将在纸上编写好的C语言程序输入计算机,并将C语言源程序文件*.c以纯文本文件形式保存在计算机的磁盘上(不能设置字体.字号等). (2)编译 ...
- Deployed component GUIs and figures have different look and feel than MATLAB desktop
原文:http://www.mathworks.com/support/bugreports/1293244 Description Deployed GUIs and figures look an ...
- 【转】iOS 宏(define)与常量(const)的正确使用-- 不错
原文网址:http://www.jianshu.com/p/f83335e036b5 在iOS开发中,经常用到宏定义,或用const修饰一些数据类型,经常有开发者不知怎么正确使用,导致项目中乱用宏与c ...
- 【转】android的消息处理机制(图+源码分析)——Looper,Handler,Message
原文地址:http://www.cnblogs.com/codingmyworld/archive/2011/09/12/2174255.html#!comments 作为一个大三的预备程序员,我学习 ...
- Apache,PHP,MySQL的安装,配置
Apache 1. 下载 Apache版本号为2.2.22. 最好下载msi安装文件.下载地址为:http://www.apache.org/dist/httpd/binaries/win32/ 如果 ...
- InnoDB关键特性之insert buffer
insert buffer 是InnoDB存储引擎所独有的功能.通过insert buffer,InnoDB存储引擎可以大幅度提高数据库中非唯一辅助索引的插入性能. 数据库对于自增主键值的插入是顺序的 ...
- UVA 1637 Double Patience
题意:36张扑克,平分成9摞,两张数字一样的可以拿走,每次随机拿两张,问能拿光的概率. 解法:记忆化搜索,状态压缩.一开始我想在还没拿的时候概率是1,然后往全拿光推···样例过不去···后来觉得推反了 ...
- 《转》高级Unix命令
原文链接:http://coolshell.cn/articles/1044.html 在Unix操作中有太多太多的命令,这些命令的强大之处就是一个命令只干一件事,并把这件事干好.Do one thi ...
- uva 10652
大意:有n块矩形木板,你的任务是用一个面积尽量小的凸多边形把它们包起来,并计算出木板站整个包装面积的百分比. 思路:按照题意将所有矩形顶点坐标存起来,旋转时先旋转从中心出发的向量,求得各个坐标之后,求 ...