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 ...
随机推荐
- c# 控件闪烁处理方法
如果你在Form中绘图的话,不论是不是采用的双缓存,都会看到图片在更新的时候都会不断地闪烁,解决方法就是在这个窗体的构造函数中增加以下三行代码:请在构造函数里面底下加上如下几行:SetStyle(Co ...
- hud 3336 count the string (KMP)
这道题本来想对了,可是因为hdu对pascal语言的限制是我认为自己想错了,结果一看题解发现自己对了…… 题意:给以字符串 计算出以前i个字符为前缀的字符中 在主串中出现的次数和 如: num(aba ...
- APK中java代码反编译
Android APK中的Java代码可以被反编译到什么程度主要看APK的加密程度. 第一种情况:无混淆无加密无加壳.直接利用Dex2jar和JD-GUI可把源码从APK里抠出来,代码逻辑清晰,基本上 ...
- Android 中的MVP 模式
MVP模式的核心思想: MVP把Activity中的UI逻辑抽象成View接口,把业务逻辑抽象成功接口,Model类还是原来的Model. MVC 其中View层其实就是程序的UI界面,用于向用户展示 ...
- CF GYM 100703G Game of numbers
题意:给n个数,一开始基数为0,用这n个数依次对基数做加法或减法,使基数不超过k且不小于0,输出最远能运算到的数字个数,输出策略. 解法:dp.dp[i][j]表示做完第i个数字的运算后结果为j的可能 ...
- HDU 5675 ztr loves math
ztr loves math Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- 进程通信之一 使用WM_COPYDATA C++及C#实现 z
原文地址:http://blog.csdn.net/morewindows/article/details/6804157 进程间通信最简单的方式就是发送WM_COPYDATA消息.本文提供C++及C ...
- HW5.31
import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...
- css div 不能贴边
*{margin:0;padding:0} 在css 最前加上这句,取消所有内边距和外边距.
- Java网络编程(UDP协议:发送端)
package WebProgramingDemo; import java.io.IOException; import java.net.DatagramPacket; import java.n ...