最新实战教程,让你了解Android自动化刷量、作弊与防作弊的那些事,案例:刷友盟统计、批量注册苹果帐号

首先,先把我之前写的那个更新操作的一个bug修复先,这个bug就是在Android4以上,我们已经不能在主线程里面进行网络操作的啦,如果进行网络操作,就会报错

所以我们就要做一下改动,我们在onCreate方法里面开启一个线程,用来检测更新信息的

     new Thread(){public void run() {try{UpdateInfoService updateInfoService = new UpdateInfoService(SplashActivity.this);info = updateInfoService.getUpdateInfo(R.string.serverUrl);}catch (Exception e){e.printStackTrace();}};}.start();

然后呢,就在原来的isNeedUpdate方法里面进行一些修改啦

 private boolean isNeedUpdate(String version){if(info == null){Toast.makeText(this, "获取更新信息异常,请稍后再试", Toast.LENGTH_SHORT).show();loadMainUI();return false;}String v = info.getVersion();if(v.equals(version)){Log.i(TAG, "当前版本:" + version);Log.i(TAG, "最新版本:" + v);loadMainUI();return false;}else{Log.i(TAG, "需要更新");return true;}}

好啦,到这里,我们的这个bug就修复的啦。在进入今天的内容之前,先谢谢一位网友啦,是他发现这个问题的,非常感谢!

好,我们今天要讲的就是设置手机归属地的样式以及显示位置,先上图,让大家看一下我们今天要做的效果

    

大家可以看到,我们今天要做的就是显示风格和位置,那个显示风格就是上面的第二张图片,其实这个功能很简单的,就是记录下来用户设置的风格,然后就进行一个背景的设置而已,而第二个要做的就是显示的位置啦,上面第三张图就是啦,我们把那个activity做成了透明的了,如果你觉得不好,那么也可以不做成透明的,我们可以手动那个紫色的方块,来确定要显示的位置!设置好这些之后,再把服务开启,我们就可以看到下面的效果的啦!

好,废话不多说,我们现在就开始做,我们首先把风格那个对话框给做出来

com.xiaobin.security.ui.AToolActivity

