安卓手势触摸滑动:
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();
}
}
}
}