最新实战教程,让你了解Android自动化刷量、作弊与防作弊的那些事,案例:刷友盟统计、批量注册苹果帐号
上一次,我们已经把那个锁的逻辑写好了,已经能够把要锁定的应用放到数据库里面了,那么今天我们就要完成真正的锁定了,要完成锁定,我们之前也说过了,就是通过监听
Android运行的任务栈,然后看看,当时是不是在运行我们已经在锁定的应用,如果真的是运行已经锁定的应用,那么就弹出输入密码的界面。因为我们是通过一个Service来控制是否打这个程序锁定的服务的,所有我们就要在设置中心里面进行一个设置的界面。
好,根据上面说我,我们就先把输入密码的界面先做出来
这个界面非常的简单啦,就是几个控件。
lock.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:gravity="center_horizontal"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dip"
android:background="@drawable/title_background"
android:gravity="center_vertical|center_horizontal"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/lock"
android:textColor="@android:color/white"
android:textSize="22sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:gravity="center_vertical|center_horizontal"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_lock_app_icon"
android:layout_width="48dip"
android:layout_height="48dip"
android:src="@drawable/app"
android:contentDescription="@string/hello_world"/>
<TextView
android:id="@+id/tv_lock_app_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dip"
android:textColor="#ffbc04e5"
android:text="@string/hello_world"/>
</LinearLayout>
<EditText
android:id="@+id/et_lock_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:hint="@string/inputPassword"
android:inputType="textPassword"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:text="@string/protectedYes"
android:onClick="confirm"/>
</LinearLayout>
com.xiaobin.security.ui.LockActivity
package com.xiaobin.security.ui;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.xiaobin.security.R;
import com.xiaobin.security.utils.MD5Encoder;
public class LockActivity extends Activity
{
private ImageView iv_app_icon;
private TextView tv_app_name;
private EditText et_app_pwd;
private String password;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.lock);
iv_app_icon = (ImageView) findViewById(R.id.iv_lock_app_icon);
tv_app_name = (TextView) findViewById(R.id.tv_lock_app_name);
et_app_pwd = (EditText) findViewById(R.id.et_lock_pwd);
//拿到真实的密码
//这里我们为了方便,就使用了手机防盗里面的那个密码,大家可以自己做成可以让用户设置的功能
password = getSharedPreferences("config", Context.MODE_PRIVATE).getString("password", "");
try
{
String packageName = getIntent().getStringExtra("packageName");
//通过包名拿到applicationInfo
ApplicationInfo appInfo = getPackageManager().getPackageInfo(packageName, 0).applicationInfo;
//应用图标
Drawable app_icon = appInfo.loadIcon(getPackageManager());
//应用的名字
String app_name = appInfo.loadLabel(getPackageManager()).toString();
iv_app_icon.setImageDrawable(app_icon);
tv_app_name.setText(app_name);
}
catch (Exception e)
{
e.printStackTrace();
}
}
//按钮的点击事件
public void confirm(View v)
{
String input = et_app_pwd.getText().toString().trim();
if(TextUtils.isEmpty(password))
{
Toast.makeText(this, "您的密码还没有设置,请进入手机防盗进行设定", Toast.LENGTH_SHORT).show();
}
else if(TextUtils.isEmpty(input))
{
Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show();
}
else if(password.equals(MD5Encoder.encode(input)))
{
finish();
}
else
{
Toast.makeText(this, "密码错误", Toast.LENGTH_SHORT).show();
}
}
//不让用户按后退键
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
//屏蔽后退键
if(KeyEvent.KEYCODE_BACK == event.getKeyCode())
{
return true;//阻止事件继续向下分发
}
return super.onKeyDown(keyCode, event);
}
}
上面的那个逻辑也很简单了,也就是拿到用户之前在手机防盗里面设置的密码,然后进行判断,当然,各位也可以自己做一下,那个密码设置的功能。
那么接下来,我们就要讲一下那个锁定应用的核心了,也就是监听任务栈了,其实这个监听也很简单,就是我们开启一条线程,每隔一段时间就扫描一个Android的任务栈,看看是不是有我们已经锁定的应用要启动,如果有,那就启动我们的密码输入界面,如果没有,那就睡眠一段时间
通过任务栈拿到要启动的Activity也很简单的
//得到当前运行的任务栈,参数就是得到多少个任务栈,1就是只拿一个任务栈
//1对应的也就是正在运行的任务栈啦
List<RunningTaskInfo> runningTaskInfos = activityManager.getRunningTasks(1);
//拿到当前运行的任务栈
RunningTaskInfo runningTaskInfo = runningTaskInfos.get(0);
//拿到要运行的Activity的包名
String packageName = runningTaskInfo.topActivity.getPackageName();
因为我们这些是要在后台长时间运行的,所以我们就要放到Service里面
com.xiaobin.security.service.WatchDogService
package com.xiaobin.security.service;
import java.util.List;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import com.xiaobin.security.dao.AppLockDao;
import com.xiaobin.security.ui.LockActivity;
public class WatchDogService extends Service
{
private AppLockDao dao;
private List<String> apps;
private ActivityManager activityManager;
private Intent intent;
private boolean flag = true;
@Override
public IBinder onBind(Intent intent)
{
return null;
}
@Override
public void onCreate()
{
super.onCreate();
dao = new AppLockDao(this);
apps = dao.getAllPackageName();
activityManager = (ActivityManager) getSystemService(Service.ACTIVITY_SERVICE);
intent = new Intent(this, LockActivity.class);
// 服务里面是没有任务栈的,所以要指定一个新的任务栈,不然是无法在服务里面启动activity的
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
new Thread()
{
public void run()
{
while (flag)
{
try
{
// 得到当前运行的任务栈,参数就是得到多少个任务栈,1就是只拿一个任务栈
// 1对应的也就是正在运行的任务栈啦
List<RunningTaskInfo> runningTaskInfos = activityManager
.getRunningTasks(1);
// 拿到当前运行的任务栈
RunningTaskInfo runningTaskInfo = runningTaskInfos
.get(0);
// 拿到要运行的Activity的包名
String packageName = runningTaskInfo.topActivity
.getPackageName();
if (apps.contains(packageName))
{
intent.putExtra("packageName", packageName);
startActivity(intent);
}
else
{
}
sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}.start();
}
@Override
public void onDestroy()
{
super.onDestroy();
flag = false;
}
}
好啦,写完这个之后,我们就要去做一个开启这个服务的开关了,我们这次写在设置中心里面,其实我们设置中心的界面也和高级工具里的界面是差不多的了
setting.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:background="@android:color/white"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dip"
android:background="@drawable/title_background"
android:gravity="center_vertical|center_horizontal"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/setting"
android:textColor="@android:color/white"
android:textSize="22sp" />
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip">
<LinearLayout
android:layout_width="280dip"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:orientation="vertical">
<TextView
android:layout_width="280dip"
android:layout_height="wrap_content"
android:textSize="20sp"
android:text="@string/lock_service"/>
<TextView
android:id="@+id/tv_lock_tips"
android:layout_width="280dip"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textColor="#ffff0000"
android:text="@string/lock_tips"/>
</LinearLayout>
<CheckBox
android:id="@+id/cb_lock_state"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"/>
</RelativeLayout>
</LinearLayout>
com.xiaobin.security.ui.SettingActivity
package com.xiaobin.security.ui;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Window;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
import com.xiaobin.security.R;
import com.xiaobin.security.service.WatchDogService;
public class SettingActivity extends Activity
{
private TextView tv_lock_tips;
private CheckBox cb_lock_state;
private Intent appLockIntent;
private SharedPreferences sp;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.setting);
appLockIntent = new Intent(this, WatchDogService.class);
tv_lock_tips = (TextView) findViewById(R.id.tv_lock_tips);
cb_lock_state = (CheckBox) findViewById(R.id.cb_lock_state);
sp = getSharedPreferences("config", Context.MODE_PRIVATE);
boolean isAppLockStart = sp.getBoolean("appLock", false);
if(isAppLockStart)
{
tv_lock_tips.setText("服务已经开启");
cb_lock_state.setChecked(false);
}
else
{
tv_lock_tips.setText("服务没有开启");
cb_lock_state.setChecked(true);
}
cb_lock_state.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
if(isChecked)
{
startService(appLockIntent);
tv_lock_tips.setText("服务已经开启");
}
else
{
stopService(appLockIntent);
tv_lock_tips.setText("服务没有开启");
}
}
});
}
}
大家也可以看到,现在我们的设置中心还是非常的简单的,就只是开启和关闭服务而已,但我们会在后面慢慢完善的啦
好啦,写到这里,我们就差不多要完成这个程序锁的功能的了,但现在还要做一个操作,那就是在AndroidMainfest文件里面拿到权限才行
<uses-permission android:name="android.permission.GET_TASKS"/>
好啦,现在我们就可以测试一下我们的程序锁的啦,一测试,我们会发现,这个程序锁还是有很多bug来的,比如说,我们一输入密码后,进入到了相应的应用了,但它马上又会变回到输入密码的界面的了,还有一些其他问题的,修复这些问题都比较麻烦,所以我们明天再来修复它。
今天就先到这里了
最后,和大家说一下
为了方便大家的交流,我创建了一个群,这样子大家有什么疑问也可以在群上交流
群号是298440981