package com.xiaobin.security.ui;import java.io.File;import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;
import android.widget.Toast;import com.xiaobin.security.R;
import com.xiaobin.security.engine.DownloadTask;
import com.xiaobin.security.service.AddressService;public class AToolActivity extends Activity implements OnClickListener
{private static final int ERROR = 0;private static final int SUCCESS = 1;private TextView tv_atool_query;private TextView tv_atool_number_service_state;private CheckBox cb_atool_state;private TextView tv_atool_select_bg;private TextView tv_atool_change_location;private Intent serviceIntent;private ProgressDialog pd;private SharedPreferences sp;@SuppressLint("HandlerLeak")private Handler handler = new Handler(){public void handleMessage(Message msg) {switch(msg.what){case ERROR : Toast.makeText(AToolActivity.this, "下载数据库失败,请检查网络!", Toast.LENGTH_SHORT).show();break;case SUCCESS : Toast.makeText(AToolActivity.this, "数据库下载成功!", Toast.LENGTH_SHORT).show();break;default : break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.atool);sp = getSharedPreferences("config", Context.MODE_PRIVATE);tv_atool_query = (TextView) findViewById(R.id.tv_atool_query);tv_atool_query.setOnClickListener(this);tv_atool_select_bg = (TextView) findViewById(R.id.tv_atool_select_bg);tv_atool_select_bg.setOnClickListener(this);tv_atool_change_location = (TextView) findViewById(R.id.tv_atool_change_location);tv_atool_change_location.setOnClickListener(this);tv_atool_number_service_state = (TextView) findViewById(R.id.tv_atool_number_service_state);cb_atool_state = (CheckBox) findViewById(R.id.cb_atool_state);serviceIntent = new Intent(this, AddressService.class);cb_atool_state.setOnCheckedChangeListener(new OnCheckedChangeListener(){@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked){if(isChecked){startService(serviceIntent);tv_atool_number_service_state.setTextColor(Color.BLACK);tv_atool_number_service_state.setText("归属地服务已开启");}else{stopService(serviceIntent);tv_atool_number_service_state.setTextColor(Color.RED);tv_atool_number_service_state.setText(R.string.number_service_state);}}});}@Overridepublic void onClick(View v){switch(v.getId()){case R.id.tv_atool_query : query();break;case R.id.tv_atool_select_bg : selectStyle();break;case R.id.tv_atool_change_location : Intent intent = new Intent(this, DragViewActivity.class);startActivity(intent);break;default : break;}}private void query(){if(isDBExist()){Intent intent = new Intent(this, QueryNumberActivity.class);startActivity(intent);}else{//提示用户下载数据库pd = new ProgressDialog(this);pd.setMessage("正在下载数据库...");pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);pd.setCancelable(false);pd.show();new Thread(){public void run() {String path = getResources().getString(R.string.serverdb);File dir = new File(Environment.getExternalStorageDirectory(), "/security/db");if(!dir.exists()){dir.mkdirs();}String dbPath = Environment.getExternalStorageDirectory() + "/security/db/data.db";try{//这个类,我们在做更新apk的时候已经写好的啦,现在直接拿过来用就可以啦DownloadTask.getFile(path, dbPath, pd);pd.dismiss();}catch (Exception e){e.printStackTrace();pd.dismiss();Message message = new Message();message.what = ERROR;handler.sendMessage(message);}};}.start();}}private boolean isDBExist(){if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){File file = new File(Environment.getExternalStorageDirectory() + "/security/db/data.db");if(file.exists()){return true;}}return false;}//显示风格的对话框,我准备了5张不同风格的背景图片,根据用户选择的风格不一样,设置不同的背景private void selectStyle(){AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle("归属地显示风格");String[] items = new String[] {"半透明", "活力橙", "苹果绿", "孔雀蓝", "金属灰"};builder.setSingleChoiceItems(items, 0, new DialogInterface.OnClickListener(){@Overridepublic void onClick(DialogInterface dialog, int which){Editor editor = sp.edit();editor.putInt("background", which);editor.commit();}});builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){@Overridepublic void onClick(DialogInterface dialog, int which){}});builder.create().show();}}

我们写了一个方法,selectStyle这个方法会把用户的设置记录下来,然后我们就在显示那个归属地那里读取出来,设置一下背景就可以啦,但我们现在先把那个显示位置的也做出来先

其实这个也很简单的,我们就用一个onTouch事件,然后记录下最终的位置就可以的啦

com.xiaobin.security.ui.DragViewActivity

package com.xiaobin.security.ui;import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams;import com.xiaobin.security.R;public class DragViewActivity extends Activity implements OnTouchListener
{private ImageView iv_drag_location;private SharedPreferences sp;//记录第一次触摸的坐标private int startX;private int startY;@Overrideprotected void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);requestWindowFeature(Window.FEATURE_NO_TITLE);setContentView(R.layout.drag_view);sp = getSharedPreferences("config", Context.MODE_PRIVATE);iv_drag_location = (ImageView) findViewById(R.id.iv_drag_location);iv_drag_location.setOnTouchListener(this);}@Overrideprotected void onResume(){super.onResume();//加载上次移动的效果int x = sp.getInt("lastX", 0);int y = sp.getInt("lastY", 0);/*iv_drag_location.layout(iv_drag_location.getLeft() + x, iv_drag_location.getTop() + y, iv_drag_location.getRight() + x, iv_drag_location.getBottom() + y);iv_drag_location.invalidate();*/RelativeLayout.LayoutParams params = (LayoutParams) iv_drag_location.getLayoutParams();params.leftMargin = x;params.topMargin = y;iv_drag_location.setLayoutParams(params);}@Overridepublic boolean onTouch(View v, MotionEvent event){switch(v.getId()){case R.id.iv_drag_location : switch(event.getAction()){case MotionEvent.ACTION_DOWN : startX = (int) event.getRawX();startY = (int) event.getRawY();break;case MotionEvent.ACTION_MOVE : int x = (int) event.getRawX();int y = (int) event.getRawY();//算出移动距离int dx = x - startX;int dy = y - startY;int l = iv_drag_location.getLeft();int r = iv_drag_location.getRight();int t = iv_drag_location.getTop();int b = iv_drag_location.getBottom();//设置新的布局位置iv_drag_location.layout(l + dx, t + dy, r + dx, b + dy);//重新获取位置startX = (int) event.getRawX();startY = (int) event.getRawY();break;case MotionEvent.ACTION_UP : int lastX = iv_drag_location.getLeft();int lastY = iv_drag_location.getTop();Editor editor = sp.edit();editor.putInt("lastX", lastX);editor.putInt("lastY", lastY);editor.commit();break;default : break;}break;default : break;}return true;}}

好啦,写完这两个,我们就可以回到我们之前显示归属地的那个Service里面写逻辑啦

com.xiaobin.security.service.AddressService

package com.xiaobin.security.service;import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;import com.xiaobin.security.R;
import com.xiaobin.security.engine.NumberAddressService;public class AddressService extends Service
{private TelephonyManager telephonyManager;private MyPhoneListener listener;private WindowManager windowManager;private View view;private SharedPreferences sp;@Overridepublic IBinder onBind(Intent intent){return null;}@Overridepublic void onCreate(){super.onCreate();sp = getSharedPreferences("config", Context.MODE_PRIVATE);windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);listener = new MyPhoneListener();telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);}@Overridepublic void onDestroy(){super.onDestroy();//停止监听telephonyManager.listen(listener, PhoneStateListener.LISTEN_NONE);}//显示归属地的窗体private void showLocation(String address){WindowManager.LayoutParams params = new WindowManager.LayoutParams();params.width = WindowManager.LayoutParams.WRAP_CONTENT;params.height = WindowManager.LayoutParams.WRAP_CONTENT;params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE //无法获取焦点| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE //无法点击| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;//保持屏幕亮params.format = PixelFormat.TRANSLUCENT;//设置成半透明的params.type = WindowManager.LayoutParams.TYPE_TOAST;params.setTitle("Toast");//主要是确定坐标系是从左上角开始的,不然呆会设置位置的时候有些麻烦params.gravity = Gravity.LEFT | Gravity.TOP;params.x = sp.getInt("lastX", 0);params.y = sp.getInt("lastY", 0);view = View.inflate(getApplicationContext(), R.layout.show_location, null);LinearLayout ll = (LinearLayout) view.findViewById(R.id.ll_location);int type = sp.getInt("background", 0);switch(type){case 0 : ll.setBackgroundResource(R.drawable.call_locate_white);break;case 1 : ll.setBackgroundResource(R.drawable.call_locate_orange);break;case 2 : ll.setBackgroundResource(R.drawable.call_locate_green);break;case 3 : ll.setBackgroundResource(R.drawable.call_locate_blue);break;case 4 : ll.setBackgroundResource(R.drawable.call_locate_gray);break;default : break;}TextView tv = (TextView) view.findViewById(R.id.tv_show_location);tv.setText("归属地: " + address);windowManager.addView(view, params);}//========================================================================private class MyPhoneListener extends PhoneStateListener{@Overridepublic void onCallStateChanged(int state, String incomingNumber){super.onCallStateChanged(state, incomingNumber);switch(state){case TelephonyManager.CALL_STATE_IDLE : //空闲状态if(view != null){windowManager.removeView(view);//移除显示归属地的那个viewview = null;}break;case TelephonyManager.CALL_STATE_OFFHOOK : //接通电话if(view != null){windowManager.removeView(view);//移除显示归属地的那个viewview = null;}break;case TelephonyManager.CALL_STATE_RINGING : //铃响状态String address = NumberAddressService.getAddress(incomingNumber);showLocation(address);break;default : break;}}}}

好啦,到现在为止,我们的显示风格还有显示位置就已经全部完成的啦!下次我们就会讲高级工具里面的黑名单功能的啦!

今天源码下载

Android项目实战--手机卫士15--设置手机归属地的样式以及显示位置相关推荐

  1. android博学谷布局,《Android项目实战-博学谷》设置部分

    设置界面 思路 设置界面有三个功能,分别为修改密码.设置密保和退出登录.创建 SettingActivity ,修改布局为 LinearLayout 具体代码如下: activity_setting. ...

  2. android找回密码界面的代码,《Android项目实战-博学谷》设置密保找回密码

    设置密保&找回密码界面 思路 由于设置密保和找回密码两个界面十分相似,代码逻辑也十分相似,因此这两个界面可以使用同一个布局文件和同一个 Activity 来处理,首先导入所需图片资源文件,再创 ...

  3. Android项目实战--手机卫士

    Android项目实战--手机卫士--结束 很久都没有来更新博客了,之前一直忙着工作的事,接触到了一些以前从来没有接触过的东西,真的挺有挑战性的,但也有很多的无奈,但也学习到了很多东西,我会慢慢的写到 ...

  4. 学习笔记之《Android项目实战——手机安全卫士》

    [Android项目实战-手机安全卫士] 目标:快速积累开发经验,具备中级Android工程师能力. 如遇到难以理解的逻辑或功能,可以先将程序打断点观察程序的执行逻辑. 第一章项目简介:欢迎界面.主界 ...

  5. 开发android项目实战,Android 项目实战:手机安全卫士开发案例解析

    Android 项目实战:手机安全卫士开发案例解析 作 者:王家林,王家俊,王家虎 出版时间:2013 丛编项:移动互联应用开发系列 内容简介 本书通过对一款手机安全卫士开发案例的详细解析,讲解了一个 ...

  6. android在使用单位方面,《Android项目实战——手机安全卫士》_面试题答案.docx

    <Android项目实战--手机安全卫士>_面试题答案 <Android项目实战--手机安全卫士>面试题答案第1章项目简介请问Android程序的真正入口是什么.Android ...

  7. 手机来电秀怎么开启_360手机卫士怎么设置来电秀 360手机卫士来电秀设置方法...

    360手机卫士除了防护等安全功能外,它的来电秀也是比较火热的,很多朋友都喜欢在这里设置自己别具个性的来电秀,这篇文章就一起了解一下360手机卫士怎么设置来电秀. 360手机卫士来电秀设置是在[隐私保护 ...

  8. 最新AndroidStudio项目实战开发安卓播放器(手机影音)

    AndroidStudio项目实战开发安卓播放器(手机影音) 下载地址:百度网盘

  9. 360 android手机备份通讯录,360手机卫士怎样备份手机通讯录 备份手机通讯录图文教程...

    软件安装:手机应用宝 随着科技的发展,手机在我们的生活中扮演了很重要的角色,手机在便利我们生活的同时,也会对我们造成很重要的影响.手机已经成为了我们的必需品,不仅是通讯工具,而且很大程度上都是娱乐功能 ...

最新文章

  1. 【tf.keras】TensorFlow 1.x 到 2.0 的 API 变化
  2. DevExpress v17.2新版亮点—ASP.NET篇(二)
  3. JEECMS自定义标签开发步骤
  4. 在JavaScript中以日期/月/年格式获取当前日期
  5. linux mint 图标主题_如何在 Linux Mint 中更换主题
  6. 服务器怎么修改密码_亚马逊账号登陆不上,修改密码后遭冻结怎么办?有没有什么申诉的办法?...
  7. 扩展二叉树(信息学奥赛一本通-T1340)
  8. jQuery多选插件
  9. linux下mysql 8.0忘记密码后重置密码
  10. Springboot的工作机制:5 总结
  11. 【考研数学】函数、极限、连续
  12. 刘知远:在深度学习时代用HowNet搞事情
  13. DxO FilmPack破解版|DxO FilmPack Elite 5.5.23破解版下载(附破解补丁)
  14. python热搜排行功能_手把手教你用Python+Pyecharts让微博热搜榜动起来
  15. 凸优化工具包CVX快速入门
  16. 2021年高教杯数学建模国赛C题的解题过程附全部代码以及参赛论文(百度网盘)
  17. 数据同步工具—SeaTunnel简介
  18. 广州Java工程师平均薪资_【广州恒生电子工资】java开发工程师待遇-看准网
  19. 003_JS实现图片轮播与点击播放
  20. Unity C# 批量处理 命名空间 修改

热门文章

  1. 将阴天欠曝发暗的照片后期调出小清新色调效果
  2. 考研英语做题技巧(个人总结)
  3. 全球与中国柑橘酒市场深度研究分析报告
  4. 关于vio和ila的区别
  5. 英语作文 谈谈计算机1.我们已进入了计算机时代2.计算机有很多优点,The Computer(电脑时代)...
  6. 中银消费金融催收受阻,强制执行遭借款人失联
  7. esxi能直通的显卡型号_怎么买显卡才能不被坑?挑选套路有这些
  8. 监控TCP/IP网络的工具netstat介绍
  9. java如何快速入门及虚拟主机能装java吗?[图]
  10. 有想象力的故事 More Story Less Theory