吴昊品工程级别项目 Round 3(追加) —— 一个基于android的手机防盗软件的实现

在吴昊系列的吴昊品工程项目的Round 3中,我介绍过一款以前的“异世界”团队(我和几个人做爱立信的比赛时候完成)的软件,叫Mobile Safe,其实,这样的软件已经有不少,而且其中的很多都是非商业的。主要是因为目前的手机防盗已经出现一些直接植入到手机(硬件)内的嵌入式产品了,这 样即使你的手机丢失,别人将你的SIM卡更换或者操作系统重刷之后,你仍然可以找到你原来的手机。不过,这里,我想介绍一款叫做LostPrevent的 软件,它是附着在操作系统上的,别人刷机你木有办法,但是,作为历史性的手机防盗软件,至少可以纳为经典的行列吧!

  LostPrevent的功能:

  手机防盗远程控制软件,包括两项功能,
   一是:手机防盗,开启防盗功能后,如果手机被盗,并更换了其他sim卡,手机就会自动发送一条短信到您预先设定好的手机上,短信中包含更换的新的sim卡的信息,便于您根据sim的信息找回您丢失的手机。
   二是:短信远程控制功能,通 过短信发送相应的命令便可以控制您的手机,例如:如果您的手机设为了静音,但这个时候您又不知道手机放在哪了,那么您便可以向 手机发送相应的短信命令,手机收到命令后便会自动将声音调到最大,然后播放音乐,这样您就可以轻松找到您的手机了,再比如,如果您的手机遗忘在家中,但是 这个时候,您又怕漏接了电话,那么您就可以像手机发送相应的命令,让您的手机呼叫转移到另外一个号码,让您轻松应对这种危难情况。

  工程目录:

 

  布局文件夹中的两个XML文件以及src包里面的三个JAVA文件,bin目录里面有APK安装文件,values装载键值,AndroidManifest里面装的是注册信息,gen装载R文件。

  Layout布局的实现:

  (1)登录界面:

  

  //声明版本号和编码格式(utf-8)

  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    //布满整个区域的竖直布局
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >

  //创建两个可以编辑的文本框(EditText),hint表示暗显示的文字,本人输入之后会撤销。
<EditText
    android:id="@+id/username"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:hint="请输入用户名"
></EditText>
<EditText
    android:id="@+id/password"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:password="true"
    android:hint="请输入密码"
></EditText>

   //下面的这一条,插入一个子布局,在一行上放置权重为1:1的两个button控件,控件中显示的文字分别为"OK"和"CANCLE"。
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
    >
    
    <Button
        android:id="@+id/ok"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="OK"
        android:layout_weight="1"
    ></Button>
    
    <Button
        android:id="@+id/cancle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="CANCLE"
        android:layout_weight="1"
    ></Button>
    </LinearLayout>

</LinearLayout>

 (2)主界面:

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <EditText

        //这里第一行为为EditText注册的控件名safenumber
        android:id="@+id/safenumber"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:hint="请输入一个安全有效的手机号码"
    
    ></EditText>
    
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
    >
    
    <Button
        android:id="@+id/start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始防盗"
        android:layout_weight="1"
    ></Button>
    
    <Button
        android:id="@+id/modify"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="修改密码"
        android:layout_weight="1"
    ></Button>
    </LinearLayout>
    
