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 ...
随机推荐
- SCOI2009生日快乐
竟然是搜索……囧 还以为是什么神题…… uses math; var x,y:extended; n:longint; function find(x,y:extended;z:longint):ex ...
- SCOI2010 and SXOI2014 股票交易(DP)
明显的单调队列…… 但下面的程序一直有bug 附上题解:http://blog.csdn.net/njlcazl/article/details/8611042 附上我的代码: var head,ta ...
- APK中java代码反编译
Android APK中的Java代码可以被反编译到什么程度主要看APK的加密程度. 第一种情况:无混淆无加密无加壳.直接利用Dex2jar和JD-GUI可把源码从APK里抠出来,代码逻辑清晰,基本上 ...
- EF Code First 学习笔记:约定配置
要更改EF中的默认配置有两个方法,一个是用Data Annotations(在命名空间System.ComponentModel.DataAnnotations;),直接作用于类的属性上面;还有一个就 ...
- uboot环境变量与内核MTD分区关系
uboot 与系统内核中MTD分区的关系: 分区只是内核的概念,就是说A-B地址放内核,C-D地址放文件系统,(也就是规定哪个地址区间放内核或者文件系统)等等. 1:在内核MTD中可以定义分区A~B, ...
- POJ 1067 取石子游戏
题意:有两堆个数分别为a和b的石子,两个人轮流取石子,一次可以取一堆中任意个数的石子,或者在两堆中取相同个数的石子,最先没有石子可以取的人输,你先取,赢为1输为0. 解法:威佐夫博弈.看完题先找规律, ...
- error MSB3027: Could not copy "xxx.dll" to "xxx.dll". Exceeded retry count of 10. Failed.
错误提示内容: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(3363,5): error MSB302 ...
- 《深入Java虚拟机学习笔记》- 第14章 浮点运算
<深入Java虚拟机学习笔记>- 第13章 浮点运算
- 《深入Java虚拟机学习笔记》- 第4章 网络移动性
Java虚拟机学习笔记(四)网络移动性
- HIbernate学习笔记(六) 关系映射之多对多
六.多对多 - 单向 Ø 一般的设计中,多对多关联映射,需要一个中间表 Ø Hibernate会自动生成中间表 Ø Hibernate使用many-to-ma ...