1、监听按钮
@Override public boolean onKeyDown(int keyCode, KeyEvent event) { Log.i(LOG_TAG, "onKeyDown: keyCode -- " + keyCode); switch (keyCode) { case KeyEvent.KEYCODE_BACK: Log.i(LOG_TAG, "KeyEvent.KEYCODE_BACK"); break; case KeyEvent.KEYCODE_MENU: Log.i(LOG_TAG, "KeyEvent.KEYCODE_MENU"); break; case KeyEvent.KEYCODE_HOME: Log.i(LOG_TAG, "KeyEvent.KEYCODE_HOME"); break; case KeyEvent.KEYCODE_APP_SWITCH: Log.i(LOG_TAG, "KeyEvent.KEYCODE_APP_SWITCH"); break; } return super.onKeyDown(keyCode, event); }
2、两次单击返回键退出
private long mExitTime; @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN){ if(System.currentTimeMillis() - mExitTime > 2000){ Toast.makeText(this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); mExitTime = System.currentTimeMillis(); }else{ finish(); System.exit(0); } return true; } return super.onKeyDown(keyCode, event); }
3、多击事件
public class MainActivity extends Activity { private Button btn_three; //需要几次点击,只需要将数组的值改成几即可 long[] mHits = new long[3]; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_three = (Button) findViewById(R.id.btn_three); btn_three.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { /** * src:拷贝源数组 * srcPos:从源数组的哪个位置开始拷贝 * dstPos:从目标数组的哪个位置开始拷贝 * length:拷贝的数据的长度 * */ System.arraycopy(mHits, 1, mHits, 0, mHits.length-1); mHits[mHits.length-1] = SystemClock.uptimeMillis(); if(mHits[0]>=(SystemClock.uptimeMillis()-500)){ Toast.makeText(getApplicationContext(), "哈哈我被三击了", 0).show(); } } }); } }
4、拖拽事件
public class MainActivity extends Activity { private ImageView iv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); iv = (ImageView) findViewById(R.id.iv); //给控件注册一个触摸的监听器 iv.setOnTouchListener(new OnTouchListener() { int startX; int startY; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN://手机第一次触摸到屏幕 startX = (int) event.getRawX(); startY = (int) event.getRawY(); System.out.println("手指触摸到了ImageView"); break; case MotionEvent.ACTION_MOVE://手指在屏幕上移动 int newX = (int) event.getRawX(); int newY = (int) event.getRawY(); System.out.println("手指在屏幕上移动了新的坐标:"+newX+","+newY); int dx = newX - startX;//手指在屏幕水平方向移动的距离 int dy = newY - startY;//手在数竖直方向移动的距离 iv.layout(iv.getLeft()+dx, iv.getTop()+dy, iv.getRight()+dx, iv.getBottom()+dy); //手指来到了新的坐标,重新初始化startx和starty startX = (int) event.getRawX(); startY = (int) event.getRawY(); break; case MotionEvent.ACTION_UP://手指离开屏幕的一瞬间 System.out.println("手指离开了ImageView"); break; } //返回true才能执行事件 return true; } }); } }
5、自定义吐司
** * 自定义的吐司 * */ private void showMyToast(String address) { WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); View view = View.inflate(this, R.layout.total_address, null); TextView tv_address = (TextView) view.findViewById(R.id.tv_address); tv_address.setText(address); WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.height = WindowManager.LayoutParams.WRAP_CONTENT; params.width = WindowManager.LayoutParams.WRAP_CONTENT; params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; params.format = PixelFormat.TRANSLUCENT; params.type = WindowManager.LayoutParams.TYPE_TOAST; wm.addView(view, params); }
注意:在不使用时间要调用WindowManager的removeView(view)来释放资源。
6、PopupWindow
public class MainActivity extends Activity { //布局的id private View root; private PopupWindow popupWindow; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); root = findViewById(R.id.root); } public void click(View v){ //弹出悬浮窗体,轻量级的对话框(内存开销,比对话框小且比对话框更灵活) TextView contentView = new TextView(this); contentView.setText("嘿嘿!我是悬浮窗体!popupWindow"); contentView.setTextColor(Color.RED); //漂浮的容器,显示在Activity的上方(下面这个构造函数是最常用的) //注意只要是在代码里面写的所有的宽高信息,单位都是像素 popupWindow = new PopupWindow(contentView,30,30); popupWindow.setBackgroundDrawable(new ColorDrawable(Color.GREEN)); Random random = new Random(); //指定窗体显示在任意的一个位置 popupWindow.showAtLocation(root,Gravity.LEFT|Gravity.TOP,100+random.nextInt(100), 150+random.nextInt(100)); } @Override protected void onDestroy() { if(popupWindow!=null && popupWindow.isShowing()){ popupWindow.dismiss(); } super.onDestroy(); } }
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/root" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="click" android:text="点我弹出窗体" /> </RelativeLayout>
7、应用程序卸载、启动、分享、安装
a)分享
Intent intent = new Intent(); intent.setAction("android.intent.action.SEND"); intent.addCategory("android.intent.category.DEFAULT"); intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT,"推荐你使用一款软件,软件的名称为:" + appInfo.getAppName() + ",我用的很爽."); startActivity(intent);
b)启动
PackageManager pm = getPackageManager(); Intent intent = pm.getLaunchIntentForPackage(appInfo.getPackName()); if(intent!=null){ startActivity(intent); }else{ Toast.makeText(this, "当前应用程序无法启动", Toast.LENGTH_SHORT).show(); }
c)信息
Intent intent = new Intent(); intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); intent.addCategory("android.intent.category.DEFAULT"); intent.setData(Uri.parse("package:"+appInfo.getPackName())); startActivity(intent);
<action android:name="android.settings.APPLICATION_DETAILS_SETTINGS" /> <category android:name="android.intent.category.DEFAULT" /> <data android:scheme="package" />
d)安装
Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); intent.addCategory("android.intent.category.DEFAULT"); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startActivity(intent);
e)卸载
Intent intent = new Intent(); intent.setAction("android.intent.action.DELETE"); intent.addCategory("android.intent.category.DEFAULT"); intent.setData(Uri.parse("package:" + appInfo.getPackName()));
8、Widget
1.创建一个类继承AppWidgetProvider类。
2.widget其实是一个特殊的广播接收者,所以需要在清单文件下配置,使用<receiver>节点即可。
3.需要配置过滤器,过滤器中使用的资源需要自行配置(名字随意),参考第4步
<receiver android:name="cn.legend.widget.MyWidget" > <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/example_appwidget_info" /> </receiver>
4.在工程下创建一个xml文件夹,再创建一个xml文件,当做资源供第3步调用
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/activity_main" android:minHeight="72dp" android:minWidth="294dp" android:updatePeriodMillis="86400000" > </appwidget-provider>
initialLayout:可以指定任意布局文件
5.部署后,低版本长按桌面弹出widget,高版本进入窗体小部件长按小部件即可。
6.widget的生命周期:onenable -> ondisable -> onupdate
9、PendingIntent(延期意图)
//自定义一个广播意图 Intent intent = new Intent(); intent.setAction("cn.legend.mobilesafe.Killall"); //延期的意图,因为这个意图不是由当前应用程序立刻执行的,而是传递给别的进程,由别的进程执行 PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); views.setOnClickPendingIntent(R.id.btn_clear,pendingIntent); //对myWidget进行更新,利用进程间的通讯 awm.updateAppWidget(provider, views);
10、流量统计
long mobilerx = TrafficStats.getMobileRxBytes(); //获取手机(2g/3g/4g)下载的数据信息单位是byte long mobiletx = TrafficStats.getMobileTxBytes(); //获取手机 2g/3g/4g上传的数据信息 long totalrx = TrafficStats.getTotalRxBytes();//获取全部端口下载的流量数据. 包括wifi和 2g/3g/4g的流量 long totaltx = TrafficStats.getTotalTxBytes();//获取全部端口上传的流量数据. 包括wifi和 2g/3g/4g的流量 long browserrx = TrafficStats.getUidRxBytes(10004); long browsertx =TrafficStats.getUidTxBytes(10004); System.out.println("手机上传:"+Formatter.formatFileSize(this, mobiletx)); System.out.println("手机下载:"+Formatter.formatFileSize(this, mobilerx)); System.out.println("wifi上传:"+Formatter.formatFileSize(this, totaltx - mobiletx)); System.out.println("wifi下载:"+Formatter.formatFileSize(this, totalrx- mobilerx)); System.out.println("浏览器上传:"+Formatter.formatFileSize(this, browsertx)); System.out.println("浏览器下载:"+Formatter.formatFileSize(this, browserrx));
11、全局异常捕捉
a) 区分日志级别
public class Logger { private static final int VERBOSE = 1; private static final int DEBUG = 2; private static final int INFO = 3; private static final int WARN = 4; private static final int ERROR = 5; private static int LOGLEVEL = 0; public static void v(String tag,String msg){ if(VERBOSE>LOGLEVEL){ Log.v(tag, msg); } } public static void d(String tag,String msg){ if(DEBUG>LOGLEVEL){ Log.d(tag, msg); } } public static void i(String tag,String msg){ if(INFO>LOGLEVEL){ Log.i(tag, msg); } } public static void w(String tag,String msg){ if(WARN>LOGLEVEL){ Log.w(tag, msg); } } public static void e(String tag,String msg){ if(ERROR>LOGLEVEL){ Log.e(tag, msg); } } }
a)全局异常捕捉
private class MyExceptionHander implements UncaughtExceptionHandler{ @Override public void uncaughtException(Thread thread, Throwable ex) { Logger.i("MobileSafeApplication", "发生了异常,但是被哥捕获了..."); //并不能把异常给消化掉. 只是应用程序挂掉之前,来一个留遗嘱的时间 try { Field[] fields = Build.class.getDeclaredFields(); StringBuffer sb = new StringBuffer(); for(Field field:fields){ String value = field.get(null).toString(); String name = field.getName(); sb.append(name); sb.append(":"); sb.append(value); sb.append("\n"); } FileOutputStream out = new FileOutputStream("/mnt/sdcard/error.log"); StringWriter wr = new StringWriter(); PrintWriter err = new PrintWriter(wr); ex.printStackTrace(err); String errorlog = wr.toString(); sb.append(errorlog); out.write(sb.toString().getBytes()); out.flush(); out.close(); } catch (Exception e) { e.printStackTrace(); } //专注自杀, 早死早超生 android.os.Process.killProcess(android.os.Process.myPid()); } } }
c)清单文件配置<application name=".MobileSafeApplication">,则表示使用该异常处理机制进行处理。
12、发送邮件
Intent i = new Intent(Intent.ACTION_SEND); //i.setType("text/plain"); //模拟器请使用这行 i.setType("message/rfc822") ; // 真机上使用这行 i.putExtra(Intent.EXTRA_EMAIL, new String[]{"test@gmail.com"}); i.putExtra(Intent.EXTRA_SUBJECT,"subject goes here"); i.putExtra(Intent.EXTRA_TEXT,"body goes here"); startActivity(Intent.createChooser(i, "Select email application."));
13、屏幕常亮
public static void setScreenBright(Activity activity, boolean keepScreenOn) { if (keepScreenOn) { activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } }
14、EditText自动大写
EditText限制:只输入大写,自动小写转大写
*** * EditText自动小写转大写 * @author legend */ public class AllCapTransformationMethod extends ReplacementTransformationMethod { @Override protected char[] getOriginal() { char[] aa = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z' }; return aa; } @Override protected char[] getReplacement() { char[] cc = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' }; return cc; } }
在初始化控件的时候调用EditText的setTransformationMethod方法即可。
editext.setTransformationMethod(new AllCapTransformationMethod ());
15、抖动动画
Animation animation = shakeAnimation(5,1000); view.setAnimation(animation); // 抖动动画 public static Animation shakeAnimation(int counts,int duration){ Animation translateAnimation = new TranslateAnimation(0, 0, 0, 10); translateAnimation.setInterpolator(new CycleInterpolator(counts)); translateAnimation.setDuration(duration); return translateAnimation; }
===========================================================