</LinearLayout>

  这里说下,关于android的程式设计,其实就是XML(布局)+JAVA(实现内部逻辑),所以有的人说android编程其实是Web meets phone,就是这个道理,其中有许多与网页编码类似的特性。说完了布局之后,可以看下src文件夹中的源代码:

  //主Activity(ActivityMain):

 

  package com.zhengping.lp;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.location.LocationManager;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class ActivityMain extends Activity {
    //定义各种控件的控件名
    AlertDialog setPasswordDialog;
    AlertDialog showPasswordDialog;

    //用SharedPreferences来实现持久存储

    SharedPreferences sp;
    
    EditText et_safenumber;
    Button btn_start;
    Button btn_modify;
    
    boolean isFirst;
    boolean isStart;
    TelephonyManager tm;
    
    
    @Override

    //重写onCreate
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //得到电话服务
        tm = (TelephonyManager) this.getSystemService(TELEPHONY_SERVICE);
        sp = this.getSharedPreferences("data", MODE_WORLD_READABLE);

        //取得数据之后,判断是不是第一次使用,如果是的话,弹出“设置密码”的对话框,而如果不是的话,则弹出“输入密码”的对话框
        isFirst = sp.getBoolean("first", true);
        if(isFirst) {
            showSetPasswordDialog();
            return;
        } else {
            showInputPasswordDialog();
        }
    }
    
    private void showInputPasswordDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        
        LayoutInflater inflater = LayoutInflater.from(this);
        View view = inflater.inflate(R.layout.showpassworddialog, null);

        //找到在XML中的控件id
        final EditText et_username = (EditText) view.findViewById(R.id.username);
        final EditText et_password = (EditText) view.findViewById(R.id.password);
        
        Button btn_ok = (Button) view.findViewById(R.id.ok);
        Button btn_cancle = (Button) view.findViewById(R.id.cancle);
        //设置OK按钮的监听
        btn_ok.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                //提取用户输入的字符串的内容,并将其存储在username和password中
                String username = et_username.getText().toString();
                String password = et_password.getText().toString();
                //判断是有用户名和密码有空的情况,有的话显示一个长的Toast
                if(username.trim().equals("") || password.trim().equals("")) {
                    Toast.makeText(ActivityMain.this, "用户名和密码不能为空", Toast.LENGTH_LONG).show();
                    return;
                }

                //提取出持久存储的用户名和密码的字符串
                String savedUsername = sp.getString("username", "");
                String savedPassword = sp.getString("password", "");
                
                if(username.trim().equals(savedUsername) && password.trim().equals(savedPassword)) {

                    //比对无误,初始化,并将密码对话框消去
                    init();
                    showPasswordDialog.dismiss();
                } else {

                    //显示一个长时的Toast
                    Toast.makeText(ActivityMain.this, "用户名或者密码错误", Toast.LENGTH_LONG).show();
                    return;
                }
                
            }});
        //同理,对cancle按钮也设置监听
        btn_cancle.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {

                //利用finish()函数退出
                finish();
                
            }});
        //设置对话框的标题,创建并显示对话框
        builder.setTitle("输入密码");
        builder.setView(view);
        showPasswordDialog = builder.create();
        showPasswordDialog.show();
    }

    private void init() {
        setContentView(R.layout.main);

        //同样地,先声明
        et_safenumber = (EditText) this.findViewById(R.id.safenumber);
        btn_start = (Button) this.findViewById(R.id.start);
        btn_modify = (Button) this.findViewById(R.id.modify);
        
        String savedNumber = sp.getString("safenumber", "");

        //显示出原来保存的数据的安全电话号码safenumber
        et_safenumber.setText(savedNumber);
        
        isStart = sp.getBoolean("start", false);
        if(isStart) {

            //如果“开始防盗”已经点开了,将et_safenumber的那个EditText控件和modify(修改密码)设置为不可见的状态,并将原来显示"开始防盗"的按钮的名字改变为"停止防盗"
            et_safenumber.setEnabled(false);
            btn_modify.setEnabled(false);
            btn_start.setText("停止防盗");
        }
        btn_start.setOnClickListener(new OnClickListener(){

            public void onClick(View v) {
                if(isStart) {

                    //退出防盗,返回来原来的状态
                    Editor editor = sp.edit();
                    editor.putBoolean("start", false);
                    editor.commit();
                    et_safenumber.setEnabled(true);
                    btn_modify.setEnabled(true);
                    btn_start.setText("开始防盗");
                    isStart = false;
                } else {
                    String safeNumber = et_safenumber.getText().toString();

                    //提示手机安全号码不能为空
                    if(safeNumber.trim().equals("")) {
                        Toast.makeText(ActivityMain.this, "安全号码不能为空,请重新设置", Toast.LENGTH_LONG).show();
                        return;
                    } else {
                        
                        String phoneNumber = tm.getLine1Number();
                        //IMSI   
                        String subScribeerId = tm.getSubscriberId();
                        //利用putString方法读入safenumber
                        Editor editor = sp.edit();
                        editor.putString("safenumber", safeNumber);
                        isStart = true;
                        editor.putBoolean("start",isStart);
                        editor.putString("subscriberid", subScribeerId);
                        editor.commit();
                        btn_modify.setEnabled(false);
                        et_safenumber.setEnabled(false);
                        btn_start.setText("停止防盗");
                    }
                }
            }});
        //修改密码按钮的监听
        btn_modify.setOnClickListener(new OnClickListener(){

            public void onClick(View v) {
                showSetPasswordDialog();
            }});
        
        
    }
    //这个与showInputPasswordDialog函数不同的是,由于是修改密码,所以,需要重新调用putString方法将用户名和密码的数据进行存储
    private void showSetPasswordDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        
        LayoutInflater inflater = LayoutInflater.from(this);
        View view = inflater.inflate(R.layout.showpassworddialog, null);
        final EditText et_username = (EditText) view.findViewById(R.id.username);
        final EditText et_password = (EditText) view.findViewById(R.id.password);
        
        Button btn_ok = (Button) view.findViewById(R.id.ok);
        Button btn_cancle = (Button) view.findViewById(R.id.cancle);
        
        btn_ok.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                String username = et_username.getText().toString();
                String password = et_password.getText().toString();
                
                if(username.trim().equals("") || password.trim().equals("")) {
                    Toast.makeText(ActivityMain.this, "用户名和密码不能为空", Toast.LENGTH_LONG).show();
                    return;
                }
                
                Editor editor = sp.edit();
                editor.putString("username", username);
                editor.putString("password", password);
                editor.putBoolean("first", false);
                editor.commit();
                setPasswordDialog.dismiss();
                init();
                
            }});
        
        btn_cancle.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                if(isFirst) {
                    finish();
                } else {
                    setPasswordDialog.dismiss();
                }
                
            }});
        
        builder.setTitle("设置密码");
        builder.setView(view);
        setPasswordDialog = builder.create();
        setPasswordDialog.show();
    }
}

 

  //BootCompleteReceiver.java:

  package com.zhengping.lp;

