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

来源:互联网 发布:女神联盟2红将进阶数据 编辑:程序博客网 时间:2024/05/06 04:02

 

首先,先把我之前写的那个更新操作的一个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;}}}}


 

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

 

今天源码下载

原创粉丝点击