- 浏览: 636554 次
文章分类
最新评论
-
涛声依旧是:
怎么提示掉线,怎么才能在线
基于Tomcat7、Java、WebSocket的服务器推送聊天室 -
dcode:
楼主写的不错,正好遇到点问题,看着你的文章解决了,感谢分享。。 ...
在 Visual Studio 2010 中配置SharpPcap
Android项目实战--手机卫士15--设置手机归属地的样式以及显示位置
首先,先把我之前写的那个更新操作的一个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; } } }; @Override protected 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() { @Override public 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); } } }); } @Override public 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() { @Override public 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() { @Override public 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; @Override protected 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); } @Override protected 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); } @Override public 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; @Override public IBinder onBind(Intent intent) { return null; } @Override public 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); } @Override public 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 { @Override public void onCallStateChanged(int state, String incomingNumber) { super.onCallStateChanged(state, incomingNumber); switch(state) { case TelephonyManager.CALL_STATE_IDLE : //空闲状态 if(view != null) { windowManager.removeView(view);//移除显示归属地的那个view view = null; } break; case TelephonyManager.CALL_STATE_OFFHOOK : //接通电话 if(view != null) { windowManager.removeView(view);//移除显示归属地的那个view view = null; } break; case TelephonyManager.CALL_STATE_RINGING : //铃响状态 String address = NumberAddressService.getAddress(incomingNumber); showLocation(address); break; default : break; } } } }
好啦,到现在为止,我们的显示风格还有显示位置就已经全部完成的啦!下次我们就会讲高级工具里面的黑名单功能的啦!
相关推荐
Android项目实战--手机卫士14--接电话时显示电话归属地
Android项目实战--手机卫士22--卸载和分享功能的完成以及用户及系统应用的切换
Android项目实战--手机卫士完整源码part1
Android项目实战--手机卫士12--手机号码归属地查询界面
Android项目实战--手机卫士13--手机号码归属地的逻辑和数据库的压缩
Android项目实战--手机卫士完整源码part3
Android项目实战--手机卫士28--读取进程的信息并显示出来
Android项目实战--手机卫士08--获取手机联系人
Android项目实战--手机卫士07--设置向导
Android项目实战--手机卫士32--给清理进程添加一个Widget
Android项目实战--手机卫士完整源码part1
Android项目实战--手机卫士23--程序锁界面
Android项目实战-手机安全卫士
Android项目实战--手机卫士09--防盗逻辑以及设置向导的完成
Android项目实战--手机卫士34--流量管理
Android项目实战--手机卫士17--拦截黑名单以及响一声电话的处理
Android项目实战--手机卫士09--防盗逻辑以及设置向导的完成_修改
Android项目实战--手机卫士06--GridView的优化与修改Button的显示样式
Android项目实战--手机卫士24--程序锁的实现以及逻辑