import java.util.List;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
  //android有四大组建,这个控件继承于BroadcastReceiver,其用于接收广播控件
public class BootCompleteReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        SharedPreferences sp = context.getSharedPreferences("data", Context.MODE_WORLD_WRITEABLE);
        TelephonyManager tm  = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        boolean isStart = sp.getBoolean("start", false);
        if(!isStart) {
            return;
        } else {
            String saveSubscriberId = sp.getString("subscriberid", "");
            String safenumber = sp.getString("safenumber", "");
            
            //IMSI
            String subscriberId = tm.getSubscriberId();
            System.out.println(subscriberId);

            //判断SIM卡是否已经被更换
            if(subscriberId.trim().equals(saveSubscriberId)) {
                return;
            } else {
                //SmsManager,开启短信服务
                SmsManager manager = SmsManager.getDefault();
                List<String> message = manager.divideMessage("手机IMSI码为:" + saveSubscriberId + " 的手机,SIM已被更换,更换的IMSI码为:" + subscriberId);
                for(String msg : message) {

                    //向号码为safenumber的手机发送短信信息
                    manager.sendTextMessage(safenumber, null, msg, null, null);
                }
                
            }
            
        }
        
     }

 }


  SMSReceivedBroadcastReceiver:短信接收广播

  package com.zhengping.lp;

import java.util.List;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;

public class SMSReceivedBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        SharedPreferences sp = context.getSharedPreferences("data", Context.MODE_WORLD_WRITEABLE);
        boolean isStart = sp.getBoolean("start", false);
        String savePhoneNumber = sp.getString("safenumber", "");
        if(isStart) {
            Object[] object = (Object[]) intent.getSerializableExtra("pdus");
            
            byte[][] pdus = new byte[object.length][];
            
            for(int i=0;i<pdus.length;i++) {
                pdus[i] = (byte[]) object[i];
            }
            SmsMessage[] msgs = new SmsMessage[object.length];
            for(int i=0;i<pdus.length;i++) {
                msgs[i] = SmsMessage.createFromPdu(pdus[i]);
            }
            
            for(int i=0;i<msgs.length;i++) {
                String oriAddress = msgs[i].getDisplayOriginatingAddress();
                if(oriAddress.trim().equals(savePhoneNumber)) {
                    String body = msgs[i].getDisplayMessageBody();
                    if(body.contains("ilovedog")) {
                        SmsManager manager = SmsManager.getDefault();
                        List<String> message = manager.divideMessage("your phone is mine");
                        for(String msg : message) {
                            manager.sendTextMessage(savePhoneNumber, null, msg, null, null);
                        }
                    }
                }
                
                
            }
            
        }
        
    }

}

posted on 2013-02-28 17:28  吴昊系列  阅读(354)  评论(0编辑  收藏  举报

导航